openpond 0.0.68 → 0.0.69

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 (128) hide show
  1. package/dist/chunks/{actions-command-DLOKFA34.js → actions-command-6N5XWMR6.js} +4 -4
  2. package/dist/chunks/{app-layer-K7NAOLDL.js → app-layer-EXXOWJ5H.js} +7 -7
  3. package/dist/chunks/{app-server-runtime-OFZZIWAB.js → app-server-runtime-7FBQBE3C.js} +10 -10
  4. package/dist/chunks/{apps-5VSVJLM7.js → apps-RZSDOFAG.js} +7 -7
  5. package/dist/chunks/{chunk-N6FKRVAT.js → chunk-47EIAYI7.js} +2 -2
  6. package/dist/chunks/{chunk-7FW2CVYN.js → chunk-4L3ZJS2T.js} +426 -1
  7. package/dist/chunks/{chunk-OOJP442J.js → chunk-5TKZBMQM.js} +1 -1
  8. package/dist/chunks/{chunk-WEB37YVJ.js → chunk-7C4OIFOC.js} +1 -1
  9. package/dist/chunks/{chunk-MUS7KPXK.js → chunk-BLFIIAWZ.js} +1931 -19
  10. package/dist/chunks/{chunk-3KLQ52B2.js → chunk-BVY5JYM6.js} +4 -9
  11. package/dist/chunks/{chunk-DBHSOTYZ.js → chunk-D7BO5Y5J.js} +3 -24
  12. package/dist/chunks/chunk-DLQQIWN2.js +648 -0
  13. package/dist/chunks/{chunk-T55IL3GI.js → chunk-DNXBJZAU.js} +1 -1
  14. package/dist/chunks/{chunk-KLD7NT5J.js → chunk-F36ZVO6U.js} +3 -3
  15. package/dist/chunks/{chunk-TSDVA7QP.js → chunk-FEOLMLYU.js} +8 -12
  16. package/dist/chunks/{chunk-QETF6ILG.js → chunk-FQS2QL5F.js} +359 -841
  17. package/dist/chunks/{chunk-J2REM7LE.js → chunk-HFPUR4CQ.js} +5 -116
  18. package/dist/chunks/{chunk-JIEUB6OS.js → chunk-J3YDKJFD.js} +1 -1
  19. package/dist/chunks/{chunk-JGOP4GCK.js → chunk-JTHL5XJ2.js} +5 -25
  20. package/dist/chunks/{chunk-OQLYO7TA.js → chunk-MMRJNSWY.js} +34 -81
  21. package/dist/chunks/{chunk-HFQHD35D.js → chunk-NPNIL6SQ.js} +1 -1
  22. package/dist/chunks/{chunk-IG72OKNB.js → chunk-OOM2PHBE.js} +2080 -16400
  23. package/dist/chunks/{chunk-PSGEH4FC.js → chunk-QTN6HXOR.js} +3 -3
  24. package/dist/chunks/{chunk-HNY7OSDY.js → chunk-SFMNGWNO.js} +1 -1
  25. package/dist/chunks/{chunk-TBEBLKCQ.js → chunk-WBAZFKC7.js} +3 -3
  26. package/dist/chunks/{chunk-NA4L2HQM.js → chunk-Y57RTLVV.js} +33 -33
  27. package/dist/chunks/{chunk-Z2ZWHU7O.js → chunk-YVCYVDNP.js} +1 -1
  28. package/dist/chunks/{cli-6WFY2ULA.js → cli-HIXVXM72.js} +8 -8
  29. package/dist/chunks/{core-commands-HQ3HL34W.js → core-commands-34SVH6ZQ.js} +8 -8
  30. package/dist/chunks/{desktop-test-RU6SRARQ.js → desktop-test-66DPBNJX.js} +7 -7
  31. package/dist/chunks/{extension-4KFKWMC4.js → extension-ZMRHCDO3.js} +36 -87
  32. package/dist/chunks/{help-ZUCPOR22.js → help-COHCZEP2.js} +1 -1
  33. package/dist/chunks/{opchat-AZX7SYM7.js → opchat-2PGW2GNN.js} +10 -18
  34. package/dist/chunks/{organizations-GV6Z7G4J.js → organizations-NZ4OY56V.js} +9 -9
  35. package/dist/chunks/{profile-TSLGZPUI.js → profile-GEMTRPUG.js} +11 -11
  36. package/dist/chunks/{project-agent-SHIQZWPY.js → project-agent-NX6YBGWC.js} +10 -10
  37. package/dist/chunks/{sandbox-command-TRS66NUT.js → sandbox-command-UEY53OJO.js} +8 -8
  38. package/dist/chunks/{sandbox-template-RVWXD5O3.js → sandbox-template-YKYRB645.js} +10 -10
  39. package/dist/chunks/{src-VUJ6EBOU.js → src-IXYDKOBI.js} +799 -965
  40. package/dist/chunks/{src-Q3BOITLJ.js → src-LKJBD5AM.js} +5 -5
  41. package/dist/chunks/{teams-bot-CLCMGBW5.js → teams-bot-K6KZHZJV.js} +7 -7
  42. package/dist/chunks/{workspaces-IIPITOCV.js → workspaces-WXM72UZF.js} +2 -2
  43. package/dist/cli.js +13 -13
  44. package/dist/index.js +15 -56
  45. package/dist/web/assets/App-BF9L0JUv.js +171 -0
  46. package/dist/web/assets/{AppDialog-sLTPiFGX.js → AppDialog-DX-xs3KA.js} +1 -1
  47. package/dist/web/assets/{AppTerminalPanel-B0NCyY4L.js → AppTerminalPanel-CYVj_ITT.js} +2 -2
  48. package/dist/web/assets/{AppsView-DyDyktK2.js → AppsView-ByjyGog7.js} +1 -1
  49. package/dist/web/assets/{BrowserSidebar-C-PQxmQa.js → BrowserSidebar-BDwtMAZl.js} +1 -1
  50. package/dist/web/assets/{CartesianChart-CnerMhTr.js → CartesianChart-Dv6jJfPR.js} +1 -1
  51. package/dist/web/assets/{CollaborationTabs-DJEp6dux.js → CollaborationTabs-CC5AIhMh.js} +1 -1
  52. package/dist/web/assets/{CommandMenu-B5lGz8rG.js → CommandMenu-Ct0Sx7yP.js} +1 -1
  53. package/dist/web/assets/{CommunityView-DQJaHBa5.js → CommunityView-C_zVE0jg.js} +1 -1
  54. package/dist/web/assets/{ComposerCreateImproveStrip-7hBR2bdV.js → ComposerCreateImproveStrip-CNn4OywM.js} +1 -1
  55. package/dist/web/assets/{GetStartedView-l1Cz1e7g.js → GetStartedView-DRFpHDLd.js} +1 -1
  56. package/dist/web/assets/LabModelVersionDetailPage-BzF-IVXQ.js +1 -0
  57. package/dist/web/assets/{LabSkillSidebar-jlX5I_D5.js → LabSkillSidebar-B9jY4AgE.js} +1 -1
  58. package/dist/web/assets/{LabsRoute-D3w6nPSa.css → LabsRoute-CS_orT9s.css} +1 -1
  59. package/dist/web/assets/LabsRoute-Di1Zs4gZ.js +2 -0
  60. package/dist/web/assets/{MainChatThread-B1nXTMAf.js → MainChatThread-8VzlD8Hi.js} +2 -2
  61. package/dist/web/assets/{MainPane-DxVcMBFo.js → MainPane-StAOFINE.js} +3 -3
  62. package/dist/web/assets/{MarkdownText-B3njGyZS.js → MarkdownText-B8D_ftSJ.js} +1 -1
  63. package/dist/web/assets/{Messages-yBS4UHWl.js → Messages-TY62tiDp.js} +1 -1
  64. package/dist/web/assets/{NativeSkillSidebar-DaD52aW1.js → NativeSkillSidebar-DjebFRoi.js} +1 -1
  65. package/dist/web/assets/{NewExperienceSwitcher-C7X_K5Xl.js → NewExperienceSwitcher-C-bJxHxY.js} +1 -1
  66. package/dist/web/assets/{NewProjectDialog-NuPVF2Y7.js → NewProjectDialog-Cx8QcZm7.js} +1 -1
  67. package/dist/web/assets/{OutputsPage-Bmof4Tdv.js → OutputsPage-Y9HM-SHX.js} +1 -1
  68. package/dist/web/assets/{ProjectsPage-D7opg6ff.js → ProjectsPage-BBr58yKT.js} +1 -1
  69. package/dist/web/assets/{RightChatPanelStack-BzsNeSwx.js → RightChatPanelStack-DzUbDKwp.js} +1 -1
  70. package/dist/web/assets/{RightSidebarHomePanel-D8dAMHcp.js → RightSidebarHomePanel-Dx-1elSI.js} +1 -1
  71. package/dist/web/assets/{ScheduledWorkPage-Dkjhof6t.js → ScheduledWorkPage-BuXw_W8b.js} +1 -1
  72. package/dist/web/assets/SettingsView-DB_zPHYY.js +6 -0
  73. package/dist/web/assets/{TeamChatView-DIxvrgai.js → TeamChatView-Bkyhu40R.js} +1 -1
  74. package/dist/web/assets/{TerminalOverlay-Cd0Sp9LD.js → TerminalOverlay-CaCkZDzO.js} +1 -1
  75. package/dist/web/assets/{TrainingCreationPanel-DACYaOny.js → TrainingCreationPanel-Vvi41WNT.js} +1 -1
  76. package/dist/web/assets/{TrainingDraftPanel-DBWJW8ZD.js → TrainingDraftPanel-C2C3hffI.js} +1 -1
  77. package/dist/web/assets/{UsageSettingsSection-B3sbqaUV.js → UsageSettingsSection-DpPBd-ra.js} +1 -1
  78. package/dist/web/assets/{WorkSidebarPanel-D4yXQ64j.js → WorkSidebarPanel-CeWGboTh.js} +1 -1
  79. package/dist/web/assets/{WorkspaceDiffPanel-CBgPVF1P.js → WorkspaceDiffPanel-D_zKOW4K.js} +3 -3
  80. package/dist/web/assets/{WorkspaceEnvironmentMenu-Bp-9V7Jq.js → WorkspaceEnvironmentMenu-BTz9FISP.js} +3 -3
  81. package/dist/web/assets/{WorkspaceGitDialogs-BxU5Uhpz.js → WorkspaceGitDialogs-BnBRUYpS.js} +1 -1
  82. package/dist/web/assets/{WorkspaceMonacoEditor-Db_sWYFt.js → WorkspaceMonacoEditor--GOVrHFp.js} +3 -3
  83. package/dist/web/assets/{activity-BzKyRXbd.js → activity-DA5DNQwD.js} +1 -1
  84. package/dist/web/assets/{arrow-up-right-DaIxkG4K.js → arrow-up-right-BRZWXpqJ.js} +1 -1
  85. package/dist/web/assets/{chat-file-links-wORSEipQ.js → chat-file-links-CgFHK89C.js} +1 -1
  86. package/dist/web/assets/chevron-up-DSv2auz_.js +1 -0
  87. package/dist/web/assets/{clipboard-BTRsPPaK.js → clipboard-dPd_3lpG.js} +1 -1
  88. package/dist/web/assets/{cloud-upload-BYXHJoKd.js → cloud-upload-DOwvN4hp.js} +1 -1
  89. package/dist/web/assets/{cssMode-Be446Wgi.js → cssMode-BM4j9M0D.js} +1 -1
  90. package/dist/web/assets/{folder-open-KtKTXn4w.js → folder-open-DavjPCw4.js} +1 -1
  91. package/dist/web/assets/{folder-plus-9-Xcli22.js → folder-plus-Dyqast6G.js} +1 -1
  92. package/dist/web/assets/{git-branch-CLGxzDjJ.js → git-branch-zKnZdQiX.js} +1 -1
  93. package/dist/web/assets/{git-commit-horizontal-CmVYsUnh.js → git-commit-horizontal-s3X0cQlz.js} +1 -1
  94. package/dist/web/assets/{htmlMode-DTjTyBB_.js → htmlMode-Nlx7ckXa.js} +1 -1
  95. package/dist/web/assets/{index-DqWw2ymf.js → index-5-B6FIuE.js} +1 -1
  96. package/dist/web/assets/index-CQ3CPVHZ.css +1 -0
  97. package/dist/web/assets/index-CuoGlf-W.js +1 -0
  98. package/dist/web/assets/{info-BLmP4K0e.js → info-CVvrNOHr.js} +1 -1
  99. package/dist/web/assets/{jsonMode-Z-2iim-u.js → jsonMode-B7monA6g.js} +1 -1
  100. package/dist/web/assets/{lspLanguageFeatures-Cr2iCfG2.js → lspLanguageFeatures-CcJ9GDtK.js} +1 -1
  101. package/dist/web/assets/{minimize-2-CWA6iO3r.js → minimize-2-O1DnznGK.js} +1 -1
  102. package/dist/web/assets/{monaco.contribution-YhqlKmCp.js → monaco.contribution-2PozfA9g.js} +2 -2
  103. package/dist/web/assets/{monaco.contribution-BtMcDmCM.js → monaco.contribution-BMAF2bmO.js} +2 -2
  104. package/dist/web/assets/{monaco.contribution-Cac9eBUk.js → monaco.contribution-BSJ2jQTi.js} +2 -2
  105. package/dist/web/assets/{monaco.contribution-NtjNqMdv.js → monaco.contribution-QOOCizYq.js} +2 -2
  106. package/dist/web/assets/{play-DYSQH2rx.js → play-BpCc5ZbR.js} +1 -1
  107. package/dist/web/assets/{python-CNqOWXNv.js → python-BK41iew-.js} +1 -1
  108. package/dist/web/assets/{refresh-cw-DMysDKOA.js → refresh-cw-Csoy1ev1.js} +1 -1
  109. package/dist/web/assets/{save-HPZ4ZiDi.js → save-Dbztj0W7.js} +1 -1
  110. package/dist/web/assets/{square-D-mpY1a-.js → square-ju7fWa0W.js} +1 -1
  111. package/dist/web/assets/{toggleHighContrast-Bccdn3Qi.js → toggleHighContrast-DrmwDpyz.js} +1 -1
  112. package/dist/web/assets/{tsMode-BhcKJxhG.js → tsMode-CFgCMr7d.js} +1 -1
  113. package/dist/web/assets/{upload-DE7xaWVj.js → upload-C5nhiSMq.js} +1 -1
  114. package/dist/web/assets/{useLocalAgentSchedules-C0J--_MD.js → useLocalAgentSchedules-LAsobERb.js} +1 -1
  115. package/dist/web/assets/{wifi-off-CrCfhll9.js → wifi-off-BHxh2UbA.js} +1 -1
  116. package/dist/web/assets/{workers-DCaGzukk.js → workers-FKb-NyBI.js} +1 -1
  117. package/dist/web/assets/{yaml-CCfH63KB.js → yaml-C5DbF9S6.js} +1 -1
  118. package/dist/web/index.html +2 -2
  119. package/package.json +1 -1
  120. package/dist/api/vercel-protection.d.ts +0 -1
  121. package/dist/chunks/chunk-MLWNI3WG.js +0 -15395
  122. package/dist/web/assets/App-D7vhbyMO.js +0 -171
  123. package/dist/web/assets/LabModelVersionDetailPage-D2PfI3-r.js +0 -1
  124. package/dist/web/assets/LabsRoute-VOgPrf94.js +0 -2
  125. package/dist/web/assets/SettingsView-CWTAUy2b.js +0 -6
  126. package/dist/web/assets/chevron-up-C8-qSzck.js +0 -1
  127. package/dist/web/assets/index-AzqEDIEY.css +0 -1
  128. package/dist/web/assets/index-C5uP_Gug.js +0 -1
@@ -0,0 +1,648 @@
1
+ import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
+ import {
3
+ external_exports
4
+ } from "./chunk-FQS2QL5F.js";
5
+
6
+ // ../../packages/sdk/dist/actions-local.js
7
+ import { randomUUID } from "node:crypto";
8
+ import { spawn } from "node:child_process";
9
+ import { promises as fs5 } from "node:fs";
10
+ import path5 from "node:path";
11
+ import { promises as fs4 } from "node:fs";
12
+ import path4 from "node:path";
13
+ import { fileURLToPath, pathToFileURL } from "node:url";
14
+ import { build } from "esbuild";
15
+ import { promises as fs } from "node:fs";
16
+ import path from "node:path";
17
+ import { promises as fs2 } from "node:fs";
18
+ import path2 from "node:path";
19
+ import { createHash } from "node:crypto";
20
+ import { promises as fs3 } from "node:fs";
21
+ import { createRequire } from "node:module";
22
+ import path3 from "node:path";
23
+ function isProjectActionDefinition(value) {
24
+ return Boolean(
25
+ value && typeof value === "object" && value.kind === "openpond-project-action" && typeof value.id === "string" && typeof value.run === "function"
26
+ );
27
+ }
28
+ function projectActionJsonSchema(schema) {
29
+ return external_exports.toJSONSchema(schema, { unrepresentable: "any" });
30
+ }
31
+ function collectProjectActions(modules) {
32
+ const actions = [];
33
+ const seenObjects = /* @__PURE__ */ new Set();
34
+ const visit = (value) => {
35
+ if (seenObjects.has(value)) return;
36
+ if (value && (typeof value === "object" || typeof value === "function")) seenObjects.add(value);
37
+ if (isProjectActionDefinition(value)) {
38
+ actions.push(value);
39
+ return;
40
+ }
41
+ if (Array.isArray(value)) {
42
+ value.forEach(visit);
43
+ return;
44
+ }
45
+ if (value && typeof value === "object") Object.values(value).forEach(visit);
46
+ };
47
+ modules.forEach(visit);
48
+ const byId = /* @__PURE__ */ new Map();
49
+ for (const action of actions) {
50
+ if (byId.has(action.id)) throw new Error(`Duplicate Project Action id: ${action.id}`);
51
+ byId.set(action.id, action);
52
+ }
53
+ return [...byId.values()].sort((left, right) => left.id.localeCompare(right.id));
54
+ }
55
+ function createProjectActionRegistry(actions) {
56
+ return {
57
+ schemaVersion: "openpond.projectActionRegistry.v1",
58
+ actions: actions.map(toCatalogEntry)
59
+ };
60
+ }
61
+ function toCatalogEntry(action) {
62
+ return {
63
+ id: action.id,
64
+ sourceActionId: action.id,
65
+ name: action.id,
66
+ label: action.label,
67
+ description: action.description,
68
+ visibility: "default",
69
+ inputSchema: projectActionJsonSchema(action.inputSchema),
70
+ outputSchema: projectActionJsonSchema(action.outputSchema),
71
+ approvalPolicy: {
72
+ ...action.approval,
73
+ required: action.approval.mode === "always" || action.approval.mode === "sensitive" || action.approval.mode === "writes" && action.behavior === "write",
74
+ risk: action.behavior
75
+ },
76
+ artifactPolicy: {
77
+ outputArtifacts: [],
78
+ persistRunSummary: true,
79
+ persistTrace: true
80
+ },
81
+ setupRequirements: [...action.setup],
82
+ mcp: { enabled: false },
83
+ schedulePolicy: { enabled: false, allowAdHoc: true },
84
+ trace: { name: action.id, namespace: "project-actions" },
85
+ implementation: {
86
+ type: "openpond-project-action",
87
+ actionId: action.id,
88
+ behavior: action.behavior,
89
+ timeoutMs: action.timeoutMs,
90
+ concurrency: action.concurrency
91
+ },
92
+ invokesModel: action.invokesModel
93
+ };
94
+ }
95
+ var PROJECT_ACTION_CONFIG_PATH = "openpond/project-actions.json";
96
+ var connectionSchema = external_exports.object({
97
+ values: external_exports.record(external_exports.string(), external_exports.unknown()).optional().default({}),
98
+ environment: external_exports.record(external_exports.string(), external_exports.string().trim().min(1)).optional().default({})
99
+ }).strict();
100
+ var configSchema = external_exports.object({
101
+ sourceDirectory: external_exports.string().trim().min(1).optional(),
102
+ outputDirectory: external_exports.string().trim().min(1).optional(),
103
+ environment: external_exports.record(external_exports.string(), external_exports.string().trim().min(1)).optional().default({}),
104
+ connections: external_exports.record(external_exports.string(), connectionSchema).optional().default({})
105
+ }).strict();
106
+ async function loadProjectActionConfiguration(projectRoot) {
107
+ const resolvedRoot = path.resolve(projectRoot);
108
+ const configPath = path.join(resolvedRoot, PROJECT_ACTION_CONFIG_PATH);
109
+ const raw = await fs.readFile(configPath, "utf8").catch((error) => {
110
+ if (error.code === "ENOENT") return null;
111
+ throw error;
112
+ });
113
+ if (raw === null) return configSchema.parse({});
114
+ let value;
115
+ try {
116
+ value = JSON.parse(raw);
117
+ } catch (error) {
118
+ const message = error instanceof Error ? error.message : String(error);
119
+ throw new Error(`${PROJECT_ACTION_CONFIG_PATH} is not valid JSON: ${message}`);
120
+ }
121
+ return configSchema.parse(value);
122
+ }
123
+ function resolveProjectActionRuntime(config, hostEnvironment = process.env) {
124
+ const environment = {};
125
+ for (const [runtimeName, hostName] of Object.entries(config.environment)) {
126
+ const value = hostEnvironment[hostName];
127
+ if (value !== void 0) environment[runtimeName] = value;
128
+ }
129
+ const connections = {};
130
+ for (const [name, descriptor] of Object.entries(config.connections)) {
131
+ const value = { ...descriptor.values };
132
+ for (const [property, hostName] of Object.entries(descriptor.environment)) {
133
+ const environmentValue = hostEnvironment[hostName];
134
+ if (environmentValue !== void 0) value[property] = environmentValue;
135
+ }
136
+ connections[name] = value;
137
+ }
138
+ return { environment, connections };
139
+ }
140
+ var ACTION_FILE = /\.(?:[cm]?[jt]s)$/i;
141
+ var IGNORED_FILE = /(?:\.d\.ts|\.test\.[cm]?[jt]s|\.spec\.[cm]?[jt]s)$/i;
142
+ async function discoverProjectActionFiles(input) {
143
+ const projectRoot = path2.resolve(input.projectRoot);
144
+ const sourceRoot = path2.resolve(projectRoot, input.sourceDirectory ?? "openpond/actions");
145
+ if (!isWithin(projectRoot, sourceRoot)) {
146
+ throw new Error("Project Action source directory must stay inside the Project root.");
147
+ }
148
+ const stats = await fs2.stat(sourceRoot).catch(() => null);
149
+ if (!stats?.isDirectory()) {
150
+ throw new Error(`Project Action source directory does not exist: ${sourceRoot}`);
151
+ }
152
+ const files = await walk(sourceRoot);
153
+ const actions = files.filter((file) => ACTION_FILE.test(file) && !IGNORED_FILE.test(file)).map((file) => path2.relative(projectRoot, file).split(path2.sep).join("/")).sort();
154
+ if (actions.length === 0) {
155
+ throw new Error(`No Project Action files were found under ${sourceRoot}.`);
156
+ }
157
+ return { projectRoot, sourceRoot, files: actions };
158
+ }
159
+ async function walk(directory) {
160
+ const entries = await fs2.readdir(directory, { withFileTypes: true });
161
+ const files = [];
162
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
163
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
164
+ const target = path2.join(directory, entry.name);
165
+ if (entry.isDirectory()) files.push(...await walk(target));
166
+ else if (entry.isFile()) files.push(target);
167
+ }
168
+ return files;
169
+ }
170
+ function isWithin(root, target) {
171
+ const relative = path2.relative(root, target);
172
+ return relative === "" || !relative.startsWith("..") && !path2.isAbsolute(relative);
173
+ }
174
+ function sha256(value) {
175
+ return createHash("sha256").update(value).digest("hex");
176
+ }
177
+ function canonicalJson(value) {
178
+ return `${JSON.stringify(sortValue(value), null, 2)}
179
+ `;
180
+ }
181
+ function sortValue(value) {
182
+ if (Array.isArray(value)) return value.map(sortValue);
183
+ if (!value || typeof value !== "object") return value;
184
+ return Object.fromEntries(
185
+ Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortValue(child)])
186
+ );
187
+ }
188
+ async function validateProjectActionStaticSetup(projectRoot, requirements) {
189
+ for (const requirement of requirements) {
190
+ if (requirement.required === false) continue;
191
+ if (requirement.kind === "package") {
192
+ try {
193
+ createRequire(path3.join(projectRoot, "package.json")).resolve(requirement.name);
194
+ } catch {
195
+ throw new Error(`Project Action package is not installed: ${requirement.name}`);
196
+ }
197
+ }
198
+ if (requirement.kind === "native_tool" && !await executableExists(requirement.name)) {
199
+ throw new Error(`Project Action native tool is not installed: ${requirement.name}`);
200
+ }
201
+ }
202
+ }
203
+ async function validateProjectActionRunSetup(projectRoot, requirements, request) {
204
+ await validateProjectActionStaticSetup(projectRoot, requirements);
205
+ for (const requirement of requirements) {
206
+ if (requirement.required === false) continue;
207
+ if (requirement.kind === "connection" && !(requirement.name in (request.connections ?? {}))) {
208
+ throw new Error(`Project Action connection is not configured: ${requirement.name}`);
209
+ }
210
+ if (requirement.kind === "env" && !(requirement.name in (request.environment ?? {}))) {
211
+ throw new Error(`Project Action environment value is not configured: ${requirement.name}`);
212
+ }
213
+ }
214
+ }
215
+ async function executableExists(name) {
216
+ if (!name.trim() || name.includes("/") || name.includes("\\")) return false;
217
+ for (const directory of (process.env.PATH ?? "").split(path3.delimiter).filter(Boolean)) {
218
+ const candidates = process.platform === "win32" ? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT;.COM").split(";").map((extension) => path3.join(directory, `${name}${extension}`)) : [path3.join(directory, name)];
219
+ for (const candidate of candidates) {
220
+ if (await fs3.access(candidate).then(() => true).catch(() => false)) return true;
221
+ }
222
+ }
223
+ return false;
224
+ }
225
+ var DEFAULT_PROJECT_ACTION_OUTPUT_DIRECTORY = ".openpond/actions";
226
+ async function buildProjectActions(input) {
227
+ const configuration = await loadProjectActionConfiguration(input.projectRoot);
228
+ const discovered = await discoverProjectActionFiles({
229
+ projectRoot: input.projectRoot,
230
+ sourceDirectory: input.sourceDirectory ?? configuration.sourceDirectory
231
+ });
232
+ const outputDirectory = path4.resolve(
233
+ discovered.projectRoot,
234
+ input.outputDirectory ?? configuration.outputDirectory ?? DEFAULT_PROJECT_ACTION_OUTPUT_DIRECTORY
235
+ );
236
+ assertWithinProject(discovered.projectRoot, outputDirectory);
237
+ await fs4.mkdir(outputDirectory, { recursive: true });
238
+ const entryPath = path4.join(outputDirectory, "entry.mjs");
239
+ const bundlePath = path4.join(outputDirectory, "bundle.mjs");
240
+ const runnerPath = path4.join(outputDirectory, "runner.mjs");
241
+ const registryPath = path4.join(outputDirectory, "action-registry.json");
242
+ const manifestPath = path4.join(outputDirectory, "build-manifest.json");
243
+ const imports = discovered.files.map((file, index) => {
244
+ const relative = path4.relative(outputDirectory, path4.join(discovered.projectRoot, file)).split(path4.sep).join("/");
245
+ const specifier = relative.startsWith(".") ? relative : `./${relative}`;
246
+ return `import * as actionModule${index} from ${JSON.stringify(specifier)};`;
247
+ });
248
+ const modules = discovered.files.map((_file, index) => `actionModule${index}`).join(", ");
249
+ await fs4.writeFile(
250
+ entryPath,
251
+ [
252
+ ...imports,
253
+ `export const projectActionModules = [${modules}];`,
254
+ "export default projectActionModules;",
255
+ ""
256
+ ].join("\n"),
257
+ "utf8"
258
+ );
259
+ await build({
260
+ entryPoints: [entryPath],
261
+ outfile: bundlePath,
262
+ bundle: true,
263
+ platform: "node",
264
+ format: "esm",
265
+ target: "node22.14",
266
+ sourcemap: false,
267
+ legalComments: "none",
268
+ logLevel: "silent",
269
+ nodePaths: dependencySearchPaths(discovered.projectRoot)
270
+ });
271
+ const cacheKey = `openpond_action_build=${Date.now()}_${Math.random().toString(16).slice(2)}`;
272
+ const loaded = await import(`${pathToFileURL(bundlePath).href}?${cacheKey}`);
273
+ const actions = collectProjectActions(loaded.projectActionModules ?? loaded.default ?? []);
274
+ for (const action of actions) {
275
+ await validateProjectActionStaticSetup(discovered.projectRoot, action.setup);
276
+ }
277
+ const registry = createProjectActionRegistry(actions);
278
+ await fs4.writeFile(registryPath, canonicalJson(registry), "utf8");
279
+ await fs4.writeFile(runnerPath, runtimeSource(), { encoding: "utf8", mode: 493 });
280
+ const bundleHash = sha256(await fs4.readFile(bundlePath));
281
+ const registryHash = sha256(canonicalJson(registry));
282
+ const manifest = {
283
+ schemaVersion: "openpond.projectActionBuild.v1",
284
+ sourceDirectory: path4.relative(discovered.projectRoot, discovered.sourceRoot).split(path4.sep).join("/"),
285
+ sourceFiles: discovered.files,
286
+ bundleFile: path4.basename(bundlePath),
287
+ runnerFile: path4.basename(runnerPath),
288
+ registryFile: path4.basename(registryPath),
289
+ bundleHash,
290
+ registryHash
291
+ };
292
+ await fs4.writeFile(manifestPath, canonicalJson(manifest), "utf8");
293
+ await fs4.rm(entryPath, { force: true });
294
+ return {
295
+ projectRoot: discovered.projectRoot,
296
+ outputDirectory,
297
+ bundlePath,
298
+ runnerPath,
299
+ registryPath,
300
+ manifestPath,
301
+ registry,
302
+ manifest
303
+ };
304
+ }
305
+ function dependencySearchPaths(projectRoot) {
306
+ const candidates = [];
307
+ let current = projectRoot;
308
+ while (true) {
309
+ candidates.push(path4.join(current, "node_modules"));
310
+ const parent = path4.dirname(current);
311
+ if (parent === current) break;
312
+ current = parent;
313
+ }
314
+ candidates.push(path4.resolve(path4.dirname(fileURLToPath(import.meta.url)), "../../../node_modules"));
315
+ return [...new Set(candidates)];
316
+ }
317
+ function assertWithinProject(projectRoot, target) {
318
+ const relative = path4.relative(projectRoot, target);
319
+ if (relative.startsWith("..") || path4.isAbsolute(relative)) {
320
+ throw new Error("Project Action output directory must stay inside the Project root.");
321
+ }
322
+ }
323
+ function runtimeSource() {
324
+ return `#!/usr/bin/env node
325
+ import { promises as fs } from "node:fs";
326
+ import { stdin } from "node:process";
327
+ import path from "node:path";
328
+ import { fileURLToPath, pathToFileURL } from "node:url";
329
+
330
+ let requestText = "";
331
+ stdin.setEncoding("utf8");
332
+ for await (const chunk of stdin) requestText += chunk;
333
+ const request = JSON.parse(requestText);
334
+ const bundlePath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "bundle.mjs");
335
+ const loaded = await import(pathToFileURL(bundlePath).href);
336
+ const values = [];
337
+ const seen = new Set();
338
+ const visit = (value) => {
339
+ if (seen.has(value)) return;
340
+ if (value && (typeof value === "object" || typeof value === "function")) seen.add(value);
341
+ if (value?.kind === "openpond-project-action" && typeof value.run === "function") { values.push(value); return; }
342
+ if (Array.isArray(value)) { value.forEach(visit); return; }
343
+ if (value && typeof value === "object") Object.values(value).forEach(visit);
344
+ };
345
+ (loaded.projectActionModules ?? loaded.default ?? []).forEach(visit);
346
+ const action = values.find((candidate) => candidate.id === request.actionId);
347
+ if (!action) throw new Error(\`Unknown Project Action: \${request.actionId}\`);
348
+ const controller = new AbortController();
349
+ const timeoutMs = Math.min(request.timeoutMs ?? action.timeoutMs, action.timeoutMs);
350
+ const timer = setTimeout(() => controller.abort(new Error(\`Project Action timed out after \${timeoutMs}ms.\`)), timeoutMs);
351
+ const traces = [];
352
+ const outputs = [];
353
+ const env = request.environment ?? {};
354
+ const connections = request.connections ?? {};
355
+ const context = {
356
+ runId: request.runId,
357
+ actionId: action.id,
358
+ idempotencyKey: request.idempotencyKey ?? null,
359
+ projectRoot: request.projectRoot,
360
+ outputDirectory: request.outputDirectory,
361
+ signal: controller.signal,
362
+ env(name) { return Object.prototype.hasOwnProperty.call(env, name) ? env[name] : undefined; },
363
+ connection(name) {
364
+ if (!Object.prototype.hasOwnProperty.call(connections, name)) throw new Error(\`Project Action connection is not configured: \${name}\`);
365
+ return connections[name];
366
+ },
367
+ trace(name, payload) { traces.push({ name, ...(payload ? { payload } : {}), timestamp: new Date().toISOString() }); },
368
+ output(value) {
369
+ if (!value || typeof value.path !== "string" || !value.path.trim()) throw new Error("Project Action output requires a path.");
370
+ const outputPath = path.resolve(request.outputDirectory, value.path);
371
+ const relative = path.relative(request.outputDirectory, outputPath);
372
+ if (relative.startsWith("..") || path.isAbsolute(relative)) throw new Error("Project Action output must stay inside the run output directory.");
373
+ outputs.push({ ...value, path: relative.split(path.sep).join("/") });
374
+ },
375
+ };
376
+ try {
377
+ const input = action.inputSchema.parse(request.input ?? {});
378
+ const result = await Promise.race([
379
+ Promise.resolve(action.run(context, input)),
380
+ new Promise((_, reject) => controller.signal.addEventListener("abort", () => reject(controller.signal.reason), { once: true })),
381
+ ]);
382
+ const output = action.outputSchema.parse(result);
383
+ for (const artifact of outputs) {
384
+ const stats = await fs.stat(path.resolve(request.outputDirectory, artifact.path)).catch(() => null);
385
+ if (!stats?.isFile()) throw new Error(\`Project Action output does not exist: \${artifact.path}\`);
386
+ }
387
+ await fs.writeFile(request.responseFile, JSON.stringify({ ok: true, output, traces, outputs }), "utf8");
388
+ } finally {
389
+ clearTimeout(timer);
390
+ }
391
+ `;
392
+ }
393
+ var localConcurrency = /* @__PURE__ */ new Map();
394
+ function createLocalActionRunner(options) {
395
+ const projectRoot = path5.resolve(options.projectRoot);
396
+ const buildPolicy = options.build ?? "if-missing";
397
+ let currentBuild = null;
398
+ const ensureBuild = async () => {
399
+ if (buildPolicy === "always") return runBuild();
400
+ if (currentBuild) return currentBuild;
401
+ if (buildPolicy === "never" || buildPolicy === "if-missing") {
402
+ const configuration = await loadProjectActionConfiguration(projectRoot);
403
+ const outputDirectory = path5.resolve(
404
+ projectRoot,
405
+ options.outputDirectory ?? configuration.outputDirectory ?? DEFAULT_PROJECT_ACTION_OUTPUT_DIRECTORY
406
+ );
407
+ const loaded = await loadBuild(projectRoot, outputDirectory);
408
+ if (loaded) return currentBuild = loaded;
409
+ if (buildPolicy === "never") {
410
+ throw new Error(`Project Actions have not been built in ${outputDirectory}.`);
411
+ }
412
+ }
413
+ return runBuild();
414
+ };
415
+ const runBuild = async () => {
416
+ currentBuild = await buildProjectActions({
417
+ projectRoot,
418
+ sourceDirectory: options.sourceDirectory,
419
+ outputDirectory: options.outputDirectory
420
+ });
421
+ return currentBuild;
422
+ };
423
+ return {
424
+ build: runBuild,
425
+ async catalog() {
426
+ return (await ensureBuild()).registry;
427
+ },
428
+ async run(request) {
429
+ const built = await ensureBuild();
430
+ const catalogAction = built.registry.actions.find((action) => action.id === request.actionId);
431
+ if (!catalogAction) throw new Error(`Unknown Project Action: ${request.actionId}`);
432
+ const configuredRuntime = resolveProjectActionRuntime(
433
+ await loadProjectActionConfiguration(projectRoot)
434
+ );
435
+ const resolvedRequest = {
436
+ ...request,
437
+ environment: {
438
+ ...configuredRuntime.environment,
439
+ ...request.environment ?? {}
440
+ },
441
+ connections: {
442
+ ...configuredRuntime.connections,
443
+ ...request.connections ?? {}
444
+ }
445
+ };
446
+ await validateProjectActionRunSetup(projectRoot, catalogAction.setupRequirements, resolvedRequest);
447
+ const runId = request.runId?.trim() || randomUUID();
448
+ const actionOutputDirectory = path5.resolve(
449
+ request.outputDirectory ?? path5.join(projectRoot, ".openpond", "outputs", runId)
450
+ );
451
+ assertWithinProject2(projectRoot, actionOutputDirectory, "Project Action output directory");
452
+ await fs5.mkdir(actionOutputDirectory, { recursive: true });
453
+ const release = await acquireLocalActionSlot(
454
+ `${projectRoot}\0${request.actionId}`,
455
+ catalogAction.implementation.concurrency,
456
+ resolvedRequest.signal
457
+ );
458
+ const responseFile = path5.join(built.outputDirectory, `.run-${randomUUID()}.json`);
459
+ const startedAt = Date.now();
460
+ let childResult;
461
+ let payload;
462
+ try {
463
+ childResult = await executeChild({
464
+ runnerPath: built.runnerPath,
465
+ cwd: projectRoot,
466
+ signal: resolvedRequest.signal,
467
+ request: {
468
+ actionId: request.actionId,
469
+ input: resolvedRequest.input ?? {},
470
+ runId,
471
+ idempotencyKey: resolvedRequest.idempotencyKey ?? null,
472
+ timeoutMs: resolvedRequest.timeoutMs,
473
+ projectRoot,
474
+ outputDirectory: actionOutputDirectory,
475
+ responseFile,
476
+ environment: resolvedRequest.environment ?? {},
477
+ connections: resolvedRequest.connections ?? {}
478
+ }
479
+ });
480
+ payload = JSON.parse(await fs5.readFile(responseFile, "utf8"));
481
+ } catch (error) {
482
+ const message = error instanceof Error ? error.message : String(error);
483
+ throw new Error(redactRuntimeValues(message, resolvedRequest));
484
+ } finally {
485
+ await fs5.rm(responseFile, { force: true }).catch(() => void 0);
486
+ release();
487
+ }
488
+ return {
489
+ runId,
490
+ actionId: request.actionId,
491
+ status: "succeeded",
492
+ output: payload.output,
493
+ stdout: redactRuntimeValues(childResult.stdout, resolvedRequest),
494
+ stderr: redactRuntimeValues(childResult.stderr, resolvedRequest),
495
+ traces: redactRuntimeValue(payload.traces, resolvedRequest),
496
+ outputs: redactRuntimeValue(payload.outputs, resolvedRequest),
497
+ outputDirectory: actionOutputDirectory,
498
+ durationMs: Date.now() - startedAt
499
+ };
500
+ }
501
+ };
502
+ }
503
+ async function acquireLocalActionSlot(key, limit, signal) {
504
+ if (limit === null) return () => void 0;
505
+ const state = localConcurrency.get(key) ?? { active: 0, waiting: [] };
506
+ localConcurrency.set(key, state);
507
+ if (state.active >= limit) {
508
+ await new Promise((resolve, reject) => {
509
+ const resume = () => {
510
+ signal?.removeEventListener("abort", abort);
511
+ resolve();
512
+ };
513
+ const abort = () => {
514
+ const index = state.waiting.indexOf(resume);
515
+ if (index >= 0) state.waiting.splice(index, 1);
516
+ reject(signal?.reason instanceof Error ? signal.reason : new Error("Project Action was cancelled."));
517
+ };
518
+ if (signal?.aborted) {
519
+ abort();
520
+ return;
521
+ }
522
+ state.waiting.push(resume);
523
+ signal?.addEventListener("abort", abort, { once: true });
524
+ });
525
+ } else {
526
+ state.active += 1;
527
+ }
528
+ let released = false;
529
+ return () => {
530
+ if (released) return;
531
+ released = true;
532
+ const next = state.waiting.shift();
533
+ if (next) {
534
+ next();
535
+ return;
536
+ }
537
+ state.active -= 1;
538
+ if (state.active === 0 && state.waiting.length === 0) localConcurrency.delete(key);
539
+ };
540
+ }
541
+ async function loadBuild(projectRoot, outputDirectory) {
542
+ const manifestPath = path5.join(outputDirectory, "build-manifest.json");
543
+ const registryPath = path5.join(outputDirectory, "action-registry.json");
544
+ const [manifestText, registryText] = await Promise.all([
545
+ fs5.readFile(manifestPath, "utf8").catch(() => null),
546
+ fs5.readFile(registryPath, "utf8").catch(() => null)
547
+ ]);
548
+ if (!manifestText || !registryText) return null;
549
+ const manifest = JSON.parse(manifestText);
550
+ const registry = JSON.parse(registryText);
551
+ return {
552
+ projectRoot,
553
+ outputDirectory,
554
+ bundlePath: path5.join(outputDirectory, manifest.bundleFile),
555
+ runnerPath: path5.join(outputDirectory, manifest.runnerFile),
556
+ registryPath,
557
+ manifestPath,
558
+ registry,
559
+ manifest
560
+ };
561
+ }
562
+ function redactRuntimeValues(value, request) {
563
+ let redacted = value;
564
+ for (const secret of runtimeStringValues(request)) {
565
+ if (secret.length >= 4) redacted = redacted.split(secret).join("[REDACTED]");
566
+ }
567
+ return redacted;
568
+ }
569
+ function redactRuntimeValue(value, request) {
570
+ const serialized = JSON.stringify(value);
571
+ return JSON.parse(redactRuntimeValues(serialized, request));
572
+ }
573
+ function runtimeStringValues(request) {
574
+ const values = new Set(Object.values(request.environment ?? {}));
575
+ const visit = (value) => {
576
+ if (typeof value === "string") values.add(value);
577
+ else if (Array.isArray(value)) value.forEach(visit);
578
+ else if (value && typeof value === "object") Object.values(value).forEach(visit);
579
+ };
580
+ visit(request.connections ?? {});
581
+ return [...values].filter(Boolean).sort((left, right) => right.length - left.length);
582
+ }
583
+ function executeChild(input) {
584
+ return new Promise((resolve, reject) => {
585
+ if (input.signal?.aborted) {
586
+ reject(input.signal.reason instanceof Error ? input.signal.reason : new Error("Project Action was cancelled."));
587
+ return;
588
+ }
589
+ let requestJson;
590
+ try {
591
+ requestJson = JSON.stringify(input.request);
592
+ } catch (error) {
593
+ reject(new Error(`Project Action request is not serializable: ${error instanceof Error ? error.message : String(error)}`));
594
+ return;
595
+ }
596
+ const child = spawn(process.execPath, [input.runnerPath], {
597
+ cwd: input.cwd,
598
+ env: minimalEnvironment(),
599
+ stdio: ["pipe", "pipe", "pipe"]
600
+ });
601
+ let stdout = "";
602
+ let stderr = "";
603
+ child.stdout.setEncoding("utf8");
604
+ child.stderr.setEncoding("utf8");
605
+ child.stdout.on("data", (chunk) => {
606
+ stdout += chunk;
607
+ });
608
+ child.stderr.on("data", (chunk) => {
609
+ stderr += chunk;
610
+ });
611
+ const abort = () => child.kill("SIGTERM");
612
+ input.signal?.addEventListener("abort", abort, { once: true });
613
+ child.once("error", reject);
614
+ child.once("close", (code, signal) => {
615
+ input.signal?.removeEventListener("abort", abort);
616
+ if (input.signal?.aborted) {
617
+ reject(input.signal.reason instanceof Error ? input.signal.reason : new Error("Project Action was cancelled."));
618
+ return;
619
+ }
620
+ if (code !== 0) {
621
+ reject(new Error(`Project Action process failed (${code ?? signal ?? "unknown"}): ${stderr.trim() || stdout.trim()}`));
622
+ return;
623
+ }
624
+ resolve({ stdout, stderr });
625
+ });
626
+ child.stdin.end(requestJson);
627
+ });
628
+ }
629
+ function assertWithinProject2(projectRoot, target, label) {
630
+ const relative = path5.relative(projectRoot, target);
631
+ if (relative.startsWith("..") || path5.isAbsolute(relative)) {
632
+ throw new Error(`${label} must stay inside the Project root.`);
633
+ }
634
+ }
635
+ function minimalEnvironment() {
636
+ const env = {};
637
+ for (const name of ["PATH", "SystemRoot", "WINDIR", "TMPDIR", "TEMP", "TMP"]) {
638
+ if (process.env[name] !== void 0) env[name] = process.env[name];
639
+ }
640
+ return env;
641
+ }
642
+
643
+ export {
644
+ PROJECT_ACTION_CONFIG_PATH,
645
+ loadProjectActionConfiguration,
646
+ buildProjectActions,
647
+ createLocalActionRunner
648
+ };
@@ -4,7 +4,7 @@ import {
4
4
  parseSandboxRuntimeProfileIdOption,
5
5
  parseSandboxRuntimePromotionPolicyOption,
6
6
  parseSandboxWorkflowModeOption
7
- } from "./chunk-J2REM7LE.js";
7
+ } from "./chunk-HFPUR4CQ.js";
8
8
  import {
9
9
  parseBooleanOption,
10
10
  parseCsvOption,
@@ -15,7 +15,7 @@ import {
15
15
  resolveRepoUrl,
16
16
  runCommand,
17
17
  warnOnRepoHostMismatch
18
- } from "./chunk-J2REM7LE.js";
18
+ } from "./chunk-HFPUR4CQ.js";
19
19
  import {
20
20
  normalizeTemplateRepoUrl,
21
21
  resolveApiBaseUrlOption,
@@ -28,7 +28,7 @@ import {
28
28
  compareSemver,
29
29
  fetchLatestNpmVersion,
30
30
  getInstalledCliVersion
31
- } from "./chunk-NA4L2HQM.js";
31
+ } from "./chunk-Y57RTLVV.js";
32
32
  import {
33
33
  checkOpenPondApiHealth,
34
34
  createHeadlessApps,
@@ -45,7 +45,7 @@ import {
45
45
  saveProfileApiKey,
46
46
  setActiveProfile,
47
47
  submitBacktestRun
48
- } from "./chunk-DBHSOTYZ.js";
48
+ } from "./chunk-D7BO5Y5J.js";
49
49
  import {
50
50
  parseBooleanOption,
51
51
  parseJsonOption,