openpond 0.0.30-bootstrap.0

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 (193) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/LICENSE +21 -0
  3. package/README.md +162 -0
  4. package/RELEASE.md +20 -0
  5. package/dist/api/core.d.ts +22 -0
  6. package/dist/api/deployments.d.ts +30 -0
  7. package/dist/api/types.d.ts +624 -0
  8. package/dist/api.d.ts +90 -0
  9. package/dist/cache.d.ts +22 -0
  10. package/dist/chunks/app-layer-YKXEQGOW.js +163 -0
  11. package/dist/chunks/apps-GGSIN2ZF.js +539 -0
  12. package/dist/chunks/chunk-3CC6MH35.js +1663 -0
  13. package/dist/chunks/chunk-3Y4EL3P6.js +1090 -0
  14. package/dist/chunks/chunk-4HYJG2JE.js +3875 -0
  15. package/dist/chunks/chunk-5G4E547X.js +294 -0
  16. package/dist/chunks/chunk-74O6FGVN.js +598 -0
  17. package/dist/chunks/chunk-AUJLPKGI.js +632 -0
  18. package/dist/chunks/chunk-BYAPLT37.js +744 -0
  19. package/dist/chunks/chunk-FUP7EGT7.js +1845 -0
  20. package/dist/chunks/chunk-I6HN3ZGW.js +88 -0
  21. package/dist/chunks/chunk-KRKGHVMQ.js +294 -0
  22. package/dist/chunks/chunk-LHYK6QO2.js +1300 -0
  23. package/dist/chunks/chunk-NLBKZZEK.js +224 -0
  24. package/dist/chunks/chunk-OG75GMVO.js +1 -0
  25. package/dist/chunks/chunk-Q57SVPEH.js +11663 -0
  26. package/dist/chunks/chunk-UACZUFIA.js +47 -0
  27. package/dist/chunks/chunk-VQX33YAG.js +5135 -0
  28. package/dist/chunks/chunk-W5GKHH77.js +168 -0
  29. package/dist/chunks/chunk-WYDVQOBL.js +17581 -0
  30. package/dist/chunks/chunk-XSAXENQD.js +4167 -0
  31. package/dist/chunks/chunk-Y6G6WRTG.js +210 -0
  32. package/dist/chunks/cli-NVKNE4AZ.js +11 -0
  33. package/dist/chunks/cli-X3HPLSOV.js +19 -0
  34. package/dist/chunks/core-commands-IM2UKLU4.js +41 -0
  35. package/dist/chunks/extend-YXCBULPO.js +84 -0
  36. package/dist/chunks/harness-GMK6IY2U.js +140 -0
  37. package/dist/chunks/help-LMH5FGT2.js +65 -0
  38. package/dist/chunks/opchat-BWXZ32GX.js +169 -0
  39. package/dist/chunks/organizations-4ISQRGMQ.js +738 -0
  40. package/dist/chunks/profile-NLDZDT3L.js +1110 -0
  41. package/dist/chunks/project-agent-ZPVO25HA.js +892 -0
  42. package/dist/chunks/sandbox-command-5GFJ2U3V.js +1652 -0
  43. package/dist/chunks/sandbox-template-LZN4F55Z.js +1646 -0
  44. package/dist/chunks/src-3RBI4DNN.js +3595 -0
  45. package/dist/chunks/src-EYXQS6XD.js +73427 -0
  46. package/dist/chunks/teams-bot-WP3FHKGA.js +137 -0
  47. package/dist/cli.js +77 -0
  48. package/dist/client-types.d.ts +222 -0
  49. package/dist/client.d.ts +19 -0
  50. package/dist/config.d.ts +184 -0
  51. package/dist/hosted-chat.d.ts +162 -0
  52. package/dist/index.d.ts +5 -0
  53. package/dist/index.js +25481 -0
  54. package/dist/indicators.d.ts +38 -0
  55. package/dist/opchat-smoke.d.ts +47 -0
  56. package/dist/private-json-file.d.ts +3 -0
  57. package/dist/profile/local-profile-types.d.ts +160 -0
  58. package/dist/profile/local-profile.d.ts +69 -0
  59. package/dist/profile/profile-catalog.d.ts +14 -0
  60. package/dist/profile/profile-git.d.ts +17 -0
  61. package/dist/profile/profile-promotion.d.ts +21 -0
  62. package/dist/profile/profile-setup-gate.d.ts +22 -0
  63. package/dist/profile/profile-skills.d.ts +30 -0
  64. package/dist/profile/profile-source-upload.d.ts +29 -0
  65. package/dist/profile/source-upload-cache.d.ts +29 -0
  66. package/dist/sandbox/async-request-options.d.ts +2 -0
  67. package/dist/sandbox/client-handles.d.ts +113 -0
  68. package/dist/sandbox/client.d.ts +348 -0
  69. package/dist/sandbox/runtime-handle.d.ts +36 -0
  70. package/dist/sandbox/sandbox-instance-client.d.ts +72 -0
  71. package/dist/sandbox/smoke.d.ts +3 -0
  72. package/dist/sandbox/stream.d.ts +7 -0
  73. package/dist/sandbox/types/billing.d.ts +176 -0
  74. package/dist/sandbox/types/client.d.ts +103 -0
  75. package/dist/sandbox/types/core.d.ts +140 -0
  76. package/dist/sandbox/types/index.d.ts +14 -0
  77. package/dist/sandbox/types/io.d.ts +240 -0
  78. package/dist/sandbox/types/microsoft-teams-bot.d.ts +51 -0
  79. package/dist/sandbox/types/org-project-agent.d.ts +610 -0
  80. package/dist/sandbox/types/record.d.ts +53 -0
  81. package/dist/sandbox/types/responses.d.ts +295 -0
  82. package/dist/sandbox/types/runtime-profiles.d.ts +15 -0
  83. package/dist/sandbox/types/runtime.d.ts +152 -0
  84. package/dist/sandbox/types/schedules.d.ts +141 -0
  85. package/dist/sandbox/types/snapshots.d.ts +205 -0
  86. package/dist/sandbox/types/workflow-modes.d.ts +1 -0
  87. package/dist/sandbox/types/workload-sources.d.ts +20 -0
  88. package/dist/sandbox/url.d.ts +2 -0
  89. package/dist/sandbox-template/manifest.d.ts +304 -0
  90. package/dist/sandbox-template/manifest.js +18381 -0
  91. package/dist/skills/openpond-cli/SKILL.md +49 -0
  92. package/dist/skills/openpond-desktop-harness/SKILL.md +113 -0
  93. package/dist/skills/openpond-desktop-harness/agents/openai.yaml +4 -0
  94. package/dist/skills/openpond-taskset-authoring/SKILL.md +38 -0
  95. package/dist/skills/openpond-taskset-authoring/references/graders-and-rewards.md +11 -0
  96. package/dist/skills/openpond-taskset-authoring/references/method-selection.md +12 -0
  97. package/dist/skills/openpond-taskset-authoring/references/privacy-and-provenance.md +8 -0
  98. package/dist/skills/openpond-taskset-authoring/references/task-design.md +13 -0
  99. package/dist/stream.d.ts +20 -0
  100. package/dist/types.d.ts +57 -0
  101. package/dist/urls.d.ts +4 -0
  102. package/dist/web/assets/AppsView-Bu-Nc3Ew.js +1 -0
  103. package/dist/web/assets/AppsView-DIhprTIC.css +1 -0
  104. package/dist/web/assets/BrowserSidebar-CCguQ-DR.js +1 -0
  105. package/dist/web/assets/BrowserSidebar-D9i7gQzw.css +1 -0
  106. package/dist/web/assets/CloudWorkView-DNoPIlMj.css +1 -0
  107. package/dist/web/assets/CloudWorkView-Dr3xqLE5.js +1 -0
  108. package/dist/web/assets/CommandMenu-CnodJFHD.js +1 -0
  109. package/dist/web/assets/CommandMenu-hNQCm8mw.css +1 -0
  110. package/dist/web/assets/CommunityView-CIbjNUZr.js +1 -0
  111. package/dist/web/assets/CommunityView-DSik4sd2.css +1 -0
  112. package/dist/web/assets/GetStartedView-C3ZrnEz5.css +1 -0
  113. package/dist/web/assets/GetStartedView-C8nyH_PT.js +1 -0
  114. package/dist/web/assets/LabsExtensions-GtJzxDnK.js +1 -0
  115. package/dist/web/assets/LabsProfile-DG7rWYur.js +1 -0
  116. package/dist/web/assets/LabsRoute-D6MDHBzq.js +2 -0
  117. package/dist/web/assets/LabsRoute-TEt9j1vB.css +1 -0
  118. package/dist/web/assets/LabsSignals-BfsDN86w.js +1 -0
  119. package/dist/web/assets/LabsSignals-D6iA6Ryl.css +1 -0
  120. package/dist/web/assets/NewProjectDialog-CaKiCoVS.js +1 -0
  121. package/dist/web/assets/ProfileSettingsSection-DTQS2DVL.css +1 -0
  122. package/dist/web/assets/ProfileSettingsSection-DxEzoF3K.js +1 -0
  123. package/dist/web/assets/ProfileView-CEscW7Ru.js +1 -0
  124. package/dist/web/assets/SettingsView-DwbGu8Kj.css +1 -0
  125. package/dist/web/assets/SettingsView-JIRR_FO4.js +63 -0
  126. package/dist/web/assets/TeamChatView-B5M1ThhJ.js +3 -0
  127. package/dist/web/assets/TeamChatView-Bx44q3WV.css +1 -0
  128. package/dist/web/assets/TerminalOverlay-C1iP4OS1.js +19 -0
  129. package/dist/web/assets/TerminalOverlay-DwBiZLwk.css +1 -0
  130. package/dist/web/assets/TrainingSettingsSection-BDYvI2te.js +1 -0
  131. package/dist/web/assets/TrainingView-CoCFK6W3.js +5 -0
  132. package/dist/web/assets/WorkspaceDiffPanel-CMxKQeo7.js +14 -0
  133. package/dist/web/assets/WorkspaceEnvironmentMenu-B8JJbwIz.js +32 -0
  134. package/dist/web/assets/WorkspaceEnvironmentMenu-DGIFdG3o.css +1 -0
  135. package/dist/web/assets/WorkspaceGitDialogs-B4sp9BGn.js +1 -0
  136. package/dist/web/assets/WorkspaceMonacoEditor-BBqimG5X.js +845 -0
  137. package/dist/web/assets/WorkspaceMonacoEditor-BwKcXIZw.css +1 -0
  138. package/dist/web/assets/boxes-DAaDUabq.js +1 -0
  139. package/dist/web/assets/codicon-ngg6Pgfi.ttf +0 -0
  140. package/dist/web/assets/css.worker-DBVD8oXr.js +93 -0
  141. package/dist/web/assets/cssMode-CBF1mieJ.js +1 -0
  142. package/dist/web/assets/dockerfile-BG73LgW2.js +1 -0
  143. package/dist/web/assets/editor.worker-CdQrwHl8.js +26 -0
  144. package/dist/web/assets/git-commit-horizontal-CAickXpN.js +1 -0
  145. package/dist/web/assets/git-dialogs-BZDqS1eT.css +1 -0
  146. package/dist/web/assets/html.worker-CwpTb9lJ.js +470 -0
  147. package/dist/web/assets/htmlMode-2u8OHtWO.js +1 -0
  148. package/dist/web/assets/index-BdY6A-YN.css +1 -0
  149. package/dist/web/assets/index-CU2qhUYV.js +195 -0
  150. package/dist/web/assets/index-Dz2B3-4C.js +1 -0
  151. package/dist/web/assets/info-CQNTh78o.js +1 -0
  152. package/dist/web/assets/json.worker-BoL8UZqY.js +58 -0
  153. package/dist/web/assets/jsonMode-C4CWXViX.js +7 -0
  154. package/dist/web/assets/lspLanguageFeatures-CBs_BOlB.js +4 -0
  155. package/dist/web/assets/markdown-BFxVWTOG.js +1 -0
  156. package/dist/web/assets/monaco.contribution-C1LUxAKf.js +2 -0
  157. package/dist/web/assets/monaco.contribution-Cpf6dWsh.js +2 -0
  158. package/dist/web/assets/monaco.contribution-lOXpG2xQ.js +2 -0
  159. package/dist/web/assets/monaco.contribution-sd3cFkcN.js +2 -0
  160. package/dist/web/assets/monitor-DsIswrMV.js +1 -0
  161. package/dist/web/assets/play-CeRw21NV.js +1 -0
  162. package/dist/web/assets/python-CXYq3BUl.js +1 -0
  163. package/dist/web/assets/refresh-cw-N5b_6AP5.js +1 -0
  164. package/dist/web/assets/reply-BSKjZrJg.js +1 -0
  165. package/dist/web/assets/save-D0oHH1a3.js +1 -0
  166. package/dist/web/assets/settings-lists-BEg6LMcy.css +1 -0
  167. package/dist/web/assets/shell-DiJ1NA_G.js +1 -0
  168. package/dist/web/assets/toggleHighContrast-B7NOMXDY.css +1 -0
  169. package/dist/web/assets/toggleHighContrast-DRjlcwes.js +62 -0
  170. package/dist/web/assets/training-model-data-BPrc68VG.js +1 -0
  171. package/dist/web/assets/ts.worker-BH9nVgjN.js +67718 -0
  172. package/dist/web/assets/tsMode-x-1A7ZcB.js +11 -0
  173. package/dist/web/assets/wifi-off-Dt52ofzh.js +1 -0
  174. package/dist/web/assets/workers-Ciff6Dzi.js +1 -0
  175. package/dist/web/assets/yaml-CB67Kxnz.js +1 -0
  176. package/dist/web/connected-apps/github.svg +3 -0
  177. package/dist/web/connected-apps/google.svg +6 -0
  178. package/dist/web/connected-apps/linear.svg +3 -0
  179. package/dist/web/connected-apps/microsoft.svg +6 -0
  180. package/dist/web/connected-apps/notion.svg +3 -0
  181. package/dist/web/connected-apps/openpond-mcp.svg +4 -0
  182. package/dist/web/connected-apps/slack.svg +6 -0
  183. package/dist/web/connected-apps/x.svg +3 -0
  184. package/dist/web/favicon-16x16.png +0 -0
  185. package/dist/web/favicon-32x32.png +0 -0
  186. package/dist/web/index.html +16 -0
  187. package/dist/web/openpond-icon.png +0 -0
  188. package/dist/web/openpond-wordlogo-white.png +0 -0
  189. package/dist/web/tokens/eth.svg +1 -0
  190. package/dist/web/tokens/usdc.svg +1 -0
  191. package/docs/agent-edit-check-status-json.md +132 -0
  192. package/docs/command-reference.md +695 -0
  193. package/package.json +84 -0
@@ -0,0 +1,1110 @@
1
+ import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
+ import {
3
+ collectAgentSdkProjectSourceUploadEntries,
4
+ collectProjectSourceUploadEntries,
5
+ mergeProjectSourceUploadEntries,
6
+ parseAgentSourceCheckDispatch,
7
+ parseAgentSourceCheckKind
8
+ } from "./chunk-3CC6MH35.js";
9
+ import {
10
+ buildHostedRunIdempotencyKey,
11
+ collectProfileSourceUploadEntries,
12
+ commitActiveProfileChanges,
13
+ defaultLocalProfileRepoPath,
14
+ formatOpenPondProfileSetupRequirement,
15
+ hostedPublishStatusFromPayload,
16
+ hostedRunStatusFromRunSummary,
17
+ hostedRunSummaryFromPayload,
18
+ hostedSourceCheckStatusFromPayload,
19
+ initLocalProfileRepo,
20
+ loadLocalProfileRepo,
21
+ loadOpenPondProfileState,
22
+ runProfileCheck,
23
+ runProfileSdkCommand,
24
+ saveProfilePushStatus
25
+ } from "./chunk-FUP7EGT7.js";
26
+ import "./chunk-I6HN3ZGW.js";
27
+ import "./chunk-VQX33YAG.js";
28
+ import "./chunk-LHYK6QO2.js";
29
+ import "./chunk-OG75GMVO.js";
30
+ import "./chunk-BYAPLT37.js";
31
+ import "./chunk-WYDVQOBL.js";
32
+ import {
33
+ resolveSandboxClient
34
+ } from "./chunk-XSAXENQD.js";
35
+ import "./chunk-5G4E547X.js";
36
+ import {
37
+ optionString,
38
+ parseBooleanOption,
39
+ requiredTeamId
40
+ } from "./chunk-3Y4EL3P6.js";
41
+ import "./chunk-UACZUFIA.js";
42
+
43
+ // src/cli/profile.ts
44
+ import { readFile } from "node:fs/promises";
45
+ import path from "node:path";
46
+ async function runOpenPondInitCommand(options) {
47
+ const state = await initLocalProfileRepo({
48
+ repoPath: optionString(options, "path") || defaultLocalProfileRepoPath(),
49
+ profile: optionString(options, "profile") || "default",
50
+ template: optionString(options, "template") || "blank-agent",
51
+ force: parseBooleanOption(options.force)
52
+ });
53
+ if (parseBooleanOption(options.json)) {
54
+ console.log(JSON.stringify(state, null, 2));
55
+ return;
56
+ }
57
+ console.log(`Initialized OpenPond profile ${state.activeProfile} at ${state.repoPath}`);
58
+ console.log(`Profile source: ${state.sourcePath}`);
59
+ }
60
+ async function runOpenPondProfileCommand(options, rest) {
61
+ const subcommand = rest[0] ?? "current";
62
+ if (subcommand === "load") {
63
+ const repoPath = optionString(options, "path") || rest[1];
64
+ if (!repoPath) {
65
+ throw new Error("usage: openpond profile load --path <dir> [--profile <name>]");
66
+ }
67
+ const state = await loadLocalProfileRepo(repoPath, optionString(options, "profile") || void 0);
68
+ if (parseBooleanOption(options.json)) {
69
+ console.log(JSON.stringify(state, null, 2));
70
+ return;
71
+ }
72
+ console.log(`Loaded OpenPond profile ${state.activeProfile} from ${state.repoPath}`);
73
+ return;
74
+ }
75
+ if (subcommand === "current" || subcommand === "status") {
76
+ const state = await loadOpenPondProfileState();
77
+ if (parseBooleanOption(options.json)) {
78
+ console.log(JSON.stringify(state, null, 2));
79
+ return;
80
+ }
81
+ printProfileState(state);
82
+ return;
83
+ }
84
+ if (subcommand === "diff") {
85
+ const state = await loadOpenPondProfileState();
86
+ if (parseBooleanOption(options.json)) {
87
+ console.log(JSON.stringify({ diff: state.diff, profile: state }, null, 2));
88
+ return;
89
+ }
90
+ printProfileDiff(state);
91
+ return;
92
+ }
93
+ if (subcommand === "catalog") {
94
+ const state = await loadOpenPondProfileState();
95
+ if (parseBooleanOption(options.json)) {
96
+ console.log(JSON.stringify({ catalog: state.catalog, actions: state.actionCatalog, profile: state }, null, 2));
97
+ return;
98
+ }
99
+ printProfileCatalog(state);
100
+ return;
101
+ }
102
+ if (subcommand === "commit") {
103
+ await runProfileCommitCommand(options, rest.slice(1));
104
+ return;
105
+ }
106
+ if (subcommand === "push") {
107
+ await runProfilePushCommand(options);
108
+ return;
109
+ }
110
+ if (subcommand === "check") {
111
+ await runProfileCheck(optionString(options, "kind") || rest[1] || "all");
112
+ return;
113
+ }
114
+ if (subcommand === "ensure-hosted") {
115
+ await runHostedProfileEnsureCommand(options);
116
+ return;
117
+ }
118
+ if (subcommand === "hosted") {
119
+ const nested = rest[1] ?? "status";
120
+ if (nested === "ensure") {
121
+ await runHostedProfileEnsureCommand(options);
122
+ return;
123
+ }
124
+ if (nested === "status" || nested === "current") {
125
+ await runHostedProfileStatusCommand(options);
126
+ return;
127
+ }
128
+ throw new Error("usage: openpond profile hosted [status|ensure] --team-id <id> [--json]");
129
+ }
130
+ if (subcommand === "agents") {
131
+ const nested = rest[1] ?? "list";
132
+ if (nested !== "list") {
133
+ throw new Error("usage: openpond profile agents list [--json]");
134
+ }
135
+ await runOpenPondAgentsCommand(options, ["list"]);
136
+ return;
137
+ }
138
+ throw new Error("usage: openpond profile <status|diff|catalog|commit|push|load|check|agents|hosted|ensure-hosted> [args]");
139
+ }
140
+ async function runProfileCommitCommand(options, rest) {
141
+ const message = optionString(options, "message") || optionString(options, "commitMessage") || rest.join(" ").trim() || void 0;
142
+ const result = await commitActiveProfileChanges(message);
143
+ if (parseBooleanOption(options.json)) {
144
+ console.log(JSON.stringify(result, null, 2));
145
+ return;
146
+ }
147
+ if (!result.committed) {
148
+ console.log("No profile changes to commit.");
149
+ printProfileState(result.state);
150
+ return;
151
+ }
152
+ console.log("Committed OpenPond profile changes.");
153
+ if (result.stdout.trim()) console.log(result.stdout.trim());
154
+ printProfileState(result.state);
155
+ }
156
+ async function runProfilePushCommand(options) {
157
+ const teamId = requiredTeamId(options, "usage: openpond profile push");
158
+ const state = await loadOpenPondProfileState();
159
+ if (state.error) throw new Error(state.error);
160
+ if (!state.repoPath || !state.sourcePath || !state.manifestPath) {
161
+ throw new Error("No active OpenPond profile. Run `openpond init`.");
162
+ }
163
+ if (!state.git?.isRepo) {
164
+ throw new Error("Active OpenPond profile source is not Git-backed. Run `openpond init` or reload a Git-backed profile.");
165
+ }
166
+ if (!state.git.head) {
167
+ throw new Error("Profile source must have a committed Git head before push. Run `openpond profile commit` first.");
168
+ }
169
+ if (state.git.dirty) {
170
+ throw new Error("Profile source has uncommitted changes. Run `openpond profile commit` before push.");
171
+ }
172
+ const client = await resolveSandboxClient(options);
173
+ const hosted = parseBooleanOption(options.ensureHosted) ? await client.profile.ensureHosted({ teamId }) : await client.profile.get({ teamId });
174
+ if (!hosted) {
175
+ throw new Error("No hosted OpenPond profile repo found. Run `openpond profile ensure-hosted --team-id <id>` first, or pass `--ensure-hosted` to push.");
176
+ }
177
+ const force = parseBooleanOption(options.force);
178
+ const currentHostedHead = hosted.sourceUpload?.sourceCommitSha ?? null;
179
+ const lastPushedHostedHead = state.hosted?.sourceCommitSha ?? null;
180
+ if (lastPushedHostedHead && currentHostedHead !== lastPushedHostedHead && !force) {
181
+ throw new Error(
182
+ [
183
+ "Hosted profile source changed since the last local push.",
184
+ `Last pushed hosted head: ${lastPushedHostedHead}`,
185
+ `Current hosted head: ${currentHostedHead ?? "none"}`,
186
+ "Inspect hosted changes before pushing, or rerun with --force to overwrite explicitly."
187
+ ].join("\n")
188
+ );
189
+ }
190
+ const explicitHostedSourceAgentId = optionString(options, "hostedSourceAgentId");
191
+ const requestHostedSourceChecks = parseBooleanOption(options.hostedSourceChecks);
192
+ const publishHostedSource = parseBooleanOption(options.publishHostedSource);
193
+ const hostedRunAgentId = optionString(options, "hostedRunAgentId");
194
+ const hostedSourceAgentId = explicitHostedSourceAgentId || (requestHostedSourceChecks || publishHostedSource ? hostedRunAgentId : null);
195
+ const manifest = JSON.parse(await readFile(state.manifestPath, "utf8"));
196
+ const hostedManifest = normalizeHostedProfileManifest(manifest);
197
+ const sourcePath = manifest.profiles[state.activeProfile ?? manifest.defaultProfile]?.path ?? "profiles/default";
198
+ const upload = await collectProfileSourceUploadForPush({
199
+ state,
200
+ hostedSourceAgentId
201
+ });
202
+ const result = await client.profile.push({
203
+ teamId,
204
+ entries: upload.entries,
205
+ branch: state.git.branch ?? "main",
206
+ commitMessage: optionString(options, "commitMessage") || optionString(options, "message") || `Push OpenPond profile ${state.activeProfile ?? "default"} at ${state.git.shortHead ?? state.git.head}`,
207
+ expectedSourceCommitSha: currentHostedHead,
208
+ localHeadSha: state.git.head,
209
+ manifest: hostedManifest,
210
+ sourcePath,
211
+ agents: state.agents.map((agent) => ({
212
+ id: agent.id,
213
+ path: agent.path,
214
+ enabled: agent.enabled
215
+ }))
216
+ });
217
+ const pushedAt = (/* @__PURE__ */ new Date()).toISOString();
218
+ const preserveHostedPromotionEvidence = state.hosted?.lastPushedLocalHead === state.git.head && state.hosted?.sourceCommitSha === result.sourceUpload.sourceCommitSha;
219
+ let pushStatus = {
220
+ status: "pushed",
221
+ promotionStatus: preserveHostedPromotionEvidence ? state.hosted?.promotionStatus ?? "uploaded" : "uploaded",
222
+ hostedRunStatus: preserveHostedPromotionEvidence ? state.hosted?.hostedRunStatus ?? "not_started" : "not_started",
223
+ pushedAt,
224
+ teamId,
225
+ projectId: result.profile.project.id,
226
+ localHead: state.git.head,
227
+ hostedHead: result.sourceUpload.sourceCommitSha,
228
+ sourceRef: result.sourceUpload.sourceRef,
229
+ hostedRunAgentId: preserveHostedPromotionEvidence ? state.hosted?.hostedRunAgentId ?? null : null,
230
+ hostedRunId: preserveHostedPromotionEvidence ? state.hosted?.hostedRunId ?? null : null,
231
+ hostedRunAt: preserveHostedPromotionEvidence ? state.hosted?.hostedRunAt ?? null : null,
232
+ hostedSourceMaterialization: preserveHostedPromotionEvidence ? state.hosted?.hostedSourceMaterialization ?? null : null,
233
+ hostedSourceCheck: preserveHostedPromotionEvidence ? state.hosted?.hostedSourceCheck ?? null : null,
234
+ hostedPublish: preserveHostedPromotionEvidence ? state.hosted?.hostedPublish ?? null : null,
235
+ hostedRun: preserveHostedPromotionEvidence ? state.hosted?.hostedRun ?? null : null
236
+ };
237
+ await saveProfilePushStatus(pushStatus);
238
+ let hostedRuntimeAgentId = hostedSourceAgentId ?? resolveHostedRuntimeAgentIdForRun(state, hostedRunAgentId);
239
+ const hostedSourceDispatch = parseAgentSourceCheckDispatch(
240
+ options.hostedSourceDispatch,
241
+ "hosted-source-dispatch"
242
+ ) ?? "coding_core";
243
+ let hostedSourceDeployPlan = null;
244
+ let hostedSourceChecks = null;
245
+ let hostedSourcePublish = null;
246
+ if (hostedSourceAgentId && (requestHostedSourceChecks || publishHostedSource || explicitHostedSourceAgentId)) {
247
+ try {
248
+ const hostedSourceMaterialization = await materializeHostedProfileAgentSource({
249
+ client,
250
+ teamId,
251
+ profileProjectId: result.profile.project.id,
252
+ profileName: state.activeProfile ?? manifest.defaultProfile,
253
+ state,
254
+ agentId: hostedSourceAgentId,
255
+ sourceRef: result.sourceUpload.sourceRef ?? state.git.branch ?? "main",
256
+ localHead: state.git.head,
257
+ hostedHead: result.sourceUpload.sourceCommitSha,
258
+ projectId: optionString(options, "hostedSourceProjectId") || (state.hosted?.hostedSourceMaterialization?.agentId === hostedSourceAgentId ? state.hosted.hostedSourceMaterialization.projectId : null)
259
+ });
260
+ pushStatus = {
261
+ ...pushStatus,
262
+ promotionStatus: "hosted_source_materialized",
263
+ hostedSourceMaterialization
264
+ };
265
+ hostedRuntimeAgentId = hostedSourceMaterialization.runtimeAgentId ?? hostedSourceAgentId;
266
+ await saveProfilePushStatus(pushStatus);
267
+ } catch (error) {
268
+ const message = error instanceof Error ? error.message : String(error);
269
+ pushStatus = {
270
+ ...pushStatus,
271
+ promotionStatus: "hosted_source_materialize_failed",
272
+ hostedSourceMaterialization: {
273
+ status: "failed",
274
+ agentId: hostedSourceAgentId,
275
+ projectId: optionString(options, "hostedSourceProjectId") ?? null,
276
+ error: message
277
+ },
278
+ error: message
279
+ };
280
+ await saveProfilePushStatus(pushStatus);
281
+ throw new Error(`Hosted source materialization failed after push: ${message}`);
282
+ }
283
+ }
284
+ if (requestHostedSourceChecks || publishHostedSource) {
285
+ if (!hostedSourceAgentId) {
286
+ throw new Error("--hosted-source-agent-id or --hosted-run-agent-id is required for hosted source checks or publish.");
287
+ }
288
+ if (!hostedRuntimeAgentId) {
289
+ throw new Error("Unable to resolve the hosted runtime agent for source checks.");
290
+ }
291
+ try {
292
+ hostedSourceDeployPlan = await client.agents.sourceDeployPlan(hostedRuntimeAgentId, { teamId });
293
+ if (requestHostedSourceChecks) {
294
+ const sourceRef = pushStatus.hostedSourceMaterialization?.sourceRef ?? result.sourceUpload.sourceRef;
295
+ const baseSha = pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? result.sourceUpload.sourceCommitSha;
296
+ hostedSourceChecks = await client.agents.requestSourceChecks(hostedRuntimeAgentId, {
297
+ teamId,
298
+ ...sourceRef ? { sourceRef } : {},
299
+ ...baseSha ? { baseSha } : {},
300
+ checkKind: parseAgentSourceCheckKind(
301
+ optionString(options, "hostedCheckKind") || optionString(options, "checkKind")
302
+ ) ?? "all",
303
+ dispatch: hostedSourceDispatch,
304
+ metadata: {
305
+ source: "openpond_profile_push_checks",
306
+ localHead: state.git.head,
307
+ hostedHead: result.sourceUpload.sourceCommitSha,
308
+ materializedProjectId: pushStatus.hostedSourceMaterialization?.projectId ?? null,
309
+ materializedSourceCommitSha: pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? null,
310
+ sourceRef,
311
+ dispatch: hostedSourceDispatch
312
+ }
313
+ });
314
+ if (hostedSourceChecks.dispatchResult?.status === "failed") {
315
+ throw new Error(hostedSourceChecks.dispatchResult.error ?? "hosted_source_check_dispatch_failed");
316
+ }
317
+ if (hostedSourceChecks.dispatchResult?.status === "completed") {
318
+ const refreshed = await refreshHostedSourceCheckStatus({
319
+ client,
320
+ teamId,
321
+ checkResult: hostedSourceChecks
322
+ });
323
+ if (refreshed) {
324
+ hostedSourceChecks = refreshed;
325
+ }
326
+ const sourceCheckStatus = record(hostedSourceChecks.sourceCheckStatus);
327
+ if (sourceCheckStatusPassed(sourceCheckStatus)) {
328
+ await bindValidatedHostedRuntimeSource({
329
+ client,
330
+ teamId,
331
+ runtimeAgentId: hostedRuntimeAgentId,
332
+ sourceRef,
333
+ sourceCommitSha: baseSha,
334
+ validatedAt: (/* @__PURE__ */ new Date()).toISOString()
335
+ });
336
+ hostedSourceDeployPlan = await client.agents.sourceDeployPlan(hostedRuntimeAgentId, { teamId });
337
+ }
338
+ }
339
+ }
340
+ pushStatus = {
341
+ ...pushStatus,
342
+ promotionStatus: requestHostedSourceChecks ? "hosted_source_check_pending" : pushStatus.promotionStatus,
343
+ hostedSourceCheck: hostedSourceCheckStatusFromPayload({
344
+ agentId: hostedRuntimeAgentId,
345
+ status: requestHostedSourceChecks ? "requested" : "deploy_plan_ready",
346
+ deployPlan: hostedSourceDeployPlan,
347
+ checkResult: hostedSourceChecks
348
+ })
349
+ };
350
+ await saveProfilePushStatus(pushStatus);
351
+ } catch (error) {
352
+ const message = error instanceof Error ? error.message : String(error);
353
+ pushStatus = {
354
+ ...pushStatus,
355
+ promotionStatus: "hosted_source_check_failed",
356
+ hostedSourceCheck: hostedSourceCheckStatusFromPayload({
357
+ agentId: hostedRuntimeAgentId,
358
+ status: "failed",
359
+ deployPlan: hostedSourceDeployPlan,
360
+ checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
361
+ error: message
362
+ }),
363
+ error: message
364
+ };
365
+ await saveProfilePushStatus(pushStatus);
366
+ throw new Error(`Hosted source check failed after push: ${message}`);
367
+ }
368
+ }
369
+ if (publishHostedSource) {
370
+ if (!hostedSourceAgentId) {
371
+ throw new Error("--hosted-source-agent-id or --hosted-run-agent-id is required for hosted source publish.");
372
+ }
373
+ if (!hostedRuntimeAgentId) {
374
+ throw new Error("Unable to resolve the hosted runtime agent for source publish.");
375
+ }
376
+ try {
377
+ const expectedManifestHash = optionString(options, "expectedManifestHash") || pushStatus.hostedSourceCheck?.manifestHash || hostedSourceDeployPlan?.source.manifestHash || void 0;
378
+ hostedSourcePublish = await client.agents.publishSource(hostedRuntimeAgentId, {
379
+ teamId,
380
+ ...expectedManifestHash ? { expectedManifestHash } : {},
381
+ ...pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? result.sourceUpload.sourceCommitSha ? { expectedSourceCommitSha: pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? result.sourceUpload.sourceCommitSha } : {},
382
+ ...optionString(options, "workItemId") ? { workItemId: optionString(options, "workItemId") } : {}
383
+ });
384
+ pushStatus = {
385
+ ...pushStatus,
386
+ promotionStatus: "hosted_source_published",
387
+ hostedPublish: hostedPublishStatusFromPayload({
388
+ agentId: hostedRuntimeAgentId,
389
+ publishResult: hostedSourcePublish
390
+ })
391
+ };
392
+ await saveProfilePushStatus(pushStatus);
393
+ } catch (error) {
394
+ const message = error instanceof Error ? error.message : String(error);
395
+ pushStatus = {
396
+ ...pushStatus,
397
+ promotionStatus: "hosted_source_publish_failed",
398
+ hostedPublish: {
399
+ status: "failed",
400
+ agentId: hostedRuntimeAgentId,
401
+ error: message
402
+ },
403
+ error: message
404
+ };
405
+ await saveProfilePushStatus(pushStatus);
406
+ throw new Error(`Hosted source publish failed after push: ${message}`);
407
+ }
408
+ }
409
+ let hostedRun = null;
410
+ if (hostedRunAgentId) {
411
+ const hostedRunRuntimeAgentId = hostedRuntimeAgentId || hostedRunAgentId;
412
+ const hostedRunStartedAt = (/* @__PURE__ */ new Date()).toISOString();
413
+ const hostedRunInput = parseJsonObjectOption(options, "hostedRunInput") ?? { prompt: "hello", channel: "openpond_chat" };
414
+ const hostedRunConversationId = optionString(options, "hostedRunConversationId") || optionString(options, "conversationId");
415
+ const hostedRunTargetProjectId = optionString(options, "hostedRunTargetProjectId");
416
+ const hostedRunIdempotencyKey = buildHostedRunIdempotencyKey({
417
+ explicitKey: optionString(options, "hostedRunIdempotencyKey"),
418
+ retry: parseBooleanOption(options.hostedRunRetry),
419
+ localHead: state.git.head,
420
+ sourceHead: pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? result.sourceUpload.sourceCommitSha,
421
+ runtimeAgentId: hostedRunRuntimeAgentId,
422
+ targetProjectId: hostedRunTargetProjectId,
423
+ input: hostedRunInput
424
+ });
425
+ await saveProfilePushStatus({
426
+ ...pushStatus,
427
+ promotionStatus: "hosted_run_pending",
428
+ hostedRunStatus: "running",
429
+ hostedRunAgentId: hostedRunRuntimeAgentId,
430
+ hostedRunAt: hostedRunStartedAt
431
+ });
432
+ try {
433
+ hostedRun = await client.agents.run(hostedRunRuntimeAgentId, {
434
+ teamId,
435
+ ...hostedRunConversationId ? { conversationId: hostedRunConversationId } : {},
436
+ ...hostedRunTargetProjectId ? { targetProjectId: hostedRunTargetProjectId } : {},
437
+ ...hostedRunTargetProjectId ? { targetProject: { id: hostedRunTargetProjectId } } : {},
438
+ idempotencyKey: hostedRunIdempotencyKey,
439
+ input: hostedRunInput,
440
+ metadata: {
441
+ source: "openpond_profile_push_run",
442
+ ...hostedRunConversationId ? { conversationId: hostedRunConversationId } : {},
443
+ targetProjectId: hostedRunTargetProjectId || null,
444
+ localHead: state.git.head,
445
+ hostedHead: result.sourceUpload.sourceCommitSha,
446
+ hostedRunIdempotencyKey,
447
+ hostedRunRetry: parseBooleanOption(options.hostedRunRetry),
448
+ materializedProjectId: pushStatus.hostedSourceMaterialization?.projectId ?? null,
449
+ materializedSourceCommitSha: pushStatus.hostedSourceMaterialization?.sourceCommitSha ?? null,
450
+ sourceRef: pushStatus.hostedSourceMaterialization?.sourceRef ?? result.sourceUpload.sourceRef,
451
+ publishedSnapshotId: pushStatus.hostedPublish?.snapshotId ?? null,
452
+ manifestHash: pushStatus.hostedPublish?.manifestHash ?? pushStatus.hostedSourceCheck?.manifestHash ?? null
453
+ },
454
+ runtimeSourcePolicy: publishHostedSource ? {
455
+ requirePublishedSnapshot: true,
456
+ source: "diagnostic"
457
+ } : {
458
+ allowLatestSource: true,
459
+ source: "diagnostic"
460
+ }
461
+ });
462
+ const hostedRunSummary = hostedRunSummaryFromPayload({
463
+ agentId: hostedRunRuntimeAgentId,
464
+ runResult: hostedRun
465
+ });
466
+ const hostedRunStatus = hostedRunStatusFromRunSummary(hostedRunSummary);
467
+ await saveProfilePushStatus({
468
+ ...pushStatus,
469
+ promotionStatus: hostedRunStatus === "passed" ? "hosted_run_passed" : hostedRunStatus === "failed" ? "hosted_run_failed" : "hosted_run_pending",
470
+ hostedRunStatus,
471
+ hostedRunAgentId: hostedRunRuntimeAgentId,
472
+ hostedRunId: hostedRun.run.id,
473
+ hostedRunAt: hostedRun.run.createdAt ?? hostedRunStartedAt,
474
+ hostedRun: hostedRunSummary
475
+ });
476
+ } catch (error) {
477
+ const message = error instanceof Error ? error.message : String(error);
478
+ await saveProfilePushStatus({
479
+ ...pushStatus,
480
+ promotionStatus: "hosted_run_failed",
481
+ hostedRunStatus: "failed",
482
+ hostedRunAgentId: hostedRunRuntimeAgentId,
483
+ hostedRunAt: (/* @__PURE__ */ new Date()).toISOString(),
484
+ hostedRun: {
485
+ status: "failed",
486
+ agentId: hostedRunRuntimeAgentId,
487
+ error: message
488
+ },
489
+ error: message
490
+ });
491
+ throw new Error(`Hosted invocation failed to start after push: ${message}`);
492
+ }
493
+ }
494
+ if (parseBooleanOption(options.json)) {
495
+ console.log(
496
+ JSON.stringify(
497
+ {
498
+ ...result,
499
+ uploaded: summarizeProfileSourceUpload(upload),
500
+ hostedSourceMaterialization: pushStatus.hostedSourceMaterialization ?? null,
501
+ hostedSourceChecks,
502
+ hostedSourcePublish,
503
+ hostedRun
504
+ },
505
+ null,
506
+ 2
507
+ )
508
+ );
509
+ return;
510
+ }
511
+ console.log(`Pushed OpenPond profile ${state.activeProfile ?? "default"} to hosted profile repo.`);
512
+ console.log(`Project id: ${result.profile.project.id}`);
513
+ console.log(`Local head: ${state.git.head}`);
514
+ console.log(`Hosted source commit: ${result.sourceUpload.sourceCommitSha ?? "unknown"}`);
515
+ console.log(
516
+ `Uploaded ${upload.fileCount} file(s), ${upload.totalBytes} byte(s) via ${upload.transport.mode} (limits: ${upload.limits.maxFiles} files, ${upload.limits.maxFileBytes} bytes/file, ${upload.limits.maxTotalBytes} bytes total).`
517
+ );
518
+ console.log(
519
+ hostedRun ? `Hosted invocation: running ${hostedRun.run.id}` : "Hosted invocation: not started"
520
+ );
521
+ if (pushStatus.hostedSourceMaterialization) {
522
+ console.log(
523
+ `Hosted materialized: ${pushStatus.hostedSourceMaterialization.status}` + (pushStatus.hostedSourceMaterialization.projectId ? ` ${pushStatus.hostedSourceMaterialization.projectId}` : "") + (pushStatus.hostedSourceMaterialization.sourceCommitSha ? ` ${pushStatus.hostedSourceMaterialization.sourceCommitSha}` : "")
524
+ );
525
+ }
526
+ if (pushStatus.hostedSourceCheck) {
527
+ console.log(
528
+ `Hosted source checks: ${pushStatus.hostedSourceCheck.status}` + (pushStatus.hostedSourceCheck.workItemId ? ` ${pushStatus.hostedSourceCheck.workItemId}` : "")
529
+ );
530
+ }
531
+ if (pushStatus.hostedPublish) {
532
+ console.log(
533
+ `Hosted publish: ${pushStatus.hostedPublish.status}` + (pushStatus.hostedPublish.snapshotId ? ` ${pushStatus.hostedPublish.snapshotId}` : "")
534
+ );
535
+ }
536
+ console.log(`Uploaded files: ${upload.fileCount}`);
537
+ }
538
+ function summarizeProfileSourceUpload(upload) {
539
+ return {
540
+ fileCount: upload.fileCount,
541
+ totalBytes: upload.totalBytes,
542
+ limits: upload.limits,
543
+ transport: upload.transport
544
+ };
545
+ }
546
+ function normalizeHostedProfileManifest(manifest) {
547
+ return {
548
+ ...manifest,
549
+ profiles: Object.fromEntries(
550
+ Object.entries(manifest.profiles).map(([name, profile]) => [
551
+ name,
552
+ {
553
+ path: profile.path,
554
+ defaultAgent: profile.defaultAgent ?? "default",
555
+ enabledAgents: profile.enabledAgents ?? []
556
+ }
557
+ ])
558
+ )
559
+ };
560
+ }
561
+ async function collectProfileSourceUploadForPush(input) {
562
+ const repoPath = input.state.repoPath;
563
+ if (!repoPath) {
564
+ throw new Error("Active OpenPond profile is missing a repository path.");
565
+ }
566
+ const collected = await collectProfileSourceUploadEntries(repoPath);
567
+ if (!input.hostedSourceAgentId) return collected;
568
+ if (!input.state.sourcePath) {
569
+ throw new Error("Active OpenPond profile is missing a source path.");
570
+ }
571
+ const agent = input.state.agents.find(
572
+ (candidate) => candidate.id === input.hostedSourceAgentId
573
+ );
574
+ if (!agent) {
575
+ throw new Error(
576
+ `Profile agent not found for hosted source upload: ${input.hostedSourceAgentId}`
577
+ );
578
+ }
579
+ const sourceRoot = resolveProfileAgentSourceRoot(
580
+ input.state.sourcePath,
581
+ agent.path
582
+ );
583
+ const relativeSourceRoot = path.relative(repoPath, sourceRoot).replace(/\\/g, "/");
584
+ if (relativeSourceRoot.startsWith("..") || path.isAbsolute(relativeSourceRoot)) {
585
+ throw new Error(`Profile agent path escapes profile repo: ${agent.path}`);
586
+ }
587
+ const agentSdk = await collectAgentSdkProjectSourceUploadEntries(
588
+ sourceRoot,
589
+ []
590
+ );
591
+ if (agentSdk.entries.length === 0) return collected;
592
+ return mergeProjectSourceUploadEntries(
593
+ collected,
594
+ agentSdk.entries.map((entry) => ({
595
+ ...entry,
596
+ path: relativeSourceRoot ? `${relativeSourceRoot}/${entry.path}` : entry.path
597
+ }))
598
+ );
599
+ }
600
+ async function materializeHostedProfileAgentSource(input) {
601
+ if (!input.state.sourcePath) {
602
+ throw new Error("Active OpenPond profile is missing a source path.");
603
+ }
604
+ const agent = input.state.agents.find((candidate) => candidate.id === input.agentId);
605
+ if (!agent) {
606
+ throw new Error(`Profile agent not found for hosted materialization: ${input.agentId}`);
607
+ }
608
+ const sourceRoot = resolveProfileAgentSourceRoot(input.state.sourcePath, agent.path);
609
+ const collected = await collectProjectSourceUploadEntries(sourceRoot);
610
+ const agentSdk = await collectAgentSdkProjectSourceUploadEntries(sourceRoot, collected.entries);
611
+ const upload = mergeProjectSourceUploadEntries(collected, agentSdk.entries);
612
+ const materializationProject = await getOrCreateHostedSourceProject({
613
+ client: input.client,
614
+ teamId: input.teamId,
615
+ projectId: input.projectId ?? null,
616
+ profileProjectId: input.profileProjectId,
617
+ profileName: input.profileName,
618
+ agentId: input.agentId,
619
+ localHead: input.localHead,
620
+ hostedHead: input.hostedHead
621
+ });
622
+ const uploadedProject = await input.client.projects.uploadSource(materializationProject.id, {
623
+ teamId: input.teamId,
624
+ entries: upload.entries,
625
+ branch: input.sourceRef,
626
+ commitMessage: `Materialize OpenPond profile agent ${input.agentId}`
627
+ });
628
+ const syncedProject = await input.client.projects.sync(uploadedProject.id, {
629
+ teamId: input.teamId
630
+ });
631
+ const sourceCommitSha = sandboxProjectSourceCommitSha(syncedProject) ?? sandboxProjectSourceCommitSha(uploadedProject);
632
+ const sourceRef = sandboxProjectSourceRef(syncedProject) ?? sandboxProjectSourceRef(uploadedProject) ?? input.sourceRef;
633
+ const selectedEntrypoint = hostedEntrypointForProfileAgent(input.state, input.agentId);
634
+ const runtimeAgent = await input.client.agents.upsert({
635
+ teamId: input.teamId,
636
+ projectId: syncedProject.id,
637
+ name: agent.name || input.agentId,
638
+ slug: hostedRuntimeAgentSlug(input.profileName, input.agentId),
639
+ selectedEntrypoint,
640
+ triggerType: "manual",
641
+ runtimeSource: {
642
+ mode: "latest_source",
643
+ ...sourceRef ? { sourceRef } : {},
644
+ ...sourceCommitSha ? { sourceCommitSha } : {}
645
+ },
646
+ metadata: {
647
+ source: "openpond_profile_agent_materialization",
648
+ profileProjectId: input.profileProjectId,
649
+ profileName: input.profileName,
650
+ profileAgentId: input.agentId,
651
+ profileSourcePath: agent.path,
652
+ localHead: input.localHead,
653
+ hostedHead: input.hostedHead
654
+ },
655
+ externalId: `openpond-profile-agent:${input.profileProjectId}:${input.profileName}:${input.agentId}`
656
+ });
657
+ const uploadMetadata = record(agentSdk.uploadMetadata);
658
+ const commands = record(uploadMetadata?.commands);
659
+ const dependencySetup = record(uploadMetadata?.dependencySetup);
660
+ const setupCommands = stringArray(dependencySetup?.commands);
661
+ const validationCommands = [
662
+ text(commands?.validate),
663
+ text(commands?.eval)
664
+ ].filter((command) => Boolean(command));
665
+ return {
666
+ status: "uploaded",
667
+ agentId: input.agentId,
668
+ runtimeAgentId: runtimeAgent.id,
669
+ projectId: syncedProject.id,
670
+ sourceRoot,
671
+ sourceRef,
672
+ sourceCommitSha: sourceCommitSha ?? null,
673
+ manifestHash: syncedProject.sandboxManifestHash ?? null,
674
+ manifestPath: syncedProject.sandboxManifestPath ?? null,
675
+ manifestSyncedAt: syncedProject.sandboxManifestSyncedAt ?? null,
676
+ fileCount: upload.fileCount,
677
+ totalBytes: upload.totalBytes,
678
+ generatedManifestPath: agentSdk.generatedManifestPath,
679
+ synthesizedOpenPondYaml: agentSdk.synthesizedOpenPondYaml,
680
+ uploadMetadataPath: agentSdk.uploadMetadataPath,
681
+ setupCommands,
682
+ validationCommands,
683
+ materializedAt: (/* @__PURE__ */ new Date()).toISOString()
684
+ };
685
+ }
686
+ async function getOrCreateHostedSourceProject(input) {
687
+ if (input.projectId) {
688
+ try {
689
+ return await input.client.projects.get(input.projectId, {
690
+ teamId: input.teamId
691
+ });
692
+ } catch {
693
+ }
694
+ }
695
+ return input.client.projects.upsert({
696
+ teamId: input.teamId,
697
+ name: `OpenPond profile ${input.profileName} ${input.agentId}`,
698
+ sourceType: "manual",
699
+ externalId: `openpond-profile:${input.profileProjectId}:${input.profileName}:${input.agentId}`,
700
+ description: `Materialized OpenPond profile agent ${input.agentId} for hosted sandbox checks.`,
701
+ metadata: {
702
+ source: "openpond_profile_agent_materialization",
703
+ profileProjectId: input.profileProjectId,
704
+ profileName: input.profileName,
705
+ profileAgentId: input.agentId,
706
+ localHead: input.localHead,
707
+ hostedHead: input.hostedHead
708
+ }
709
+ });
710
+ }
711
+ function resolveProfileAgentSourceRoot(sourcePath, agentPath) {
712
+ const normalized = agentPath.replace(/\\/g, "/");
713
+ const absolute = path.resolve(sourcePath, normalized);
714
+ const relative = path.relative(sourcePath, absolute);
715
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
716
+ throw new Error(`Profile agent path escapes profile source: ${agentPath}`);
717
+ }
718
+ return normalized === "agent/agent.ts" || normalized.endsWith("/agent.ts") ? sourcePath : absolute;
719
+ }
720
+ function hostedEntrypointForProfileAgent(state, agentId) {
721
+ const action = state.actionCatalog.find(
722
+ (candidate) => candidate.agentId === agentId && (candidate.sourceActionId === "chat" || candidate.name === "chat")
723
+ ) ?? state.actionCatalog.find((candidate) => candidate.agentId === agentId);
724
+ return {
725
+ scope: "action",
726
+ name: typeof action?.sourceActionId === "string" && action.sourceActionId || typeof action?.name === "string" && action.name || "chat"
727
+ };
728
+ }
729
+ function hostedRuntimeAgentSlug(profileName, agentId) {
730
+ const slug = `openpond-profile-${profileName}-${agentId}`.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
731
+ return slug || "openpond-profile-agent";
732
+ }
733
+ function sandboxProjectSourceCommitSha(project) {
734
+ const item = record(project);
735
+ const sourceConfig = record(item?.sourceConfig);
736
+ const metadata = record(item?.metadata);
737
+ return text(sourceConfig?.sourceCommitSha) ?? text(sourceConfig?.commitSha) ?? text(sourceConfig?.remoteSha) ?? text(metadata?.projectSourceUploadCommitSha) ?? text(metadata?.sourceCommitSha) ?? text(item?.templateRemoteSha);
738
+ }
739
+ function sandboxProjectSourceRef(project) {
740
+ const item = record(project);
741
+ const sourceConfig = record(item?.sourceConfig);
742
+ return text(sourceConfig?.sourceRef) ?? text(sourceConfig?.branch) ?? text(item?.gitBranch) ?? text(item?.defaultBranch);
743
+ }
744
+ function record(value) {
745
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
746
+ }
747
+ function text(value) {
748
+ return typeof value === "string" && value.trim() ? value.trim() : null;
749
+ }
750
+ function stringArray(value) {
751
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
752
+ }
753
+ function resolveHostedRuntimeAgentIdForRun(state, hostedRunAgentId) {
754
+ if (!hostedRunAgentId) return null;
755
+ const materialization = state.hosted?.hostedSourceMaterialization;
756
+ if (materialization?.agentId === hostedRunAgentId && materialization.runtimeAgentId) {
757
+ return materialization.runtimeAgentId;
758
+ }
759
+ return hostedRunAgentId;
760
+ }
761
+ async function refreshHostedSourceCheckStatus(input) {
762
+ const workItemId = text(record(input.checkResult.workItem)?.id);
763
+ if (!workItemId) return null;
764
+ const status = await input.client.workItems.status(workItemId, {
765
+ teamId: input.teamId,
766
+ includeArchived: true,
767
+ limit: 50
768
+ });
769
+ return {
770
+ ...input.checkResult,
771
+ workItem: status.workItem,
772
+ activity: status.activity,
773
+ sourceCheckStatus: status.sourceCheckStatus
774
+ };
775
+ }
776
+ async function bindValidatedHostedRuntimeSource(input) {
777
+ if (!input.sourceRef || !input.sourceCommitSha) return;
778
+ await input.client.agents.update(input.runtimeAgentId, {
779
+ teamId: input.teamId,
780
+ runtimeSource: {
781
+ mode: "latest_source",
782
+ sourceRef: input.sourceRef,
783
+ sourceCommitSha: input.sourceCommitSha,
784
+ buildStatus: "succeeded",
785
+ validationStatus: "passed",
786
+ validatedAt: input.validatedAt
787
+ }
788
+ });
789
+ }
790
+ function sourceCheckStatusPassed(status) {
791
+ if (!status) return false;
792
+ const finalResultState = text(status.finalResultState)?.toLowerCase();
793
+ if (finalResultState && finalResultState !== "completed" && !passingStatus(finalResultState)) {
794
+ return false;
795
+ }
796
+ const checkRuns = Array.isArray(status.checkRuns) ? status.checkRuns.map(record).filter((item) => Boolean(item)) : [];
797
+ if (checkRuns.some(checkRunFailed)) return false;
798
+ const buildPassed = checkRuns.some(
799
+ (run) => checkRunCommand(run).includes("build") && checkEvidencePassed(run)
800
+ );
801
+ const validationPassed = checkEvidencePassed(record(status.validation)) || checkRuns.some(
802
+ (run) => checkRunCommand(run).includes("validate") && checkEvidencePassed(run)
803
+ );
804
+ const evalEvidence = record(status.eval);
805
+ const evalRequired = (text(status.requestedCheckKind) ?? "all") === "all" || (text(status.requestedCheckKind) ?? "") === "eval" || Boolean(evalEvidence) || checkRuns.some((run) => checkRunCommand(run).includes("eval"));
806
+ const evalPassed = !evalRequired || checkEvidencePassed(evalEvidence) || checkRuns.some(
807
+ (run) => checkRunCommand(run).includes("eval") && checkEvidencePassed(run)
808
+ );
809
+ return buildPassed && validationPassed && evalPassed;
810
+ }
811
+ function checkRunCommand(run) {
812
+ return (text(run.command) ?? "").toLowerCase();
813
+ }
814
+ function checkRunFailed(run) {
815
+ const passed = run.passed;
816
+ if (typeof passed === "boolean") return !passed;
817
+ const exitCode = run.exitCode;
818
+ if (typeof exitCode === "number" && exitCode !== 0) return true;
819
+ const status = text(run.status)?.toLowerCase();
820
+ return Boolean(status && failingStatus(status));
821
+ }
822
+ function checkEvidencePassed(evidence) {
823
+ if (!evidence) return false;
824
+ if (typeof evidence.passed === "boolean") return evidence.passed;
825
+ const failed = numericEvidence(evidence.failed) ?? numericEvidence(evidence.failedCount);
826
+ if (failed !== null && failed > 0) return false;
827
+ const exitCode = evidence.exitCode;
828
+ if (typeof exitCode === "number") return exitCode === 0;
829
+ const status = text(evidence.status)?.toLowerCase();
830
+ return Boolean(status && passingStatus(status));
831
+ }
832
+ function numericEvidence(value) {
833
+ if (typeof value === "number" && Number.isFinite(value)) return value;
834
+ if (typeof value === "string" && value.trim()) {
835
+ const parsed = Number(value);
836
+ return Number.isFinite(parsed) ? parsed : null;
837
+ }
838
+ return null;
839
+ }
840
+ function passingStatus(status) {
841
+ return status === "passed" || status === "succeeded" || status === "success";
842
+ }
843
+ function failingStatus(status) {
844
+ return status === "failed" || status === "failure" || status === "cancelled";
845
+ }
846
+ async function runHostedProfileStatusCommand(options) {
847
+ const teamId = requiredTeamId(
848
+ options,
849
+ "usage: openpond profile hosted status"
850
+ );
851
+ const client = await resolveSandboxClient(options);
852
+ const profile = await client.profile.get({ teamId });
853
+ if (parseBooleanOption(options.json)) {
854
+ console.log(JSON.stringify({ profile }, null, 2));
855
+ return;
856
+ }
857
+ if (!profile) {
858
+ console.log("No hosted OpenPond profile repo found.");
859
+ console.log("Run `openpond profile ensure-hosted --team-id <id>` to create one.");
860
+ return;
861
+ }
862
+ printHostedProfileSummary(profile);
863
+ }
864
+ async function runHostedProfileEnsureCommand(options) {
865
+ const teamId = requiredTeamId(
866
+ options,
867
+ "usage: openpond profile ensure-hosted"
868
+ );
869
+ const client = await resolveSandboxClient(options);
870
+ const profile = await client.profile.ensureHosted({ teamId });
871
+ if (parseBooleanOption(options.json)) {
872
+ console.log(JSON.stringify({ profile }, null, 2));
873
+ return;
874
+ }
875
+ printHostedProfileSummary(profile);
876
+ }
877
+ async function runOpenPondAgentsCommand(options, rest) {
878
+ const subcommand = rest[0] ?? "list";
879
+ if (subcommand !== "list") {
880
+ throw new Error("usage: openpond agents list [--json]");
881
+ }
882
+ const state = await loadOpenPondProfileState();
883
+ if (state.error) throw new Error(state.error);
884
+ if (parseBooleanOption(options.json)) {
885
+ console.log(JSON.stringify({ agents: state.agents, profile: state }, null, 2));
886
+ return;
887
+ }
888
+ if (state.mode === "none") {
889
+ console.log("No active OpenPond profile. Run `openpond init`.");
890
+ return;
891
+ }
892
+ if (state.agents.length === 0) {
893
+ console.log(`No agents found in ${state.activeProfile}.`);
894
+ return;
895
+ }
896
+ for (const agent of state.agents) {
897
+ console.log(`${agent.id} ${agent.enabled ? "enabled" : "disabled"} ${agent.path}`);
898
+ }
899
+ }
900
+ async function runOpenPondProfileSdkAlias(command, options, rest) {
901
+ const cwd = optionString(options, "cwd");
902
+ const args = [...rest, ...optionArgs(options, /* @__PURE__ */ new Set(["cwd", "account", "profile", "handle", "baseUrl"]))];
903
+ await runProfileSdkCommand({
904
+ command,
905
+ cwd: cwd ? path.resolve(cwd) : void 0,
906
+ args,
907
+ inherit: true
908
+ });
909
+ }
910
+ function printProfileState(state) {
911
+ if (state.mode === "none") {
912
+ console.log("No active OpenPond profile.");
913
+ console.log(`Default location: ${defaultLocalProfileRepoPath()}`);
914
+ return;
915
+ }
916
+ console.log(`Mode: ${state.mode}`);
917
+ console.log(`Repo: ${state.repoPath}`);
918
+ console.log(`Profile: ${state.activeProfile}`);
919
+ console.log(`Source: ${state.sourcePath ?? "missing"}`);
920
+ console.log(`State: ${state.summary.message}`);
921
+ if (state.git) {
922
+ console.log(`Git: ${state.git.branch ?? "detached"} ${state.git.shortHead ?? "no-head"}${state.git.dirty ? " dirty" : " clean"}`);
923
+ if (state.git.upstream) {
924
+ console.log(`Upstream: ${state.git.upstream} ahead ${state.git.ahead ?? "?"} behind ${state.git.behind ?? "?"}`);
925
+ }
926
+ }
927
+ if (state.hosted?.projectId || state.hosted?.sourceCommitSha) {
928
+ console.log(`Hosted: ${state.hosted.projectId ?? "unbound"} ${state.hosted.sourceCommitSha ?? "no-source-head"}`);
929
+ if (state.hosted.hostedSourceMaterialization) {
930
+ console.log(
931
+ `Hosted materialized: ${state.hosted.hostedSourceMaterialization.status}` + (state.hosted.hostedSourceMaterialization.agentId ? ` ${state.hosted.hostedSourceMaterialization.agentId}` : "") + (state.hosted.hostedSourceMaterialization.sourceCommitSha ? ` ${state.hosted.hostedSourceMaterialization.sourceCommitSha}` : "")
932
+ );
933
+ }
934
+ if (state.hosted.hostedSourceCheck) {
935
+ console.log(
936
+ `Hosted checks: ${state.hosted.hostedSourceCheck.status}` + (state.hosted.hostedSourceCheck.workItemId ? ` ${state.hosted.hostedSourceCheck.workItemId}` : "") + (state.hosted.hostedSourceCheck.sandboxId ? ` sandbox ${state.hosted.hostedSourceCheck.sandboxId}` : "")
937
+ );
938
+ }
939
+ if (state.hosted.hostedPublish) {
940
+ console.log(
941
+ `Hosted publish: ${state.hosted.hostedPublish.status}` + (state.hosted.hostedPublish.snapshotId ? ` ${state.hosted.hostedPublish.snapshotId}` : "")
942
+ );
943
+ }
944
+ if (state.hosted.hostedRun) {
945
+ console.log(
946
+ `Hosted run: ${state.hosted.hostedRun.status}` + (state.hosted.hostedRun.runId ? ` ${state.hosted.hostedRun.runId}` : "") + (state.hosted.hostedRun.runtimeId ? ` runtime ${state.hosted.hostedRun.runtimeId}` : "")
947
+ );
948
+ }
949
+ }
950
+ console.log(`Catalog: ${state.catalog.actionCount} action(s)${state.catalog.stale ? " stale" : ""}`);
951
+ console.log(
952
+ `Setup gate: ${state.setupGate.status} (${state.setupGate.blockingCount} blocking, ${state.setupGate.optionalMissingCount} optional missing)`
953
+ );
954
+ if (state.summary.defaultAction) {
955
+ console.log(`Default action: ${state.summary.defaultAction}`);
956
+ }
957
+ if (state.setupGate.blockingRequirements.length > 0) {
958
+ console.log("Blocking setup:");
959
+ for (const requirement of state.setupGate.blockingRequirements.slice(0, 10)) {
960
+ console.log(` ${formatOpenPondProfileSetupRequirement(requirement)}`);
961
+ }
962
+ if (state.setupGate.blockingRequirements.length > 10) {
963
+ console.log(` ... ${state.setupGate.blockingRequirements.length - 10} more`);
964
+ }
965
+ }
966
+ if (!state.summary.checkFresh && state.summary.checkStaleReason) {
967
+ console.log(`Checks: stale - ${state.summary.checkStaleReason}`);
968
+ } else if (state.summary.checkFresh) {
969
+ console.log("Checks: fresh");
970
+ }
971
+ if (state.lastCheck) {
972
+ console.log(`Last check: ${state.lastCheck.command} ${state.lastCheck.status} at ${state.lastCheck.checkedAt}`);
973
+ }
974
+ if (state.error) {
975
+ console.log(`Error: ${state.error}`);
976
+ }
977
+ if (state.agents.length > 0) {
978
+ console.log("Agents:");
979
+ for (const agent of state.agents) {
980
+ console.log(` ${agent.id} (${agent.enabled ? "enabled" : "disabled"}) ${agent.path}`);
981
+ }
982
+ }
983
+ if (state.skills.length > 0) {
984
+ console.log("Skills:");
985
+ for (const skill of state.skills) {
986
+ const status = skill.validationStatus === "valid" ? "valid" : skill.validationStatus;
987
+ console.log(` ${skill.name} (${status}) ${skill.path}`);
988
+ }
989
+ }
990
+ }
991
+ function printProfileDiff(state) {
992
+ if (state.mode === "none") {
993
+ console.log("No active OpenPond profile.");
994
+ return;
995
+ }
996
+ console.log(`Profile: ${state.activeProfile}`);
997
+ console.log(`State: ${state.summary.message}`);
998
+ const groups = [
999
+ ["Changed agents", state.diff.changedAgents],
1000
+ ["New agents", state.diff.newAgents],
1001
+ ["Deleted agents", state.diff.deletedAgents],
1002
+ ["Changed skills", state.diff.changedSkills],
1003
+ ["Changed actions", state.diff.changedActions],
1004
+ ["Changed extensions", state.diff.changedExtensions],
1005
+ ["Setup changes", state.diff.setupChanges],
1006
+ ["Env requirement changes", state.diff.envRequirementChanges]
1007
+ ];
1008
+ for (const [label, values] of groups) {
1009
+ if (values.length === 0) continue;
1010
+ console.log(`${label}: ${values.join(", ")}`);
1011
+ }
1012
+ if (state.diff.files.length === 0) {
1013
+ console.log("No source changes.");
1014
+ return;
1015
+ }
1016
+ console.log("Files:");
1017
+ for (const file of state.diff.files) {
1018
+ console.log(` ${file.status.padEnd(2)} ${file.path}`);
1019
+ }
1020
+ }
1021
+ function printProfileCatalog(state) {
1022
+ if (state.mode === "none") {
1023
+ console.log("No active OpenPond profile.");
1024
+ return;
1025
+ }
1026
+ console.log(`Profile: ${state.activeProfile}`);
1027
+ console.log(`Catalog: ${state.catalog.actionCount} action(s)${state.catalog.stale ? " stale" : ""}`);
1028
+ console.log(
1029
+ `Setup gate: ${state.setupGate.status} (${state.setupGate.blockingCount} blocking, ${state.setupGate.optionalMissingCount} optional missing)`
1030
+ );
1031
+ if (state.catalog.generatedAt) console.log(`Generated at: ${state.catalog.generatedAt}`);
1032
+ if (state.catalog.error) console.log(`Catalog error: ${state.catalog.error}`);
1033
+ if (state.actionCatalog.length === 0) {
1034
+ console.log("No catalog actions found. Run `openpond inspect` or `openpond build`.");
1035
+ return;
1036
+ }
1037
+ for (const action of state.actionCatalog) {
1038
+ const label = action.label ?? action.name ?? action.id;
1039
+ const visibility = action.visibility ?? "default";
1040
+ const actionBlocking = state.setupGate.blockingRequirements.filter(
1041
+ (requirement) => requirement.actionId === action.id
1042
+ );
1043
+ const setup = actionBlocking.length ? `setup_required:${actionBlocking.map((requirement) => requirement.label).join(",")}` : "setup_ready";
1044
+ console.log(`${action.id} ${visibility} ${setup} ${label}`);
1045
+ }
1046
+ const sourceBlocking = state.setupGate.blockingRequirements.filter(
1047
+ (requirement) => requirement.actionId === null
1048
+ );
1049
+ if (sourceBlocking.length > 0) {
1050
+ console.log("Source setup blockers:");
1051
+ for (const requirement of sourceBlocking) {
1052
+ console.log(` ${formatOpenPondProfileSetupRequirement(requirement)}`);
1053
+ }
1054
+ }
1055
+ }
1056
+ function printHostedProfileSummary(profile) {
1057
+ console.log(`Hosted profile repo: ${profile.project.name}`);
1058
+ console.log(`Project id: ${profile.project.id}`);
1059
+ console.log(`Role: ${profile.project.role ?? "profile"}`);
1060
+ console.log(`Default profile: ${profile.defaultProfile}`);
1061
+ console.log(`Source path: ${profile.sourcePath}`);
1062
+ console.log(`Seed status: ${profile.seedStatus}`);
1063
+ if (profile.sourceUpload?.sourceRef) {
1064
+ console.log(`Source ref: ${profile.sourceUpload.sourceRef}`);
1065
+ }
1066
+ if (profile.sourceUpload?.sourceCommitSha) {
1067
+ console.log(`Source commit: ${profile.sourceUpload.sourceCommitSha}`);
1068
+ }
1069
+ if (profile.seededAt) {
1070
+ console.log(`Seeded at: ${profile.seededAt}`);
1071
+ }
1072
+ if (profile.agents.length > 0) {
1073
+ console.log("Agents:");
1074
+ for (const agent of profile.agents) {
1075
+ console.log(` ${agent.id} (${agent.enabled ? "enabled" : "disabled"}) ${agent.path}`);
1076
+ }
1077
+ }
1078
+ }
1079
+ function optionArgs(options, ignored) {
1080
+ const args = [];
1081
+ const booleanFlags = /* @__PURE__ */ new Set(["force", "json"]);
1082
+ for (const [key, value] of Object.entries(options)) {
1083
+ if (ignored.has(key)) continue;
1084
+ const flag = `--${key.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`)}`;
1085
+ if (value === true || booleanFlags.has(key) && value === "true") {
1086
+ args.push(flag);
1087
+ } else if (booleanFlags.has(key) && value === "false") {
1088
+ continue;
1089
+ } else if (typeof value === "string") {
1090
+ args.push(flag, value);
1091
+ }
1092
+ }
1093
+ return args;
1094
+ }
1095
+ function parseJsonObjectOption(options, key) {
1096
+ const raw = optionString(options, key);
1097
+ if (!raw) return null;
1098
+ const parsed = JSON.parse(raw);
1099
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1100
+ throw new Error(`--${key} must be a JSON object`);
1101
+ }
1102
+ return parsed;
1103
+ }
1104
+ export {
1105
+ collectProfileSourceUploadForPush,
1106
+ runOpenPondAgentsCommand,
1107
+ runOpenPondInitCommand,
1108
+ runOpenPondProfileCommand,
1109
+ runOpenPondProfileSdkAlias
1110
+ };