@keystrokehq/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/AGENTS-blurb.md +123 -0
  2. package/LICENSE +42 -0
  3. package/README.md +177 -0
  4. package/THIRD_PARTY_NOTICES.md +16 -0
  5. package/bin/keystroke.mjs +107 -0
  6. package/dist/_manifest-JSRE3H8k.mjs +385 -0
  7. package/dist/agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs +2344 -0
  8. package/dist/agent-manifest-CDnbkR2f.mjs +245 -0
  9. package/dist/agents-CZJGxVqV.mjs +228 -0
  10. package/dist/api-keys-D2lgguuY.mjs +40 -0
  11. package/dist/auth-DN2VusyU.mjs +59 -0
  12. package/dist/auth.handler-CT1BQUvu.mjs +340 -0
  13. package/dist/browser-qwFrUH82.mjs +24 -0
  14. package/dist/build-agents-BmM_AsSd-BGi9wtzt.mjs +514 -0
  15. package/dist/build-metadata-BWS7uhd_-DR8gJjTX.mjs +1422 -0
  16. package/dist/build-progress-DgYKb4hB.mjs +183 -0
  17. package/dist/build-tasks-CdihpudT-D5r5HUHe.mjs +91 -0
  18. package/dist/build-workflows-CfxBnIWh-CdYPv8w2.mjs +370 -0
  19. package/dist/build.handler-4799CjWH.mjs +36 -0
  20. package/dist/chunk-CH6r78ws.mjs +37 -0
  21. package/dist/clear-cache.handler-B9tqSoSM.mjs +11 -0
  22. package/dist/clear.handler-BTIXXPTJ.mjs +42 -0
  23. package/dist/clear.handler-BydlX-zE.mjs +11 -0
  24. package/dist/commander-DfTVqQ-3.mjs +133 -0
  25. package/dist/concurrency-gXn9Rw8x-DNl2YtrS.mjs +20 -0
  26. package/dist/connect-BUXkeH0F.mjs +43 -0
  27. package/dist/connect.handler-CYel9cy6.mjs +430 -0
  28. package/dist/constants-CPpPdSNg.mjs +8 -0
  29. package/dist/context-T7HZuB97.mjs +138 -0
  30. package/dist/credential-env-map-CI8yWHVy.mjs +28 -0
  31. package/dist/credential-schema-mismatch-BKo5PjcQ.mjs +76 -0
  32. package/dist/credentials-CvmjU0lK.mjs +171 -0
  33. package/dist/credentials-OfVHOtG3.mjs +151216 -0
  34. package/dist/current-deployment-workflow-poHt27i3.mjs +94 -0
  35. package/dist/current.handler-B8zKzfPp.mjs +21 -0
  36. package/dist/delete.handler-bAu1iXVQ.mjs +17 -0
  37. package/dist/deploy-7Jjls436.mjs +26 -0
  38. package/dist/deploy-BOPIpRWm.mjs +74 -0
  39. package/dist/deploy-progress-BmGUNFKg.mjs +70 -0
  40. package/dist/deploy.handler-BAzgiNhd.mjs +370 -0
  41. package/dist/detect-env-access-CwkOYeYM-D_BCZqV6.mjs +209 -0
  42. package/dist/diff-utils-NEfcjqxt.mjs +185 -0
  43. package/dist/diff.handler-Du7SY8K4.mjs +47 -0
  44. package/dist/dist-BkJUoBiG.mjs +1116 -0
  45. package/dist/dist-CUK7yBM0.mjs +308 -0
  46. package/dist/env-91KwMKov.mjs +140 -0
  47. package/dist/env.handler-BAzBuMzQ.mjs +277 -0
  48. package/dist/error-boundary-VL-JLfIa.mjs +34 -0
  49. package/dist/file-metadata-D1vm-XY2.mjs +191 -0
  50. package/dist/get-intrinsic-zLxwtrLK.mjs +658 -0
  51. package/dist/import-module-CV84H5fZ-B_CBCmb4.mjs +1747 -0
  52. package/dist/init-DpMCotSK.mjs +45 -0
  53. package/dist/init.handler-CPRnif52.mjs +585 -0
  54. package/dist/inspect.handler-DT_cD036.mjs +146 -0
  55. package/dist/integration-catalog-Bt-L3GjF.mjs +104 -0
  56. package/dist/integrations-DlatPK4W.mjs +79 -0
  57. package/dist/keystroke.d.mts +3 -0
  58. package/dist/keystroke.mjs +707 -0
  59. package/dist/layout-CbMtQ2tm.mjs +67 -0
  60. package/dist/list-enrichment-y-cwizLr.mjs +189 -0
  61. package/dist/list.handler-BTWvCyjA.mjs +52 -0
  62. package/dist/list.handler-CWF_Dj15.mjs +24 -0
  63. package/dist/list.handler-CZ6G2x_G.mjs +75 -0
  64. package/dist/list.handler-DWaQkJaR.mjs +51 -0
  65. package/dist/list.handler-DqbFcBW7.mjs +180 -0
  66. package/dist/list.handler-lq3ZGAn4.mjs +104 -0
  67. package/dist/logs-BEg9L5l8.mjs +28 -0
  68. package/dist/logs.handler-6hoMBzqw.mjs +35 -0
  69. package/dist/logs.handler-BD_dXiL1.mjs +231 -0
  70. package/dist/metadata-layout-GUYIUo0i-_aG2zjue.mjs +5877 -0
  71. package/dist/normalize-path-CojS-CgQ-DLCOvnD1.mjs +20 -0
  72. package/dist/options-CeaTcFxP.mjs +43 -0
  73. package/dist/org-xLzBtt2_.mjs +41 -0
  74. package/dist/output-DM4b7KgY.mjs +72 -0
  75. package/dist/oxc-B3KI3rf_-n9d1hKNq.mjs +119 -0
  76. package/dist/paused.handler-BMFm9Cff.mjs +94 -0
  77. package/dist/project-config-D1qsQlO7.mjs +107 -0
  78. package/dist/projects-CHkRE9rS.mjs +1574 -0
  79. package/dist/projects-Cjb7sovS.mjs +30 -0
  80. package/dist/read-credential-keys-77a91T8M-KA0Iw0Z1.mjs +9 -0
  81. package/dist/register.handler-BPCdor1_.mjs +86 -0
  82. package/dist/requirements.handler-DPXdSks3.mjs +201 -0
  83. package/dist/resolve-project-DDJ29sCF.mjs +35 -0
  84. package/dist/rolldown-runtime-twds-ZHy-BWWzu8VG.mjs +15 -0
  85. package/dist/run-polling-CAgFRdK3.mjs +20 -0
  86. package/dist/runs-D9hNLb9A.mjs +259 -0
  87. package/dist/schedule-BXx3uXwr.mjs +1142 -0
  88. package/dist/schema-17qMfNyI.mjs +18 -0
  89. package/dist/schema-display-CgmeKigW.mjs +130 -0
  90. package/dist/schemas-CDib1RhE.mjs +125 -0
  91. package/dist/skills-sync.handler-DIy8GR16.mjs +34 -0
  92. package/dist/skills.command-CrjI2dN9.mjs +35 -0
  93. package/dist/skills.handler-Bz8bJKql.mjs +9 -0
  94. package/dist/source-analysis-Cj-ADyu--BJQcFPCG.mjs +144 -0
  95. package/dist/spinner-progress-DMVwgqO9.mjs +173 -0
  96. package/dist/src-C0X6u_Mw.mjs +1340 -0
  97. package/dist/src-eHwu-Gfw.mjs +369 -0
  98. package/dist/status.handler-BO4nwvWn.mjs +101 -0
  99. package/dist/switch.handler-D_9213Vf.mjs +51 -0
  100. package/dist/sync-BL_Mo5st.mjs +39 -0
  101. package/dist/sync-keystroke-agent-skills-Kx_H7UTd.mjs +70 -0
  102. package/dist/sync.handler-BUFPdzWz.mjs +82 -0
  103. package/dist/task-B2sZMaZu.mjs +8 -0
  104. package/dist/task-target-build-CBeCKbu2.mjs +432 -0
  105. package/dist/task-target-deploy-C5X-USeR.mjs +4 -0
  106. package/dist/task-target-deploy-CA6elFpF-BEr4gkol.mjs +271 -0
  107. package/dist/task-target-deploy-runner.d.mts +3 -0
  108. package/dist/task-target-deploy-runner.mjs +202 -0
  109. package/dist/test-BHTgR3UA.mjs +698 -0
  110. package/dist/test.handler-BcPQ8b74.mjs +13 -0
  111. package/dist/trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs +239 -0
  112. package/dist/trigger-manifest-CY7brZeg.mjs +30 -0
  113. package/dist/try-deploy.handler-DqybNhXx.mjs +490 -0
  114. package/dist/upload-CkU--iDC.mjs +207 -0
  115. package/dist/upload.handler-DCtiznQp.mjs +441 -0
  116. package/dist/utils-CywxCDM7.mjs +14 -0
  117. package/dist/validate.handler-DOcTaJL0.mjs +280 -0
  118. package/dist/workflow-build-DBQaBfnn.mjs +1819 -0
  119. package/dist/workflow-bundler-BPiqVscj-X1PFFAuP.mjs +167 -0
  120. package/dist/workflows-g9z87AJJ.mjs +799 -0
  121. package/dist/writer-BG8poUm3-BbXlU2kI.mjs +426 -0
  122. package/package.json +87 -0
@@ -0,0 +1,1819 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { i as __toESM, n as __exportAll } from "./chunk-CH6r78ws.mjs";
4
+ import { a as originalConsole, h as toErrorMessage, i as logger, o as ANSI, s as style, t as ui } from "./keystroke.mjs";
5
+ import { a as getKeystrokeTmpDir } from "./dist-CUK7yBM0.mjs";
6
+ import { t as assertWorkflowProjectRoot } from "./project-config-D1qsQlO7.mjs";
7
+ import { c as FlowGraphSchema, s as WorkflowManifestSchema } from "./_manifest-JSRE3H8k.mjs";
8
+ import { t as AgentVersionManifestSchema } from "./agent-manifest-CDnbkR2f.mjs";
9
+ import { r as RelativeFilePathSchema } from "./file-metadata-D1vm-XY2.mjs";
10
+ import { c as createArtifactOutputFiles, l as createMetadataOutputFile, o as METADATA_ROOT_DIR_NAME, p as getWorkflowArtifactPaths, t as BUILD_DIR_NAME } from "./layout-CbMtQ2tm.mjs";
11
+ import { t as resolveConfiguredBuildOutputDir } from "./utils-CywxCDM7.mjs";
12
+ import { a as readAgentSandboxPackage, r as AGENT_VM_TOOLS_RUNTIME_RELATIVE_PATH } from "./agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs";
13
+ import { a as prewarmFileContentCache, c as typedEntries, i as createFileContentCache, l as require_out, n as computeBuilderFingerprint, o as resetFileContentCache, r as computeWorkflowFingerprint, s as sha256String } from "./metadata-layout-GUYIUo0i-_aG2zjue.mjs";
14
+ import { a as getAgentArtifactPaths, c as hashWorkflowManifestForDisk, d as resolveOutputDir, i as createAgentOutputFiles, l as removeAgentArtifacts, n as BUILD_CACHE_FILE_NAME, o as hashAgentManifestForDisk, r as allOutputFilesExist, s as hashWorkflowFlowForDisk, t as AGENT_ARTIFACT_DIR_PREFIX, u as removeWorkflowArtifacts } from "./writer-BG8poUm3-BbXlU2kI.mjs";
15
+ import { a as createDiscoveryFailure, c as createNamespaceStarExportDiscoveryError, d as isWorkflowLoadResult, f as loadWorkflowMetadataBatch, i as createAmbiguousExportDiscoveryError, l as isAgentLoadResult, o as createDuplicateWorkflowIdFailure, t as DuplicateWorkflowIdError, u as isTaskLoadResult } from "./import-module-CV84H5fZ-B_CBCmb4.mjs";
16
+ import { a as literalString, n as identifierName, o as parseSourceFile, r as isNode } from "./oxc-B3KI3rf_-n9d1hKNq.mjs";
17
+ import { a as getLocalModuleSpecifier, c as removeAllMetadataArtifacts, d as resolveDefaultExportAssignment, f as resolveLocalModulePath, i as collectWorkflowImportNames, n as DISCOVERY_IGNORE, o as getVariableDeclarators, r as collectLocalWorkflowBindings, s as isExportedVariableStatement, t as DISCOVERY_GLOB, u as removeMetadataArtifacts } from "./source-analysis-Cj-ADyu--BJQcFPCG.mjs";
18
+ import { n as parseRelativeFilePath } from "./normalize-path-CojS-CgQ-DLCOvnD1.mjs";
19
+ import * as fs from "node:fs/promises";
20
+ import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
21
+ import * as path$1 from "node:path";
22
+ import path from "node:path";
23
+ import { z } from "zod";
24
+ import { fileURLToPath } from "node:url";
25
+ import { createHash } from "node:crypto";
26
+ import "oxc-parser";
27
+ import { performance } from "node:perf_hooks";
28
+ //#region ../../packages/workflow-core/dist/chunks/schema-DnT5yizJ.mjs
29
+ var import_out = /* @__PURE__ */ __toESM(require_out(), 1);
30
+ const MAX_JSON_DEPTH = 20;
31
+ function buildJsonValueSchema(depth) {
32
+ const primitives = z.union([
33
+ z.string(),
34
+ z.number(),
35
+ z.boolean(),
36
+ z.null()
37
+ ]);
38
+ if (depth <= 0) return primitives;
39
+ const nested = buildJsonValueSchema(depth - 1);
40
+ return z.union([
41
+ primitives,
42
+ z.array(nested),
43
+ z.record(z.string(), nested)
44
+ ]);
45
+ }
46
+ const jsonValueSchema = buildJsonValueSchema(MAX_JSON_DEPTH);
47
+ z.record(z.string(), jsonValueSchema);
48
+ z.custom((value) => value instanceof z.ZodType, "Expected a Zod schema");
49
+ z.custom((value) => value instanceof z.ZodObject, "Expected a Zod object schema");
50
+ //#endregion
51
+ //#region ../../packages/workflow-core/dist/flow-graph-toolkit/index.mjs
52
+ function detectAgentInPathCycles(input) {
53
+ const nodes = /* @__PURE__ */ new Map();
54
+ const edges = /* @__PURE__ */ new Map();
55
+ for (const node of [
56
+ ...input.agents,
57
+ ...input.workflows,
58
+ ...input.operations
59
+ ]) {
60
+ nodes.set(node.id, node);
61
+ edges.set(node.id, node.kind === "agent" ? node.tools : node.kind === "workflow" ? node.callees : []);
62
+ }
63
+ const cycles = [];
64
+ const path = [];
65
+ const visited = /* @__PURE__ */ new Set();
66
+ const visit = (id) => {
67
+ const existingIndex = path.indexOf(id);
68
+ if (existingIndex >= 0) {
69
+ const cycleNodes = path.slice(existingIndex).concat(id).flatMap((cycleId) => {
70
+ const node = nodes.get(cycleId);
71
+ return node ? [toCycleNode(node)] : [];
72
+ });
73
+ if (cycleNodes.some((node) => node.kind === "agent")) cycles.push({
74
+ path: cycleNodes,
75
+ description: cycleNodes.map((node) => `${node.kind}:${node.id}`).join(" -> ")
76
+ });
77
+ return;
78
+ }
79
+ if (visited.has(id)) return;
80
+ visited.add(id);
81
+ path.push(id);
82
+ for (const next of edges.get(id) ?? []) visit(next);
83
+ path.pop();
84
+ };
85
+ for (const id of nodes.keys()) visit(id);
86
+ return cycles;
87
+ }
88
+ function toCycleNode(node) {
89
+ return {
90
+ kind: node.kind,
91
+ id: node.id,
92
+ displayName: node.displayName,
93
+ source: node.source
94
+ };
95
+ }
96
+ //#endregion
97
+ //#region ../../packages/workflow-builder/dist/build-9Sd6SkIz.mjs
98
+ const DiscoveredWorkflowSchema = z.object({
99
+ exportFilePath: z.string(),
100
+ resolvedFilePath: z.string(),
101
+ relativePath: z.string(),
102
+ exportName: z.string(),
103
+ isDefaultExport: z.boolean(),
104
+ localExportName: z.string(),
105
+ bindingKey: z.string(),
106
+ exportKind: z.union([
107
+ z.literal("workflow"),
108
+ z.literal("agent"),
109
+ z.literal("task")
110
+ ])
111
+ });
112
+ const ScanCacheEntrySchema = z.object({
113
+ mtimeMs: z.number(),
114
+ size: z.number(),
115
+ hasWorkflow: z.boolean(),
116
+ exportNames: z.array(z.string()),
117
+ discoveryEntries: z.array(DiscoveredWorkflowSchema),
118
+ dependencyPaths: z.array(z.string())
119
+ });
120
+ const WorkflowCacheEntrySchema = z.object({
121
+ bindingKey: z.string(),
122
+ workflowId: z.string(),
123
+ resolvedFilePath: z.string().optional(),
124
+ inputFingerprint: z.string(),
125
+ dependencyPaths: z.array(z.string()),
126
+ manifestHash: z.string(),
127
+ flowGraphHash: z.string(),
128
+ bundleHash: z.string(),
129
+ sourceMapHash: z.string().optional(),
130
+ outputFiles: z.array(z.string()),
131
+ updatedAt: z.string()
132
+ });
133
+ const AgentCacheEntrySchema = z.object({
134
+ bindingKey: z.string(),
135
+ agentId: z.string(),
136
+ resolvedFilePath: z.string().optional(),
137
+ inputFingerprint: z.string(),
138
+ dependencyPaths: z.array(z.string()),
139
+ manifestHash: z.string(),
140
+ bundleHash: z.string(),
141
+ sandboxPackageHash: z.string(),
142
+ sourceMapHash: z.string().optional(),
143
+ outputFiles: z.array(z.string()),
144
+ updatedAt: z.string()
145
+ });
146
+ const FileMetadataCacheEntrySchema = z.object({
147
+ filePath: RelativeFilePathSchema,
148
+ sourceChecksum: z.string().length(64).regex(/^[a-f0-9]{64}$/i),
149
+ metadataHash: z.string().min(1),
150
+ outputFile: z.string().min(1),
151
+ updatedAt: z.iso.datetime(),
152
+ crossReferenceFingerprint: z.string().min(1).optional()
153
+ });
154
+ const BuildCacheSchema = z.object({
155
+ cacheVersion: z.literal(2),
156
+ builderFingerprint: z.string(),
157
+ scanEntries: z.record(z.string(), ScanCacheEntrySchema),
158
+ bindings: z.record(z.string(), WorkflowCacheEntrySchema),
159
+ agentBindings: z.record(z.string(), AgentCacheEntrySchema).default({}),
160
+ metadata: z.record(z.string(), FileMetadataCacheEntrySchema).default({})
161
+ });
162
+ function sha256Buffer(buffer) {
163
+ return createHash("sha256").update(buffer).digest("hex");
164
+ }
165
+ async function readBuildCache(outputDir) {
166
+ const cachePath = path.join(outputDir, BUILD_CACHE_FILE_NAME);
167
+ try {
168
+ const parsed = JSON.parse(await readFile(cachePath, "utf-8"));
169
+ const result = BuildCacheSchema.safeParse(parsed);
170
+ return result.success ? result.data : null;
171
+ } catch {
172
+ return null;
173
+ }
174
+ }
175
+ async function writeBuildCache(outputDir, cache) {
176
+ const cachePath = path.join(outputDir, BUILD_CACHE_FILE_NAME);
177
+ const validatedCache = BuildCacheSchema.parse(cache);
178
+ await mkdir(outputDir, { recursive: true });
179
+ await writeFile(cachePath, `${JSON.stringify(validatedCache, null, 2)}\n`, "utf-8");
180
+ }
181
+ function createEmptyBuildCache(builderFingerprint) {
182
+ return {
183
+ cacheVersion: 2,
184
+ builderFingerprint,
185
+ scanEntries: {},
186
+ bindings: {},
187
+ agentBindings: {},
188
+ metadata: {}
189
+ };
190
+ }
191
+ async function loadCachedArtifact(outputDir, discoveredWorkflow, cachedEntry) {
192
+ if (!await allOutputFilesExist(outputDir, cachedEntry.outputFiles)) return null;
193
+ try {
194
+ const artifactPaths = getWorkflowArtifactPaths(outputDir, cachedEntry.workflowId);
195
+ const [manifestText, flowText, bundleCode, sourceMap] = await Promise.all([
196
+ readFile(artifactPaths.manifestPath, "utf-8"),
197
+ readFile(artifactPaths.flowPath, "utf-8"),
198
+ readFile(artifactPaths.bundlePath, "utf-8"),
199
+ cachedEntry.sourceMapHash ? readFile(artifactPaths.sourceMapPath, "utf-8") : null
200
+ ]);
201
+ if (sha256String(manifestText) !== cachedEntry.manifestHash) return null;
202
+ if (sha256String(flowText) !== cachedEntry.flowGraphHash) return null;
203
+ const manifest = WorkflowManifestSchema.parse(JSON.parse(manifestText));
204
+ const flowGraph = FlowGraphSchema.parse(JSON.parse(flowText));
205
+ if (manifest.id !== cachedEntry.workflowId) return null;
206
+ if (path.basename(artifactPaths.workflowDir) !== manifest.id) return null;
207
+ if (sha256String(bundleCode) !== cachedEntry.bundleHash) return null;
208
+ if (cachedEntry.sourceMapHash && sourceMap && sha256String(sourceMap) !== cachedEntry.sourceMapHash) return null;
209
+ return {
210
+ workflow: {
211
+ ...discoveredWorkflow,
212
+ workflowId: manifest.id
213
+ },
214
+ manifest,
215
+ flowGraph,
216
+ bundle: {
217
+ code: bundleCode,
218
+ sourceMap,
219
+ hash: cachedEntry.bundleHash,
220
+ ...cachedEntry.sourceMapHash ? { sourceMapHash: cachedEntry.sourceMapHash } : {},
221
+ localDependencies: [...cachedEntry.dependencyPaths],
222
+ externalImports: [],
223
+ size: Buffer.byteLength(bundleCode)
224
+ },
225
+ triggers: [],
226
+ timing: {
227
+ importMs: 0,
228
+ manifestMs: 0,
229
+ flowGraphMs: 0,
230
+ bundleMs: 0,
231
+ triggerMs: 0,
232
+ totalMs: 0
233
+ }
234
+ };
235
+ } catch {
236
+ return null;
237
+ }
238
+ }
239
+ async function loadCachedAgentArtifact(outputDir, discoveredWorkflow, cachedEntry) {
240
+ if (!await allOutputFilesExist(outputDir, cachedEntry.outputFiles)) return null;
241
+ try {
242
+ const artifactPaths = getAgentArtifactPaths(outputDir, cachedEntry.agentId);
243
+ const [manifestText, sandboxPackageBuffer] = await Promise.all([readFile(artifactPaths.manifestPath, "utf-8"), readFile(artifactPaths.sandboxPackagePath)]);
244
+ if (sha256String(manifestText) !== cachedEntry.manifestHash) return null;
245
+ const manifest = AgentVersionManifestSchema.parse(JSON.parse(manifestText));
246
+ if (sha256Buffer(sandboxPackageBuffer) !== cachedEntry.sandboxPackageHash) return null;
247
+ const toolsRuntimeFile = (await readAgentSandboxPackage(sandboxPackageBuffer)).find((file) => path.posix.normalize(file.path) === AGENT_VM_TOOLS_RUNTIME_RELATIVE_PATH);
248
+ if (!toolsRuntimeFile) return null;
249
+ const bundleCode = Buffer.isBuffer(toolsRuntimeFile.content) ? toolsRuntimeFile.content.toString("utf-8") : toolsRuntimeFile.content;
250
+ if (sha256String(bundleCode) !== cachedEntry.bundleHash) return null;
251
+ return {
252
+ agent: {
253
+ bindingKey: discoveredWorkflow.bindingKey,
254
+ exportFilePath: discoveredWorkflow.exportFilePath,
255
+ resolvedFilePath: discoveredWorkflow.resolvedFilePath,
256
+ exportName: discoveredWorkflow.exportName,
257
+ localExportName: discoveredWorkflow.localExportName,
258
+ agentId: cachedEntry.agentId,
259
+ agentName: manifest.agentName
260
+ },
261
+ manifest,
262
+ bundle: {
263
+ code: bundleCode,
264
+ sourceMap: null,
265
+ hash: cachedEntry.bundleHash,
266
+ localDependencies: [...cachedEntry.dependencyPaths],
267
+ externalImports: [],
268
+ size: Buffer.byteLength(bundleCode)
269
+ },
270
+ sandboxPackage: {
271
+ buffer: sandboxPackageBuffer,
272
+ size: sandboxPackageBuffer.byteLength,
273
+ hash: cachedEntry.sandboxPackageHash
274
+ },
275
+ timing: {
276
+ importMs: 0,
277
+ manifestMs: 0,
278
+ bundleMs: 0,
279
+ totalMs: 0
280
+ }
281
+ };
282
+ } catch {
283
+ return null;
284
+ }
285
+ }
286
+ function createWorkflowCacheEntries(artifacts, validatedHashes) {
287
+ return Object.fromEntries(artifacts.map((artifact) => {
288
+ const outputFiles = createArtifactOutputFiles(artifact.workflow.workflowId, artifact.bundle.sourceMap !== null || artifact.bundle.sourceMapHash !== void 0 || artifact.bundle.sourceMapPath !== void 0);
289
+ const existing = validatedHashes?.get(artifact.workflow.bindingKey);
290
+ return [artifact.workflow.bindingKey, {
291
+ bindingKey: artifact.workflow.bindingKey,
292
+ workflowId: artifact.workflow.workflowId,
293
+ resolvedFilePath: artifact.workflow.resolvedFilePath,
294
+ inputFingerprint: "",
295
+ dependencyPaths: artifact.bundle.localDependencies.filter((dependencyPath) => path.isAbsolute(dependencyPath) && !dependencyPath.includes("\0")),
296
+ manifestHash: existing?.manifestHash ?? hashWorkflowManifestForDisk(artifact.manifest),
297
+ flowGraphHash: existing?.flowGraphHash ?? hashWorkflowFlowForDisk(artifact.flowGraph),
298
+ bundleHash: existing?.bundleHash ?? artifact.bundle.hash ?? sha256String(artifact.bundle.code),
299
+ sourceMapHash: existing?.sourceMapHash ?? artifact.bundle.sourceMapHash ?? (artifact.bundle.sourceMap ? sha256String(artifact.bundle.sourceMap) : void 0),
300
+ outputFiles,
301
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
302
+ }];
303
+ }));
304
+ }
305
+ function createAgentCacheEntries(artifacts, validatedHashes) {
306
+ return Object.fromEntries(artifacts.map((artifact) => {
307
+ const existing = validatedHashes?.get(artifact.agent.bindingKey);
308
+ return [artifact.agent.bindingKey, {
309
+ bindingKey: artifact.agent.bindingKey,
310
+ agentId: artifact.agent.agentId,
311
+ resolvedFilePath: artifact.agent.resolvedFilePath,
312
+ inputFingerprint: "",
313
+ dependencyPaths: artifact.bundle.localDependencies.filter((dependencyPath) => path.isAbsolute(dependencyPath) && !dependencyPath.includes("\0")),
314
+ manifestHash: existing?.manifestHash ?? hashAgentManifestForDisk(artifact.manifest),
315
+ bundleHash: existing?.bundleHash ?? artifact.bundle.hash ?? sha256String(artifact.bundle.code),
316
+ sandboxPackageHash: existing?.sandboxPackageHash ?? sha256Buffer(artifact.sandboxPackage.buffer),
317
+ outputFiles: createAgentOutputFiles(artifact.agent.agentId),
318
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
319
+ }];
320
+ }));
321
+ }
322
+ async function resolveCachedArtifacts(options) {
323
+ const cachedArtifacts = [];
324
+ const cachedAgentArtifacts = [];
325
+ const workflowsToBuild = [];
326
+ const fingerprintByBinding = /* @__PURE__ */ new Map();
327
+ const validatedHashesByBinding = /* @__PURE__ */ new Map();
328
+ const warnings = [];
329
+ let cacheHits = 0;
330
+ let cacheMisses = 0;
331
+ let cachedWorkflowIndex = 0;
332
+ const cacheResolutionStartedAt = performance.now();
333
+ createFileContentCache();
334
+ await prewarmFileContentCache(collectDependencyPaths(options.scopedDiscoveredWorkflows, options.buildCache));
335
+ for (const discoveredWorkflow of options.scopedDiscoveredWorkflows) {
336
+ if (options.config.force) {
337
+ workflowsToBuild.push(discoveredWorkflow);
338
+ cacheMisses += 1;
339
+ continue;
340
+ }
341
+ if (discoveredWorkflow.exportKind === "agent") {
342
+ const resolved = await resolveCachedAgentArtifact({
343
+ buildCache: options.buildCache,
344
+ discoveredWorkflow,
345
+ outputDir: options.outputDir,
346
+ fingerprintByBinding
347
+ });
348
+ if (!resolved) {
349
+ workflowsToBuild.push(discoveredWorkflow);
350
+ cacheMisses += 1;
351
+ continue;
352
+ }
353
+ cachedAgentArtifacts.push(resolved.artifact);
354
+ cacheHits += 1;
355
+ validatedHashesByBinding.set(discoveredWorkflow.bindingKey, resolved.validatedHashes);
356
+ continue;
357
+ }
358
+ const resolved = await resolveCachedWorkflowArtifact({
359
+ config: options.config,
360
+ buildCache: options.buildCache,
361
+ discoveredWorkflow,
362
+ outputDir: options.outputDir,
363
+ fingerprintByBinding
364
+ });
365
+ if (!resolved) {
366
+ workflowsToBuild.push(discoveredWorkflow);
367
+ cacheMisses += 1;
368
+ continue;
369
+ }
370
+ cachedArtifacts.push(resolved.artifact);
371
+ cacheHits += 1;
372
+ validatedHashesByBinding.set(discoveredWorkflow.bindingKey, resolved.validatedHashes);
373
+ options.emit({
374
+ phase: "workflow-stage",
375
+ stage: "cached",
376
+ workflow: resolved.artifact.workflow,
377
+ workflowIndex: cachedWorkflowIndex,
378
+ workflowCount: options.scopedWorkflowCount,
379
+ elapsedMs: 0
380
+ });
381
+ cachedWorkflowIndex += 1;
382
+ }
383
+ resetFileContentCache();
384
+ const cacheResolutionMs = performance.now() - cacheResolutionStartedAt;
385
+ options.emit({
386
+ phase: "cache-stats",
387
+ cacheHits,
388
+ cacheMisses,
389
+ invalidated: options.cacheInvalidated
390
+ });
391
+ return {
392
+ cachedArtifacts,
393
+ cachedAgentArtifacts,
394
+ workflowsToBuild,
395
+ fingerprintByBinding,
396
+ validatedHashesByBinding,
397
+ warnings,
398
+ cacheHits,
399
+ cacheMisses,
400
+ cacheResolutionMs
401
+ };
402
+ }
403
+ function collectDependencyPaths(scopedDiscoveredWorkflows, buildCache) {
404
+ const allDepPaths = [];
405
+ for (const discoveredWorkflow of scopedDiscoveredWorkflows) {
406
+ allDepPaths.push(discoveredWorkflow.resolvedFilePath);
407
+ const cached = discoveredWorkflow.exportKind === "agent" ? buildCache.agentBindings[discoveredWorkflow.bindingKey] : buildCache.bindings[discoveredWorkflow.bindingKey];
408
+ if (cached) allDepPaths.push(...cached.dependencyPaths);
409
+ }
410
+ return allDepPaths;
411
+ }
412
+ async function resolveCachedAgentArtifact(options) {
413
+ const cachedEntry = options.buildCache.agentBindings[options.discoveredWorkflow.bindingKey];
414
+ if (!cachedEntry) return null;
415
+ try {
416
+ const inputFingerprint = await computeWorkflowFingerprint(options.discoveredWorkflow.resolvedFilePath, cachedEntry.dependencyPaths);
417
+ options.fingerprintByBinding.set(options.discoveredWorkflow.bindingKey, inputFingerprint);
418
+ if (inputFingerprint !== cachedEntry.inputFingerprint) return null;
419
+ const artifact = await loadCachedAgentArtifact(options.outputDir, options.discoveredWorkflow, cachedEntry);
420
+ if (!artifact) return null;
421
+ return {
422
+ artifact,
423
+ validatedHashes: {
424
+ manifestHash: cachedEntry.manifestHash,
425
+ bundleHash: cachedEntry.bundleHash,
426
+ sandboxPackageHash: cachedEntry.sandboxPackageHash
427
+ }
428
+ };
429
+ } catch {
430
+ return null;
431
+ }
432
+ }
433
+ async function resolveCachedWorkflowArtifact(options) {
434
+ const cachedEntry = options.buildCache.bindings[options.discoveredWorkflow.bindingKey];
435
+ if (!cachedEntry) return null;
436
+ try {
437
+ const inputFingerprint = await computeWorkflowFingerprint(options.discoveredWorkflow.resolvedFilePath, cachedEntry.dependencyPaths);
438
+ options.fingerprintByBinding.set(options.discoveredWorkflow.bindingKey, inputFingerprint);
439
+ if (inputFingerprint !== cachedEntry.inputFingerprint) return null;
440
+ const artifact = await loadCachedArtifact(options.outputDir, options.discoveredWorkflow, cachedEntry);
441
+ if (!artifact) return null;
442
+ return {
443
+ artifact,
444
+ validatedHashes: {
445
+ manifestHash: cachedEntry.manifestHash,
446
+ flowGraphHash: cachedEntry.flowGraphHash,
447
+ bundleHash: cachedEntry.bundleHash,
448
+ sourceMapHash: cachedEntry.sourceMapHash
449
+ }
450
+ };
451
+ } catch {
452
+ return null;
453
+ }
454
+ }
455
+ /** Narrows to any failure tied to a specific workflow (workflow or loader-protocol). */
456
+ function isWorkflowScopedBuildFailure(failure) {
457
+ return failure.kind === "workflow" || failure.kind === "loader-protocol";
458
+ }
459
+ /** Narrows to a duplicate-workflow-id conflict failure. */
460
+ function isDuplicateWorkflowIdFailure(failure) {
461
+ return failure.kind === "duplicate-workflow-id";
462
+ }
463
+ /** Narrows to a duplicate-agent-id conflict failure. */
464
+ function isDuplicateAgentIdFailure(failure) {
465
+ return failure.kind === "duplicate-agent-id";
466
+ }
467
+ async function cleanupFailedBuildState(options) {
468
+ const workflowIdsToRemove = Array.from(new Set(options.workflowIdsToRemove));
469
+ if (workflowIdsToRemove.length > 0) await removeWorkflowArtifacts(options.outputDir, workflowIdsToRemove);
470
+ const agentIdsToRemove = Array.from(new Set(options.agentIdsToRemove ?? []));
471
+ if (agentIdsToRemove.length > 0) await removeAgentArtifacts(options.outputDir, agentIdsToRemove);
472
+ if (options.metadataPathsToRemove && options.metadataPathsToRemove.length > 0) await removeMetadataArtifacts(options.outputDir, options.metadataPathsToRemove.map((filePath) => createMetadataOutputFile(filePath)));
473
+ else await removeAllMetadataArtifacts(options.outputDir);
474
+ if (!options.cache) return;
475
+ const bindingKeysToRemove = new Set(options.bindingKeysToRemove);
476
+ const workflowIdsToRemoveSet = new Set(workflowIdsToRemove);
477
+ const agentIdsToRemoveSet = new Set(agentIdsToRemove);
478
+ const bindings = Object.fromEntries(typedEntries(options.cache.bindings).filter(([bindingKey, entry]) => !bindingKeysToRemove.has(bindingKey) && !workflowIdsToRemoveSet.has(entry.workflowId)));
479
+ const agentBindings = Object.fromEntries(typedEntries(options.cache.agentBindings).filter(([bindingKey, entry]) => !bindingKeysToRemove.has(bindingKey) && !agentIdsToRemoveSet.has(entry.agentId)));
480
+ const metadataPathsToRemove = new Set(options.metadataPathsToRemove ?? []);
481
+ const metadata = metadataPathsToRemove.size > 0 ? Object.fromEntries(typedEntries(options.cache.metadata).filter(([filePath]) => !metadataPathsToRemove.has(parseRelativeFilePath(filePath)))) : {};
482
+ await writeBuildCache(options.outputDir, {
483
+ ...options.cache,
484
+ builderFingerprint: options.builderFingerprint ?? options.cache.builderFingerprint,
485
+ scanEntries: options.scanEntries ?? options.cache.scanEntries,
486
+ bindings,
487
+ agentBindings,
488
+ metadata
489
+ });
490
+ }
491
+ async function resolveCandidateFiles(projectRoot) {
492
+ const resolvedProjectRoot = path.resolve(projectRoot);
493
+ const files = await (0, import_out.default)([...DISCOVERY_GLOB], {
494
+ cwd: resolvedProjectRoot,
495
+ absolute: true,
496
+ onlyFiles: true,
497
+ ignore: [...DISCOVERY_IGNORE]
498
+ });
499
+ files.sort((left, right) => left.localeCompare(right));
500
+ return files;
501
+ }
502
+ async function resolveDiscoveredWorkflowEntries(candidateFiles, projectRoot) {
503
+ const resolutionContext = { cache: /* @__PURE__ */ new Map() };
504
+ const entries = [];
505
+ for (const exportFilePath of candidateFiles) {
506
+ const moduleResolution = await resolveModuleExports(exportFilePath, resolutionContext, []);
507
+ const discoveredByBindingKey = /* @__PURE__ */ new Map();
508
+ for (const [exportName, target] of moduleResolution.namedExports) {
509
+ if (!target) continue;
510
+ const discovered = createDiscoveredWorkflow({
511
+ exportFilePath,
512
+ exportName,
513
+ isDefaultExport: false,
514
+ projectRoot,
515
+ target
516
+ });
517
+ discoveredByBindingKey.set(discovered.bindingKey, discoveredByBindingKey.get(discovered.bindingKey) ?? discovered);
518
+ }
519
+ if (moduleResolution.defaultExport) {
520
+ const discovered = createDiscoveredWorkflow({
521
+ exportFilePath,
522
+ exportName: "default",
523
+ isDefaultExport: true,
524
+ projectRoot,
525
+ target: moduleResolution.defaultExport
526
+ });
527
+ discoveredByBindingKey.set(discovered.bindingKey, discoveredByBindingKey.get(discovered.bindingKey) ?? discovered);
528
+ }
529
+ entries.push({
530
+ exportFilePath,
531
+ discoveryEntries: [...discoveredByBindingKey.values()].sort((left, right) => left.bindingKey.localeCompare(right.bindingKey)),
532
+ dependencyPaths: moduleResolution.dependencyPaths.filter((dependencyPath) => dependencyPath !== exportFilePath)
533
+ });
534
+ }
535
+ return entries.sort((left, right) => left.exportFilePath.localeCompare(right.exportFilePath));
536
+ }
537
+ async function resolveModuleExports(filePath, context, resolutionStack) {
538
+ const resolvedFilePath = path.resolve(filePath);
539
+ const cached = context.cache.get(resolvedFilePath);
540
+ if (cached) return cached;
541
+ const resolutionPromise = resolveModuleExportsUncached(resolvedFilePath, context, resolutionStack);
542
+ context.cache.set(resolvedFilePath, resolutionPromise);
543
+ return resolutionPromise;
544
+ }
545
+ async function resolveModuleExportsUncached(filePath, context, resolutionStack) {
546
+ if (resolutionStack.includes(filePath)) return {
547
+ namedExports: /* @__PURE__ */ new Map(),
548
+ defaultExport: null,
549
+ dependencyPaths: [filePath]
550
+ };
551
+ const analysis = await analyzeModule(filePath, parseSourceFile(filePath, await readFile(filePath, "utf-8")), context, [...resolutionStack, filePath]);
552
+ if (analysis.hasNamespaceStarExport) throw createNamespaceStarExportDiscoveryError(filePath);
553
+ const ambiguousExports = [...analysis.namedExports.entries()].filter(([, target]) => target === null).map(([exportName]) => exportName);
554
+ if (ambiguousExports.length > 0) throw createAmbiguousExportDiscoveryError(filePath, ambiguousExports);
555
+ return {
556
+ namedExports: analysis.namedExports,
557
+ defaultExport: analysis.defaultExport,
558
+ dependencyPaths: [...new Set([filePath, ...analysis.dependencyPaths])].sort((left, right) => left.localeCompare(right))
559
+ };
560
+ }
561
+ async function analyzeModule(filePath, sourceFile, context, resolutionStack) {
562
+ const workflowImportNames = collectWorkflowImportNames(sourceFile);
563
+ const localWorkflowBindings = collectLocalWorkflowBindings(sourceFile, workflowImportNames);
564
+ const namedExports = /* @__PURE__ */ new Map();
565
+ let defaultExport = null;
566
+ let hasNamespaceStarExport = false;
567
+ const dependencyPaths = /* @__PURE__ */ new Set();
568
+ for (const statement of sourceFile.statements) {
569
+ if (isExportedVariableStatement(statement)) {
570
+ for (const declaration of getVariableDeclarators(statement)) {
571
+ const localName = identifierName(declaration.id);
572
+ if (!localName) continue;
573
+ const exportKind = localWorkflowBindings.get(localName);
574
+ if (!exportKind) continue;
575
+ addNamedExport(namedExports, localName, {
576
+ resolvedFilePath: filePath,
577
+ localExportName: localName,
578
+ exportKind
579
+ });
580
+ }
581
+ continue;
582
+ }
583
+ if (statement.type === "ExportNamedDeclaration") {
584
+ const moduleSpecifier = getLocalModuleSpecifier(literalString(statement.source));
585
+ if (!moduleSpecifier) {
586
+ if (Array.isArray(statement.specifiers)) for (const specifier of statement.specifiers) {
587
+ if (!isNode(specifier) || specifier.type !== "ExportSpecifier") continue;
588
+ const localName = identifierName(specifier.local);
589
+ const exportName = identifierName(specifier.exported);
590
+ if (!localName || !exportName) continue;
591
+ const exportKind = localWorkflowBindings.get(localName);
592
+ if (!exportKind) continue;
593
+ addNamedExport(namedExports, exportName, {
594
+ resolvedFilePath: filePath,
595
+ localExportName: localName,
596
+ exportKind
597
+ });
598
+ }
599
+ continue;
600
+ }
601
+ const resolvedModuleFile = await resolveLocalModulePath(filePath, moduleSpecifier);
602
+ if (!resolvedModuleFile) continue;
603
+ const targetResolution = await resolveModuleExports(resolvedModuleFile, context, resolutionStack);
604
+ dependencyPaths.add(resolvedModuleFile);
605
+ for (const dependencyPath of targetResolution.dependencyPaths) dependencyPaths.add(dependencyPath);
606
+ for (const specifier of Array.isArray(statement.specifiers) ? statement.specifiers : []) {
607
+ if (!isNode(specifier) || specifier.type !== "ExportSpecifier") continue;
608
+ const sourceExportName = identifierName(specifier.local);
609
+ const exportName = identifierName(specifier.exported);
610
+ if (!sourceExportName || !exportName) continue;
611
+ if (sourceExportName === "default") {
612
+ if (exportName === "default") defaultExport = targetResolution.defaultExport;
613
+ else addNamedExport(namedExports, exportName, targetResolution.defaultExport);
614
+ continue;
615
+ }
616
+ addNamedExport(namedExports, exportName, targetResolution.namedExports.get(sourceExportName) ?? null);
617
+ }
618
+ continue;
619
+ }
620
+ if (statement.type === "ExportAllDeclaration") {
621
+ const moduleSpecifier = getLocalModuleSpecifier(literalString(statement.source));
622
+ if (!moduleSpecifier) continue;
623
+ const resolvedModuleFile = await resolveLocalModulePath(filePath, moduleSpecifier);
624
+ if (!resolvedModuleFile) continue;
625
+ const targetResolution = await resolveModuleExports(resolvedModuleFile, context, resolutionStack);
626
+ dependencyPaths.add(resolvedModuleFile);
627
+ for (const dependencyPath of targetResolution.dependencyPaths) dependencyPaths.add(dependencyPath);
628
+ if (identifierName(statement.exported)) {
629
+ hasNamespaceStarExport = true;
630
+ continue;
631
+ }
632
+ for (const [exportName, target] of targetResolution.namedExports) addNamedExport(namedExports, exportName, target);
633
+ continue;
634
+ }
635
+ if (statement.type === "ExportDefaultDeclaration" && isNode(statement.declaration)) defaultExport = resolveDefaultExportAssignment(statement.declaration, filePath, localWorkflowBindings, workflowImportNames);
636
+ }
637
+ return {
638
+ localWorkflowBindings,
639
+ namedExports,
640
+ defaultExport,
641
+ hasNamespaceStarExport,
642
+ dependencyPaths: [...dependencyPaths].sort((left, right) => left.localeCompare(right))
643
+ };
644
+ }
645
+ function addNamedExport(exportsMap, exportName, target) {
646
+ if (!target) return;
647
+ const existing = exportsMap.get(exportName);
648
+ if (!existing) {
649
+ exportsMap.set(exportName, target);
650
+ return;
651
+ }
652
+ if (existing.resolvedFilePath === target.resolvedFilePath && existing.localExportName === target.localExportName && existing.exportKind === target.exportKind) return;
653
+ exportsMap.set(exportName, null);
654
+ }
655
+ function createDiscoveredWorkflow(options) {
656
+ return {
657
+ exportFilePath: options.exportFilePath,
658
+ resolvedFilePath: options.target.resolvedFilePath,
659
+ relativePath: path.relative(options.projectRoot, options.target.resolvedFilePath),
660
+ exportName: options.exportName,
661
+ isDefaultExport: options.isDefaultExport,
662
+ localExportName: options.target.localExportName,
663
+ bindingKey: `${options.target.resolvedFilePath}::${options.target.localExportName}`,
664
+ exportKind: options.target.exportKind
665
+ };
666
+ }
667
+ const BLOCK_COMMENTS_RE = /\/\*[\s\S]*?\*\//g;
668
+ const LINE_COMMENTS_RE = /(^|[^:])\/\/.*$/gm;
669
+ function stripComments(source) {
670
+ return source.replace(BLOCK_COMMENTS_RE, "").replace(LINE_COMMENTS_RE, "$1");
671
+ }
672
+ /**
673
+ * Fast pre-filter: returns true if the file MIGHT contain a workflow, agent,
674
+ * or task export. Files that return false are guaranteed not to export
675
+ * Workflow/Agent/Task instances and can skip expensive AST parsing.
676
+ *
677
+ * The heuristic checks for:
678
+ * 1. Direct `new Workflow(`, `new Agent(`, or `new Task(` constructor calls
679
+ * 2. Re-exports that reference a local module (`export { ... } from './...`)
680
+ * or `export * from './...` — these might re-export a workflow/agent/task
681
+ *
682
+ * We intentionally skip `export {` without a `from` clause when there's no
683
+ * Workflow/Agent/Task reference, since those are just re-exports of local bindings
684
+ * which would already be caught by the constructor check.
685
+ */
686
+ function couldContainWorkflowExport(source) {
687
+ const codeOnly = stripComments(source);
688
+ if (codeOnly.includes("new Workflow(") || codeOnly.includes("new Agent(") || codeOnly.includes("new Task(")) return true;
689
+ if (REEXPORT_FROM_LOCAL_RE.test(codeOnly)) return true;
690
+ if (codeOnly.includes("export default")) return codeOnly.includes("Workflow") || codeOnly.includes("Agent") || codeOnly.includes("Task");
691
+ return false;
692
+ }
693
+ const REEXPORT_FROM_LOCAL_RE = /export\s+(?:\{[^}]*\}|\*(?:\s+as\s+\w+)?)\s+from\s+['"]\.[\w./-]*['"]/;
694
+ const CONCURRENCY_LIMIT = 20;
695
+ async function discoverWorkflows(options) {
696
+ const startedAt = performance.now();
697
+ const projectRoot = path.resolve(options.projectRoot);
698
+ const allCandidateFiles = await resolveCandidateFiles(projectRoot);
699
+ const scanEntries = {};
700
+ const discoveredByBindingKey = /* @__PURE__ */ new Map();
701
+ const fileStats = await batchStat(allCandidateFiles);
702
+ const cacheHitFiles = [];
703
+ const cacheMissFiles = [];
704
+ for (let i = 0; i < allCandidateFiles.length; i++) {
705
+ const filePath = allCandidateFiles[i];
706
+ const fileStat = fileStats[i];
707
+ const cachedEntry = options.scanEntries?.[filePath];
708
+ if (cachedEntry && isScanCacheEntryValid(fileStat, cachedEntry, options.scanEntries ?? {}, fileStats, allCandidateFiles)) cacheHitFiles.push({
709
+ filePath,
710
+ entry: cachedEntry
711
+ });
712
+ else cacheMissFiles.push({
713
+ filePath,
714
+ fileStat
715
+ });
716
+ }
717
+ for (const { filePath, entry } of cacheHitFiles) {
718
+ scanEntries[filePath] = entry;
719
+ for (const workflow of entry.discoveryEntries) discoveredByBindingKey.set(workflow.bindingKey, discoveredByBindingKey.get(workflow.bindingKey) ?? workflow);
720
+ }
721
+ let filesScanned = cacheHitFiles.length;
722
+ options.onProgress?.({
723
+ filesScanned,
724
+ filesTotal: allCandidateFiles.length
725
+ });
726
+ for (let batchStart = 0; batchStart < cacheMissFiles.length; batchStart += CONCURRENCY_LIMIT) {
727
+ const batch = cacheMissFiles.slice(batchStart, batchStart + CONCURRENCY_LIMIT);
728
+ const batchResults = await Promise.all(batch.map(async ({ filePath, fileStat }) => {
729
+ if (!couldContainWorkflowExport(await readFile(filePath, "utf-8"))) return {
730
+ filePath,
731
+ entry: {
732
+ mtimeMs: fileStat.mtimeMs,
733
+ size: fileStat.size,
734
+ hasWorkflow: false,
735
+ exportNames: [],
736
+ discoveryEntries: [],
737
+ dependencyPaths: []
738
+ }
739
+ };
740
+ const [resolvedEntry] = await resolveDiscoveredWorkflowEntries([filePath], projectRoot);
741
+ const discoveryEntries = resolvedEntry?.discoveryEntries ?? [];
742
+ return {
743
+ filePath,
744
+ entry: {
745
+ mtimeMs: fileStat.mtimeMs,
746
+ size: fileStat.size,
747
+ hasWorkflow: discoveryEntries.length > 0,
748
+ exportNames: discoveryEntries.map((w) => w.exportName),
749
+ discoveryEntries,
750
+ dependencyPaths: resolvedEntry?.dependencyPaths ?? []
751
+ }
752
+ };
753
+ }));
754
+ for (const { filePath, entry } of batchResults) {
755
+ scanEntries[filePath] = entry;
756
+ for (const workflow of entry.discoveryEntries) discoveredByBindingKey.set(workflow.bindingKey, discoveredByBindingKey.get(workflow.bindingKey) ?? workflow);
757
+ }
758
+ filesScanned += batch.length;
759
+ options.onProgress?.({
760
+ filesScanned,
761
+ filesTotal: allCandidateFiles.length
762
+ });
763
+ }
764
+ const discoveredExports = [...discoveredByBindingKey.values()].sort((left, right) => left.bindingKey.localeCompare(right.bindingKey));
765
+ const { workflowCount, agentCount, taskCount } = countDiscoveredExports$1(discoveredExports);
766
+ return {
767
+ projectRoot,
768
+ workflows: discoveredExports,
769
+ workflowCount,
770
+ agentCount,
771
+ taskCount,
772
+ filesScanned,
773
+ elapsedMs: performance.now() - startedAt,
774
+ scanEntries
775
+ };
776
+ }
777
+ async function batchStat(files) {
778
+ const results = [];
779
+ for (let i = 0; i < files.length; i += CONCURRENCY_LIMIT) {
780
+ const batch = files.slice(i, i + CONCURRENCY_LIMIT);
781
+ const batchResults = await Promise.all(batch.map(async (filePath) => {
782
+ const s = await stat(filePath);
783
+ return {
784
+ mtimeMs: s.mtimeMs,
785
+ size: s.size
786
+ };
787
+ }));
788
+ results.push(...batchResults);
789
+ }
790
+ return results;
791
+ }
792
+ function isScanCacheEntryValid(fileStat, cachedEntry, previousScanEntries, allFileStats, allFilePaths) {
793
+ if (cachedEntry.discoveryEntries.some((entry) => entry.exportKind !== "workflow" && entry.exportKind !== "agent" && entry.exportKind !== "task")) return false;
794
+ if (cachedEntry.mtimeMs !== fileStat.mtimeMs || cachedEntry.size !== fileStat.size) return false;
795
+ const fileStatLookup = /* @__PURE__ */ new Map();
796
+ for (let i = 0; i < allFilePaths.length; i++) {
797
+ const fp = allFilePaths[i];
798
+ const fs = allFileStats[i];
799
+ fileStatLookup.set(fp, fs);
800
+ }
801
+ for (const dependencyPath of cachedEntry.dependencyPaths) {
802
+ const dependencyEntry = previousScanEntries[dependencyPath];
803
+ if (!dependencyEntry) return false;
804
+ const dependencyStat = fileStatLookup.get(dependencyPath);
805
+ if (!dependencyStat) return false;
806
+ if (dependencyEntry.mtimeMs !== dependencyStat.mtimeMs || dependencyEntry.size !== dependencyStat.size) return false;
807
+ }
808
+ return true;
809
+ }
810
+ function countDiscoveredExports$1(discoveredExports) {
811
+ let workflowCount = 0;
812
+ let agentCount = 0;
813
+ let taskCount = 0;
814
+ for (const discoveredExport of discoveredExports) if (discoveredExport.exportKind === "agent") agentCount += 1;
815
+ else if (discoveredExport.exportKind === "task") taskCount += 1;
816
+ else workflowCount += 1;
817
+ return {
818
+ workflowCount,
819
+ agentCount,
820
+ taskCount
821
+ };
822
+ }
823
+ function createProgressEmitter(callback) {
824
+ return function emit(event) {
825
+ if (!callback) return;
826
+ queueMicrotask(() => {
827
+ try {
828
+ callback(event);
829
+ } catch {}
830
+ });
831
+ };
832
+ }
833
+ function runCycleDetection(params) {
834
+ const detectedCycles = detectAgentInPathCycles(buildCycleAnalysisInput(params));
835
+ return {
836
+ detectedCycles,
837
+ blocking: detectedCycles.length > 0
838
+ };
839
+ }
840
+ function buildCycleAnalysisInput(params) {
841
+ return {
842
+ agents: params.agentArtifacts.map((artifact) => ({
843
+ kind: "agent",
844
+ id: artifact.agent.agentId,
845
+ displayName: artifact.agent.agentName,
846
+ tools: (artifact.manifest.tools ?? []).filter((tool) => tool.sourceKind === "workflow" && tool.authoredWorkflowId).map((tool) => tool.authoredWorkflowId)
847
+ })),
848
+ workflows: params.workflowArtifacts.map((artifact) => ({
849
+ kind: "workflow",
850
+ id: artifact.workflow.workflowId,
851
+ displayName: artifact.manifest.name,
852
+ callees: artifact.flowGraph.nodes.flatMap((node) => {
853
+ if (node.type !== "step" || node.data.kind !== "call") return [];
854
+ if (node.data.callKind !== "child-workflow" && node.data.callKind !== "agent") return [];
855
+ return node.data.stepId ? [node.data.stepId] : [];
856
+ })
857
+ })),
858
+ operations: []
859
+ };
860
+ }
861
+ /**
862
+ * Names that conflict with builder output directories/files.
863
+ * A workflow id matching any of these would overwrite builder infrastructure.
864
+ *
865
+ * Note: `.keystroke` is not included because it contains a dot, which is already
866
+ * rejected by the workflow id schema (`[a-zA-Z0-9_-]+`).
867
+ */
868
+ const RESERVED_WORKFLOW_IDS = new Set([
869
+ METADATA_ROOT_DIR_NAME,
870
+ BUILD_DIR_NAME,
871
+ "node_modules"
872
+ ]);
873
+ /**
874
+ * Prefixes that conflict with builder output directory naming conventions.
875
+ * A workflow id starting with any of these would collide with agent artifact dirs.
876
+ */
877
+ const RESERVED_WORKFLOW_ID_PREFIXES = [AGENT_ARTIFACT_DIR_PREFIX];
878
+ var ReservedWorkflowIdError = class extends Error {
879
+ workflowId;
880
+ file;
881
+ bindingKey;
882
+ constructor(options) {
883
+ const reserved = RESERVED_WORKFLOW_ID_PREFIXES.some((prefix) => options.workflowId.startsWith(prefix)) ? `prefix "${options.workflowId.split("_")[0]}_"` : `"${options.workflowId}"`;
884
+ super(`Workflow id ${reserved} is reserved by the build system and cannot be used (in ${options.file})`);
885
+ this.name = "ReservedWorkflowIdError";
886
+ this.workflowId = options.workflowId;
887
+ this.file = options.file;
888
+ this.bindingKey = options.bindingKey;
889
+ }
890
+ };
891
+ function assertUniqueWorkflowIds(artifacts) {
892
+ const artifactByWorkflowId = /* @__PURE__ */ new Map();
893
+ for (const artifact of artifacts) {
894
+ assertNotReservedWorkflowId(artifact);
895
+ const existingSource = artifactByWorkflowId.get(artifact.workflow.workflowId);
896
+ if (existingSource) throw new DuplicateWorkflowIdError({
897
+ workflowId: artifact.workflow.workflowId,
898
+ files: [existingSource.file, artifact.workflow.resolvedFilePath],
899
+ bindingKeys: [existingSource.bindingKey, artifact.workflow.bindingKey]
900
+ });
901
+ artifactByWorkflowId.set(artifact.workflow.workflowId, {
902
+ file: artifact.workflow.resolvedFilePath,
903
+ bindingKey: artifact.workflow.bindingKey
904
+ });
905
+ }
906
+ }
907
+ var DuplicateAgentIdError = class extends Error {
908
+ agentId;
909
+ files;
910
+ bindingKeys;
911
+ constructor(options) {
912
+ super(`Duplicate agent id "${options.agentId}" found in ${options.files.join(" and ")}`);
913
+ this.name = "DuplicateAgentIdError";
914
+ this.agentId = options.agentId;
915
+ this.files = [...options.files];
916
+ this.bindingKeys = [...options.bindingKeys];
917
+ }
918
+ };
919
+ function assertUniqueAgentIds(artifacts) {
920
+ const seen = /* @__PURE__ */ new Map();
921
+ for (const artifact of artifacts) {
922
+ const existing = seen.get(artifact.agent.agentId);
923
+ if (existing) throw new DuplicateAgentIdError({
924
+ agentId: artifact.agent.agentId,
925
+ files: [existing.file, artifact.agent.resolvedFilePath],
926
+ bindingKeys: [existing.bindingKey, artifact.agent.bindingKey]
927
+ });
928
+ seen.set(artifact.agent.agentId, {
929
+ file: artifact.agent.resolvedFilePath,
930
+ bindingKey: artifact.agent.bindingKey
931
+ });
932
+ }
933
+ }
934
+ var DuplicateCredentialSetIdError = class extends Error {
935
+ resolvedCredentialSetId;
936
+ files;
937
+ constructor(options) {
938
+ super(`Duplicate credential set resolved ID "${options.resolvedCredentialSetId}" found in ${options.files.join(" and ")}`);
939
+ this.name = "DuplicateCredentialSetIdError";
940
+ this.resolvedCredentialSetId = options.resolvedCredentialSetId;
941
+ this.files = [...options.files];
942
+ }
943
+ };
944
+ function assertUniqueCredentialSetDefinitionResolvedIds(analyzedFiles) {
945
+ const seen = /* @__PURE__ */ new Map();
946
+ for (const analyzedFile of analyzedFiles) for (const credentialSet of analyzedFile.definitions.credentialSets) {
947
+ if (!credentialSet.resolvedCredentialSetId) continue;
948
+ const existing = seen.get(credentialSet.resolvedCredentialSetId);
949
+ if (existing && existing !== analyzedFile.filePath) throw new DuplicateCredentialSetIdError({
950
+ resolvedCredentialSetId: credentialSet.resolvedCredentialSetId,
951
+ files: [existing, analyzedFile.filePath]
952
+ });
953
+ seen.set(credentialSet.resolvedCredentialSetId, analyzedFile.filePath);
954
+ }
955
+ }
956
+ function assertNotReservedWorkflowId(artifact) {
957
+ const id = artifact.workflow.workflowId;
958
+ if (RESERVED_WORKFLOW_IDS.has(id)) throw new ReservedWorkflowIdError({
959
+ workflowId: id,
960
+ file: artifact.workflow.resolvedFilePath,
961
+ bindingKey: artifact.workflow.bindingKey
962
+ });
963
+ for (const prefix of RESERVED_WORKFLOW_ID_PREFIXES) if (id.startsWith(prefix)) throw new ReservedWorkflowIdError({
964
+ workflowId: id,
965
+ file: artifact.workflow.resolvedFilePath,
966
+ bindingKey: artifact.workflow.bindingKey
967
+ });
968
+ }
969
+ async function buildDiscoveredWorkflows(options) {
970
+ const emit = createProgressEmitter(options.onProgressEvent);
971
+ const emitLifecycleEvents = options.emitLifecycleEvents ?? true;
972
+ const startedAt = performance.now();
973
+ const workflowCount = options.discoveredWorkflows.length;
974
+ const workflowBuildCount = options.discoveredWorkflows.filter((discoveredWorkflow) => discoveredWorkflow.exportKind === "workflow").length;
975
+ const agentBuildCount = options.discoveredWorkflows.filter((discoveredWorkflow) => discoveredWorkflow.exportKind === "agent").length;
976
+ const taskBuildCount = options.discoveredWorkflows.filter((discoveredWorkflow) => discoveredWorkflow.exportKind === "task").length;
977
+ if (emitLifecycleEvents) emit({
978
+ phase: "build-start",
979
+ workflowCount: workflowBuildCount,
980
+ agentCount: agentBuildCount,
981
+ taskCount: taskBuildCount
982
+ });
983
+ const workflowsByKey = /* @__PURE__ */ new Map();
984
+ for (let i = 0; i < workflowCount; i++) {
985
+ const workflow = options.discoveredWorkflows[i];
986
+ if (workflow) workflowsByKey.set(workflow.bindingKey, {
987
+ workflow,
988
+ index: i
989
+ });
990
+ }
991
+ const batchResults = await loadWorkflowMetadataBatch([...options.discoveredWorkflows], { concurrency: options.metadataLoaderConcurrency });
992
+ const metadataByKey = /* @__PURE__ */ new Map();
993
+ for (const result of batchResults) metadataByKey.set(result.bindingKey, result);
994
+ const buildPlan = await createBuildPlan({
995
+ discoveredWorkflows: options.discoveredWorkflows,
996
+ metadataByKey
997
+ });
998
+ const artifacts = [];
999
+ const agentArtifacts = [];
1000
+ const taskArtifacts = [];
1001
+ const failures = [...buildPlan.failures];
1002
+ const warnings = [];
1003
+ if (buildPlan.workflows.length > 0) {
1004
+ const { buildWorkflowArtifacts } = await import("./build-workflows-CfxBnIWh-CdYPv8w2.mjs");
1005
+ const result = await buildWorkflowArtifacts({
1006
+ entries: buildPlan.workflows,
1007
+ workflowsByKey,
1008
+ metadataByKey,
1009
+ projectRoot: options.projectRoot,
1010
+ workflowCount: workflowBuildCount,
1011
+ sourceMaps: options.sourceMaps,
1012
+ onProgressEvent: options.onProgressEvent
1013
+ });
1014
+ artifacts.push(...result.artifacts);
1015
+ failures.push(...result.failures);
1016
+ warnings.push(...result.warnings);
1017
+ }
1018
+ if (buildPlan.agents.length > 0) {
1019
+ const { buildAgentArtifacts } = await import("./build-agents-BmM_AsSd-BGi9wtzt.mjs");
1020
+ const result = await buildAgentArtifacts({
1021
+ entries: buildPlan.agents,
1022
+ projectRoot: options.projectRoot
1023
+ });
1024
+ agentArtifacts.push(...result.agentArtifacts);
1025
+ failures.push(...result.failures);
1026
+ }
1027
+ if (buildPlan.tasks.length > 0) {
1028
+ const { buildTaskArtifacts } = await import("./build-tasks-CdihpudT-D5r5HUHe.mjs");
1029
+ const result = await buildTaskArtifacts({
1030
+ entries: buildPlan.tasks,
1031
+ projectRoot: options.projectRoot,
1032
+ sourceMaps: options.sourceMaps
1033
+ });
1034
+ taskArtifacts.push(...result.taskArtifacts);
1035
+ failures.push(...result.failures);
1036
+ }
1037
+ try {
1038
+ assertUniqueWorkflowIds(artifacts);
1039
+ } catch (error) {
1040
+ if (error instanceof ReservedWorkflowIdError) failures.push({
1041
+ kind: "workflow",
1042
+ workflow: {
1043
+ bindingKey: error.bindingKey,
1044
+ exportFilePath: error.file,
1045
+ resolvedFilePath: error.file,
1046
+ exportName: "",
1047
+ localExportName: ""
1048
+ },
1049
+ phase: "output",
1050
+ error: error.message
1051
+ });
1052
+ else {
1053
+ const duplicateFailure = createDuplicateWorkflowIdFailure(artifacts, error);
1054
+ emit({
1055
+ phase: "duplicate-id-conflict",
1056
+ workflowId: duplicateFailure.workflowId,
1057
+ files: duplicateFailure.files
1058
+ });
1059
+ failures.push(duplicateFailure);
1060
+ }
1061
+ }
1062
+ try {
1063
+ assertUniqueAgentIds(agentArtifacts);
1064
+ } catch (error) {
1065
+ if (error instanceof DuplicateAgentIdError) failures.push({
1066
+ kind: "duplicate-agent-id",
1067
+ agentId: error.agentId,
1068
+ files: error.files,
1069
+ bindingKeys: error.bindingKeys,
1070
+ phase: "output",
1071
+ error: error.message
1072
+ });
1073
+ }
1074
+ const cycleDetection = runCycleDetection({
1075
+ workflowArtifacts: artifacts,
1076
+ agentArtifacts
1077
+ });
1078
+ for (const cycle of cycleDetection.detectedCycles) failures.push({
1079
+ kind: "agent-cycle",
1080
+ cyclePath: cycle.path.map((node) => `${node.kind}:${node.id}`),
1081
+ phase: "output",
1082
+ error: `Agent-in-path cycle detected: ${cycle.description}`
1083
+ });
1084
+ const successfulArtifacts = failures.some((failure) => failure.kind === "duplicate-workflow-id" || failure.kind === "duplicate-agent-id" || failure.kind === "agent-cycle") ? [] : artifacts;
1085
+ const totalMs = performance.now() - startedAt;
1086
+ if (emitLifecycleEvents) emit({
1087
+ phase: "build-complete",
1088
+ workflowBuiltCount: successfulArtifacts.length,
1089
+ agentBuiltCount: agentArtifacts.length,
1090
+ taskBuiltCount: taskArtifacts.length,
1091
+ cachedWorkflowCount: 0,
1092
+ cachedAgentCount: 0,
1093
+ cachedTaskCount: 0,
1094
+ builtCount: successfulArtifacts.length + agentArtifacts.length + taskArtifacts.length,
1095
+ failedCount: failures.length,
1096
+ cachedCount: 0,
1097
+ elapsedMs: totalMs
1098
+ });
1099
+ return {
1100
+ artifacts: successfulArtifacts,
1101
+ agentArtifacts,
1102
+ taskArtifacts,
1103
+ failures,
1104
+ warnings,
1105
+ totalMs,
1106
+ success: failures.length === 0
1107
+ };
1108
+ }
1109
+ async function createBuildPlan(options) {
1110
+ const plan = {
1111
+ workflows: [],
1112
+ agents: [],
1113
+ tasks: [],
1114
+ failures: []
1115
+ };
1116
+ let workflowProgressIndex = 0;
1117
+ for (const discoveredWorkflow of options.discoveredWorkflows) {
1118
+ const loadResult = options.metadataByKey.get(discoveredWorkflow.bindingKey);
1119
+ if (loadResult && isAgentLoadResult(loadResult)) {
1120
+ plan.agents.push({
1121
+ discoveredWorkflow,
1122
+ agentMetadata: loadResult.agentMetadata
1123
+ });
1124
+ continue;
1125
+ }
1126
+ if (loadResult && isTaskLoadResult(loadResult)) {
1127
+ plan.tasks.push({
1128
+ discoveredWorkflow,
1129
+ taskMetadata: loadResult.taskMetadata
1130
+ });
1131
+ continue;
1132
+ }
1133
+ const currentWorkflowIndex = workflowProgressIndex;
1134
+ workflowProgressIndex += 1;
1135
+ if (!loadResult?.ok) {
1136
+ const { createWorkflowMetadataFailure } = await import("./build-workflows-CfxBnIWh-CdYPv8w2.mjs");
1137
+ plan.failures.push(createWorkflowMetadataFailure(discoveredWorkflow, loadResult?.error));
1138
+ continue;
1139
+ }
1140
+ if (isWorkflowLoadResult(loadResult)) plan.workflows.push({
1141
+ discoveredWorkflow,
1142
+ metadata: loadResult.metadata,
1143
+ workflowIndex: currentWorkflowIndex
1144
+ });
1145
+ }
1146
+ return plan;
1147
+ }
1148
+ function countDiscoveredExports(discoveredWorkflows) {
1149
+ let workflowCount = 0;
1150
+ let agentCount = 0;
1151
+ let taskCount = 0;
1152
+ for (const discoveredWorkflow of discoveredWorkflows) if (discoveredWorkflow.exportKind === "agent") agentCount += 1;
1153
+ else if (discoveredWorkflow.exportKind === "task") taskCount += 1;
1154
+ else workflowCount += 1;
1155
+ return {
1156
+ workflowCount,
1157
+ agentCount,
1158
+ taskCount
1159
+ };
1160
+ }
1161
+ /**
1162
+ * Main build entry point. Discovers workflow exports, builds each through the pipeline
1163
+ * (import, manifest, flow-graph, bundle), and writes output artifacts.
1164
+ * Returns all artifacts on success or a list of failures with output set to null.
1165
+ */
1166
+ async function build(config) {
1167
+ return runBuild(config);
1168
+ }
1169
+ async function runBuild(config, initialTargetBindingKeys, metadataRebuildDecision) {
1170
+ const context = await prepareBuildContext(config);
1171
+ const { emit, startedAt, outputDir, builderFingerprint, buildCache } = context;
1172
+ const discoveryStage = await runDiscoveryStage(config, context);
1173
+ if (discoveryStage.result) return discoveryStage.result;
1174
+ const { cacheInvalidated, discovery } = discoveryStage;
1175
+ const targetResolution = resolveTargetedDiscovery({
1176
+ projectRoot: config.projectRoot,
1177
+ discovery,
1178
+ targetFiles: config.targetFiles
1179
+ });
1180
+ if (targetResolution && "failure" in targetResolution) {
1181
+ const result = createFailedExecutionResult({
1182
+ failure: targetResolution.failure,
1183
+ startedAt
1184
+ });
1185
+ emit({
1186
+ phase: "complete",
1187
+ success: false,
1188
+ totalMs: result.totalMs
1189
+ });
1190
+ return result;
1191
+ }
1192
+ let targetBindingKeys = targetResolution?.targetBindingKeys ?? initialTargetBindingKeys;
1193
+ let scopedPlan = null;
1194
+ if (targetResolution) scopedPlan = {
1195
+ scopedDiscoveredWorkflows: discovery.workflows.filter((workflow) => targetResolution.targetBindingKeys.has(workflow.bindingKey)),
1196
+ preservedArtifacts: [],
1197
+ targetBindingKeys: targetResolution.targetBindingKeys
1198
+ };
1199
+ else while (!scopedPlan) {
1200
+ scopedPlan = await buildScopedDiscoveryPlan({
1201
+ outputDir,
1202
+ buildCache,
1203
+ discovery,
1204
+ targetBindingKeys
1205
+ });
1206
+ if (!scopedPlan) targetBindingKeys = void 0;
1207
+ }
1208
+ const { preservedArtifacts, scopedDiscoveredWorkflows } = scopedPlan;
1209
+ const { workflowCount: scopedWorkflowCount, agentCount: scopedAgentCount, taskCount: scopedTaskCount } = countDiscoveredExports(scopedDiscoveredWorkflows);
1210
+ const { cachedArtifacts, cachedAgentArtifacts, workflowsToBuild, fingerprintByBinding, validatedHashesByBinding, warnings: cacheWarnings, cacheResolutionMs } = await resolveCachedArtifacts({
1211
+ config,
1212
+ scopedDiscoveredWorkflows,
1213
+ buildCache,
1214
+ outputDir,
1215
+ cacheInvalidated,
1216
+ scopedWorkflowCount,
1217
+ emit
1218
+ });
1219
+ const warnings = [...cacheWarnings];
1220
+ const duplicateBindingKeys = /* @__PURE__ */ new Set();
1221
+ const duplicateWorkflowIds = /* @__PURE__ */ new Set();
1222
+ const buildStartedAt = performance.now();
1223
+ emit({
1224
+ phase: "build-start",
1225
+ workflowCount: scopedWorkflowCount,
1226
+ agentCount: scopedAgentCount,
1227
+ taskCount: scopedTaskCount
1228
+ });
1229
+ const bundlePipelineStartedAt = performance.now();
1230
+ const pipelineResult = workflowsToBuild.length > 0 ? await buildDiscoveredWorkflows({
1231
+ discoveredWorkflows: workflowsToBuild,
1232
+ projectRoot: config.projectRoot,
1233
+ metadataLoaderConcurrency: config.metadataLoaderConcurrency,
1234
+ sourceMaps: config.sourceMaps ?? true,
1235
+ onProgressEvent: config.onProgressEvent,
1236
+ emitLifecycleEvents: false
1237
+ }) : {
1238
+ artifacts: [],
1239
+ agentArtifacts: [],
1240
+ taskArtifacts: [],
1241
+ failures: [],
1242
+ warnings: [],
1243
+ totalMs: 0,
1244
+ success: true
1245
+ };
1246
+ const bundlePipelineMs = performance.now() - bundlePipelineStartedAt;
1247
+ const failures = [...pipelineResult.failures];
1248
+ warnings.push(...pipelineResult.warnings);
1249
+ const artifacts = [
1250
+ ...preservedArtifacts,
1251
+ ...cachedArtifacts,
1252
+ ...pipelineResult.artifacts
1253
+ ];
1254
+ const agentArtifacts = [...cachedAgentArtifacts, ...pipelineResult.agentArtifacts];
1255
+ const taskArtifacts = [...pipelineResult.taskArtifacts];
1256
+ const finalizedScopedArtifacts = failures.length === 0 ? [...cachedArtifacts, ...pipelineResult.artifacts] : [];
1257
+ try {
1258
+ assertUniqueWorkflowIds(artifacts);
1259
+ } catch (error) {
1260
+ if (error instanceof ReservedWorkflowIdError) {
1261
+ const failure = {
1262
+ kind: "workflow",
1263
+ workflow: {
1264
+ bindingKey: error.bindingKey,
1265
+ exportFilePath: error.file,
1266
+ resolvedFilePath: error.file,
1267
+ exportName: "",
1268
+ localExportName: ""
1269
+ },
1270
+ phase: "output",
1271
+ error: error.message
1272
+ };
1273
+ failures.push(failure);
1274
+ } else {
1275
+ const duplicateFailure = createDuplicateWorkflowIdFailure(artifacts, error);
1276
+ duplicateWorkflowIds.add(duplicateFailure.workflowId);
1277
+ for (const bindingKey of duplicateFailure.bindingKeys) duplicateBindingKeys.add(bindingKey);
1278
+ emit({
1279
+ phase: "duplicate-id-conflict",
1280
+ workflowId: duplicateFailure.workflowId,
1281
+ files: duplicateFailure.files
1282
+ });
1283
+ failures.push(duplicateFailure);
1284
+ }
1285
+ }
1286
+ try {
1287
+ assertUniqueAgentIds(agentArtifacts);
1288
+ } catch (error) {
1289
+ if (error instanceof DuplicateAgentIdError) {
1290
+ for (const bindingKey of error.bindingKeys) duplicateBindingKeys.add(bindingKey);
1291
+ failures.push({
1292
+ kind: "duplicate-agent-id",
1293
+ agentId: error.agentId,
1294
+ files: error.files,
1295
+ bindingKeys: error.bindingKeys,
1296
+ phase: "output",
1297
+ error: error.message
1298
+ });
1299
+ }
1300
+ }
1301
+ const successfulArtifacts = failures.length === 0 ? artifacts : [];
1302
+ emit({
1303
+ phase: "build-complete",
1304
+ workflowBuiltCount: pipelineResult.artifacts.length,
1305
+ agentBuiltCount: pipelineResult.agentArtifacts.length,
1306
+ taskBuiltCount: pipelineResult.taskArtifacts.length,
1307
+ cachedWorkflowCount: cachedArtifacts.length,
1308
+ cachedAgentCount: cachedAgentArtifacts.length,
1309
+ cachedTaskCount: 0,
1310
+ builtCount: pipelineResult.artifacts.length + pipelineResult.agentArtifacts.length + pipelineResult.taskArtifacts.length,
1311
+ failedCount: failures.length,
1312
+ cachedCount: cachedArtifacts.length + cachedAgentArtifacts.length,
1313
+ elapsedMs: performance.now() - buildStartedAt,
1314
+ cacheResolutionMs,
1315
+ bundlePipelineMs
1316
+ });
1317
+ const finalizedArtifacts = failures.length === 0 ? successfulArtifacts : [];
1318
+ let output = null;
1319
+ let metadataCacheEntries = buildCache.metadata;
1320
+ if (failures.length === 0) {
1321
+ emit({
1322
+ phase: "output-start",
1323
+ artifactCount: finalizedArtifacts.length + agentArtifacts.length + taskArtifacts.length
1324
+ });
1325
+ const writeStartedAt = performance.now();
1326
+ const cacheResolvedBindingKeys = new Set([...cachedArtifacts.map((a) => a.workflow.bindingKey), ...cachedAgentArtifacts.map((a) => a.agent.bindingKey)]);
1327
+ const writeOptions = {
1328
+ skipUnchangedWrites: !config.force,
1329
+ buildCache,
1330
+ force: config.force,
1331
+ cacheResolvedBindingKeys,
1332
+ releaseBundleMemory: config.releaseBundleMemory
1333
+ };
1334
+ const { writeBuildOutput, writeTargetedBuildOutput } = await import("./writer-BG8poUm3-BbXlU2kI.mjs").then((n) => n.f).then((n) => n.t);
1335
+ const writeResult = targetBindingKeys ? await writeTargetedBuildOutput({
1336
+ artifacts: finalizedScopedArtifacts,
1337
+ agentArtifacts,
1338
+ taskArtifacts,
1339
+ failures: [],
1340
+ warnings,
1341
+ totalMs: pipelineResult.totalMs,
1342
+ success: true
1343
+ }, outputDir, collectPreviousWorkflowIds(buildCache, targetBindingKeys), writeOptions) : await writeBuildOutput({
1344
+ artifacts: finalizedArtifacts,
1345
+ agentArtifacts,
1346
+ taskArtifacts,
1347
+ failures: [],
1348
+ warnings,
1349
+ totalMs: pipelineResult.totalMs,
1350
+ success: true
1351
+ }, outputDir, writeOptions);
1352
+ emit({
1353
+ phase: "output-complete",
1354
+ writtenCount: writeResult.writtenCount,
1355
+ cleanedCount: writeResult.cleanedCount,
1356
+ elapsedMs: performance.now() - writeStartedAt,
1357
+ ...writeResult.skippedWriteCount !== void 0 && writeResult.skippedWriteCount > 0 ? { skippedWriteCount: writeResult.skippedWriteCount } : {}
1358
+ });
1359
+ const { buildMetadataArtifacts } = await import("./build-metadata-BWS7uhd_-DR8gJjTX.mjs");
1360
+ const metadata = await buildMetadataArtifacts({
1361
+ projectRoot: config.projectRoot,
1362
+ outputDir,
1363
+ artifacts: finalizedArtifacts,
1364
+ cacheEntries: buildCache.metadata,
1365
+ cacheInvalidated,
1366
+ rebuildDecision: targetResolution && "affectedPaths" in targetResolution ? {
1367
+ action: "targeted",
1368
+ affectedPaths: targetResolution.affectedPaths
1369
+ } : metadataRebuildDecision,
1370
+ emit
1371
+ });
1372
+ const conventionErrors = [];
1373
+ for (const violation of metadata.conventionViolations) if (violation.level === "warning") warnings.push(violation.message);
1374
+ else {
1375
+ failures.push({
1376
+ kind: "convention",
1377
+ filePath: violation.filePath,
1378
+ error: violation.message
1379
+ });
1380
+ conventionErrors.push(violation.message);
1381
+ }
1382
+ if (conventionErrors.length > 0) emit({
1383
+ phase: "convention-errors",
1384
+ errorCount: conventionErrors.length,
1385
+ errors: conventionErrors
1386
+ });
1387
+ try {
1388
+ assertUniqueCredentialSetDefinitionResolvedIds(metadata.analyzedFacts);
1389
+ } catch (error) {
1390
+ if (error instanceof Error) failures.push({
1391
+ kind: "convention",
1392
+ filePath: error instanceof DuplicateCredentialSetIdError ? error.files[0] ?? "" : "",
1393
+ error: error.message
1394
+ });
1395
+ }
1396
+ output = {
1397
+ writtenCount: writeResult.writtenCount,
1398
+ cleanedCount: writeResult.cleanedCount,
1399
+ outputDir: writeResult.outputDir,
1400
+ ...writeResult.skippedWriteCount !== void 0 && writeResult.skippedWriteCount > 0 ? { skippedWriteCount: writeResult.skippedWriteCount } : {},
1401
+ metadata: metadata.result
1402
+ };
1403
+ metadataCacheEntries = metadata.cacheEntries;
1404
+ }
1405
+ if (failures.length === 0) {
1406
+ const cacheEntries = createWorkflowCacheEntries(targetBindingKeys ? finalizedScopedArtifacts : finalizedArtifacts, validatedHashesByBinding);
1407
+ const agentCacheEntries = createAgentCacheEntries(targetBindingKeys ? pipelineResult.agentArtifacts : agentArtifacts, validatedHashesByBinding);
1408
+ for (const artifact of finalizedArtifacts) {
1409
+ const fingerprint = fingerprintByBinding.get(artifact.workflow.bindingKey) ?? await computeWorkflowFingerprint(artifact.workflow.resolvedFilePath, artifact.bundle.localDependencies);
1410
+ const cacheEntry = cacheEntries[artifact.workflow.bindingKey];
1411
+ if (cacheEntry) cacheEntry.inputFingerprint = fingerprint;
1412
+ }
1413
+ for (const artifact of agentArtifacts) {
1414
+ const fingerprint = fingerprintByBinding.get(artifact.agent.bindingKey) ?? await computeWorkflowFingerprint(artifact.agent.resolvedFilePath, artifact.bundle.localDependencies);
1415
+ const cacheEntry = agentCacheEntries[artifact.agent.bindingKey];
1416
+ if (cacheEntry) cacheEntry.inputFingerprint = fingerprint;
1417
+ }
1418
+ await writeBuildCache(outputDir, {
1419
+ ...buildCache,
1420
+ builderFingerprint,
1421
+ scanEntries: discovery.scanEntries,
1422
+ bindings: targetBindingKeys ? mergeScopedBindings(buildCache, cacheEntries, targetBindingKeys) : cacheEntries,
1423
+ agentBindings: targetBindingKeys ? mergeScopedAgentBindings(buildCache, agentCacheEntries, targetBindingKeys) : agentCacheEntries,
1424
+ metadata: metadataCacheEntries
1425
+ });
1426
+ } else await cleanupFailedBuild({
1427
+ buildCache,
1428
+ builderFingerprint,
1429
+ discoveryScanEntries: discovery.scanEntries,
1430
+ duplicateBindingKeys,
1431
+ duplicateWorkflowIds,
1432
+ failures,
1433
+ metadataRebuildDecision,
1434
+ outputDir
1435
+ });
1436
+ const totalMs = performance.now() - startedAt;
1437
+ const result = {
1438
+ artifacts: finalizedArtifacts,
1439
+ agentArtifacts,
1440
+ taskArtifacts,
1441
+ failures,
1442
+ warnings,
1443
+ totalMs,
1444
+ success: failures.length === 0,
1445
+ output
1446
+ };
1447
+ emit({
1448
+ phase: "complete",
1449
+ success: result.success,
1450
+ totalMs
1451
+ });
1452
+ return result;
1453
+ }
1454
+ async function prepareBuildContext(config) {
1455
+ const emit = createProgressEmitter(config.onProgressEvent);
1456
+ const startedAt = performance.now();
1457
+ await assertWorkflowProjectRoot(config.projectRoot);
1458
+ const outputDir = resolveBuildOutputDir(config);
1459
+ if (hasTargetFiles(config) && !config.outDir) await fs.rm(outputDir, {
1460
+ recursive: true,
1461
+ force: true
1462
+ });
1463
+ const builderFingerprint = await computeBuilderFingerprint(path$1.join(path$1.dirname(fileURLToPath(import.meta.url)), ".."));
1464
+ const existingCache = config.force ? null : await readBuildCache(outputDir);
1465
+ return {
1466
+ emit,
1467
+ startedAt,
1468
+ outputDir,
1469
+ builderFingerprint,
1470
+ buildCache: config.force || !existingCache || existingCache.builderFingerprint !== builderFingerprint ? createEmptyBuildCache(builderFingerprint) : existingCache
1471
+ };
1472
+ }
1473
+ function hasTargetFiles(config) {
1474
+ return (config.targetFiles?.length ?? 0) > 0;
1475
+ }
1476
+ function resolveBuildOutputDir(config) {
1477
+ if (!hasTargetFiles(config)) return resolveOutputDir(config.projectRoot, config);
1478
+ if (config.outDir) return resolveOutputDir(config.projectRoot, config);
1479
+ const normalizedTargets = (config.targetFiles ?? []).map((target) => path$1.isAbsolute(target) ? target : path$1.resolve(config.projectRoot, target)).map((target) => path$1.normalize(target)).sort((left, right) => left.localeCompare(right));
1480
+ const targetHash = createHash("sha256").update(JSON.stringify(normalizedTargets)).digest("hex");
1481
+ return path$1.join(getKeystrokeTmpDir({ projectRoot: config.projectRoot }), "target-builds", targetHash);
1482
+ }
1483
+ async function runDiscoveryStage(config, context) {
1484
+ const existingCache = config.force ? null : await readBuildCache(context.outputDir);
1485
+ const cacheInvalidated = Boolean(existingCache && existingCache.builderFingerprint !== context.builderFingerprint);
1486
+ context.emit({
1487
+ phase: "discovery-start",
1488
+ filesTotal: 0
1489
+ });
1490
+ try {
1491
+ const discovery = await discoverWorkflows({
1492
+ projectRoot: config.projectRoot,
1493
+ scanEntries: context.buildCache.scanEntries,
1494
+ onProgress: ({ filesScanned, filesTotal }) => {
1495
+ context.emit({
1496
+ phase: "discovery-scan",
1497
+ filesScanned,
1498
+ filesTotal
1499
+ });
1500
+ }
1501
+ });
1502
+ context.emit({
1503
+ phase: "discovery-complete",
1504
+ workflowCount: discovery.workflowCount,
1505
+ agentCount: discovery.agentCount,
1506
+ filesScanned: discovery.filesScanned,
1507
+ elapsedMs: discovery.elapsedMs
1508
+ });
1509
+ return {
1510
+ cacheInvalidated,
1511
+ discovery
1512
+ };
1513
+ } catch (error) {
1514
+ const result = createFailedExecutionResult({
1515
+ failure: createDiscoveryFailure(error),
1516
+ startedAt: context.startedAt
1517
+ });
1518
+ context.emit({
1519
+ phase: "complete",
1520
+ success: false,
1521
+ totalMs: result.totalMs
1522
+ });
1523
+ return { result };
1524
+ }
1525
+ }
1526
+ async function buildScopedDiscoveryPlan(options) {
1527
+ if (!options.targetBindingKeys) return {
1528
+ scopedDiscoveredWorkflows: options.discovery.workflows,
1529
+ preservedArtifacts: [],
1530
+ targetBindingKeys: void 0
1531
+ };
1532
+ const discoveredBindingKeys = new Set(options.discovery.workflows.map((workflow) => workflow.bindingKey));
1533
+ for (const bindingKey of Array.from(options.targetBindingKeys)) if (!discoveredBindingKeys.has(bindingKey)) return null;
1534
+ const preservedArtifacts = [];
1535
+ for (const discoveredWorkflow of options.discovery.workflows) {
1536
+ if (options.targetBindingKeys.has(discoveredWorkflow.bindingKey)) continue;
1537
+ const preservedArtifact = await loadPreservedArtifact(options.outputDir, discoveredWorkflow, options.buildCache);
1538
+ if (!preservedArtifact) return null;
1539
+ preservedArtifacts.push(preservedArtifact);
1540
+ }
1541
+ return {
1542
+ scopedDiscoveredWorkflows: options.discovery.workflows.filter((workflow) => options.targetBindingKeys?.has(workflow.bindingKey)),
1543
+ preservedArtifacts,
1544
+ targetBindingKeys: options.targetBindingKeys
1545
+ };
1546
+ }
1547
+ function resolveTargetedDiscovery(options) {
1548
+ const targetFiles = options.targetFiles?.filter((target) => target.trim().length > 0) ?? [];
1549
+ if (targetFiles.length === 0) return null;
1550
+ const normalizedTargets = /* @__PURE__ */ new Map();
1551
+ for (const target of targetFiles) {
1552
+ const absolutePath = path$1.normalize(path$1.isAbsolute(target) ? target : path$1.resolve(options.projectRoot, target));
1553
+ normalizedTargets.set(absolutePath, target);
1554
+ }
1555
+ const matchedBindingKeys = /* @__PURE__ */ new Set();
1556
+ const affectedPaths = /* @__PURE__ */ new Set();
1557
+ const matchedTargets = /* @__PURE__ */ new Set();
1558
+ for (const discoveredWorkflow of options.discovery.workflows) {
1559
+ const resolvedPath = path$1.normalize(discoveredWorkflow.resolvedFilePath);
1560
+ if (!normalizedTargets.has(resolvedPath)) continue;
1561
+ matchedBindingKeys.add(discoveredWorkflow.bindingKey);
1562
+ affectedPaths.add(discoveredWorkflow.relativePath);
1563
+ matchedTargets.add(resolvedPath);
1564
+ }
1565
+ for (const [absolutePath, originalTarget] of normalizedTargets) {
1566
+ if (matchedTargets.has(absolutePath)) continue;
1567
+ return { failure: {
1568
+ kind: "discovery",
1569
+ code: "unknown-discovery-error",
1570
+ filePath: absolutePath,
1571
+ exportNames: [],
1572
+ error: `Target file "${originalTarget}" did not contain any deployable workflow, agent, or task exports.`
1573
+ } };
1574
+ }
1575
+ return {
1576
+ targetBindingKeys: matchedBindingKeys,
1577
+ affectedPaths: Array.from(affectedPaths).sort((left, right) => left.localeCompare(right))
1578
+ };
1579
+ }
1580
+ function createFailedExecutionResult(options) {
1581
+ return {
1582
+ artifacts: [],
1583
+ agentArtifacts: [],
1584
+ taskArtifacts: [],
1585
+ failures: options.failures ?? (options.failure ? [options.failure] : []),
1586
+ warnings: options.warnings ?? [],
1587
+ totalMs: performance.now() - options.startedAt,
1588
+ success: false,
1589
+ output: null
1590
+ };
1591
+ }
1592
+ function collectPreviousWorkflowIds(buildCache, targetBindingKeys) {
1593
+ const workflowIds = /* @__PURE__ */ new Set();
1594
+ for (const bindingKey of Array.from(targetBindingKeys)) {
1595
+ const workflowId = buildCache.bindings[bindingKey]?.workflowId;
1596
+ if (workflowId) workflowIds.add(workflowId);
1597
+ }
1598
+ return Array.from(workflowIds).sort((left, right) => left.localeCompare(right));
1599
+ }
1600
+ async function loadPreservedArtifact(outputDir, discoveredWorkflow, buildCache) {
1601
+ const cachedEntry = buildCache.bindings[discoveredWorkflow.bindingKey];
1602
+ if (!cachedEntry) return null;
1603
+ return loadCachedArtifact(outputDir, discoveredWorkflow, cachedEntry);
1604
+ }
1605
+ function mergeScopedBindings(buildCache, nextBindings, targetBindingKeys) {
1606
+ const mergedBindings = Object.fromEntries(typedEntries(buildCache.bindings).filter(([bindingKey]) => !targetBindingKeys.has(bindingKey)));
1607
+ for (const [bindingKey, entry] of Object.entries(nextBindings)) mergedBindings[bindingKey] = entry;
1608
+ return mergedBindings;
1609
+ }
1610
+ function mergeScopedAgentBindings(buildCache, nextBindings, targetBindingKeys) {
1611
+ const mergedBindings = Object.fromEntries(typedEntries(buildCache.agentBindings).filter(([bindingKey]) => !targetBindingKeys.has(bindingKey)));
1612
+ for (const [bindingKey, entry] of Object.entries(nextBindings)) mergedBindings[bindingKey] = entry;
1613
+ return mergedBindings;
1614
+ }
1615
+ async function cleanupFailedBuild(options) {
1616
+ const bindingKeysToRemove = new Set(options.duplicateBindingKeys);
1617
+ const workflowIdsToRemove = new Set(options.duplicateWorkflowIds);
1618
+ const agentIdsToRemove = /* @__PURE__ */ new Set();
1619
+ for (const failure of options.failures) {
1620
+ if (isWorkflowScopedBuildFailure(failure) && failure.workflow.bindingKey) bindingKeysToRemove.add(failure.workflow.bindingKey);
1621
+ if (isWorkflowScopedBuildFailure(failure) && failure.workflow.workflowId) workflowIdsToRemove.add(failure.workflow.workflowId);
1622
+ if (isDuplicateWorkflowIdFailure(failure)) {
1623
+ for (const bindingKey of failure.bindingKeys) {
1624
+ bindingKeysToRemove.add(bindingKey);
1625
+ const cachedEntry = options.buildCache.bindings[bindingKey];
1626
+ if (cachedEntry) workflowIdsToRemove.add(cachedEntry.workflowId);
1627
+ }
1628
+ workflowIdsToRemove.add(failure.workflowId);
1629
+ continue;
1630
+ }
1631
+ if (isDuplicateAgentIdFailure(failure)) {
1632
+ for (const bindingKey of failure.bindingKeys) {
1633
+ bindingKeysToRemove.add(bindingKey);
1634
+ const cachedAgentEntry = options.buildCache.agentBindings[bindingKey];
1635
+ if (cachedAgentEntry) agentIdsToRemove.add(cachedAgentEntry.agentId);
1636
+ }
1637
+ agentIdsToRemove.add(failure.agentId);
1638
+ continue;
1639
+ }
1640
+ if (!isWorkflowScopedBuildFailure(failure)) continue;
1641
+ const cachedEntry = options.buildCache.bindings[failure.workflow.bindingKey];
1642
+ if (cachedEntry) workflowIdsToRemove.add(cachedEntry.workflowId);
1643
+ const cachedAgentEntry = options.buildCache.agentBindings[failure.workflow.bindingKey];
1644
+ if (cachedAgentEntry) agentIdsToRemove.add(cachedAgentEntry.agentId);
1645
+ }
1646
+ await cleanupFailedBuildState({
1647
+ outputDir: options.outputDir,
1648
+ cache: options.buildCache,
1649
+ bindingKeysToRemove: Array.from(bindingKeysToRemove),
1650
+ workflowIdsToRemove: Array.from(workflowIdsToRemove),
1651
+ agentIdsToRemove: Array.from(agentIdsToRemove),
1652
+ metadataPathsToRemove: options.metadataRebuildDecision?.action === "targeted" ? options.metadataRebuildDecision.affectedPaths : void 0,
1653
+ builderFingerprint: options.builderFingerprint,
1654
+ scanEntries: options.discoveryScanEntries
1655
+ });
1656
+ }
1657
+ //#endregion
1658
+ //#region ../../packages/workflow-builder/dist/build-format-06ylK1PX.mjs
1659
+ const RAW_OUTPUT_MAX_LENGTH = 500;
1660
+ function truncateRawOutput(raw) {
1661
+ const trimmed = raw.trim();
1662
+ if (trimmed.length <= RAW_OUTPUT_MAX_LENGTH) return trimmed;
1663
+ return `${trimmed.slice(0, RAW_OUTPUT_MAX_LENGTH)}… (truncated)`;
1664
+ }
1665
+ /** Formats a build failure into a human-readable single-line message. */
1666
+ function formatBuildFailure(failure) {
1667
+ switch (failure.kind) {
1668
+ case "workflow": return `${failure.workflow.resolvedFilePath}: ${failure.error}`;
1669
+ case "loader-protocol": {
1670
+ const raw = failure.rawOutput?.trim();
1671
+ if (raw && raw.length > 0 && !failure.error.includes(raw)) {
1672
+ const detail = truncateRawOutput(raw);
1673
+ return `${failure.workflow.resolvedFilePath}: ${failure.error}\n ${detail.split("\n").join("\n ")}`;
1674
+ }
1675
+ return `${failure.workflow.resolvedFilePath}: ${failure.error}`;
1676
+ }
1677
+ case "duplicate-workflow-id": return `${failure.workflowId}: ${failure.error}`;
1678
+ case "duplicate-agent-id": return `${failure.agentId}: ${failure.error}`;
1679
+ case "agent-cycle": return failure.error;
1680
+ case "discovery": return `${failure.filePath}: ${failure.error}`;
1681
+ case "trigger": return `trigger "${failure.triggerName}" (${failure.triggerExportName}) in workflow ${failure.workflowId}: ${failure.error}`;
1682
+ case "convention": return `${failure.filePath}: ${failure.error}`;
1683
+ case "agent": return `${failure.agent.resolvedFilePath}: ${failure.error}`;
1684
+ case "task": return `${failure.task.resolvedFilePath}: ${failure.error}`;
1685
+ }
1686
+ }
1687
+ //#endregion
1688
+ //#region src/lib/workflow-build.ts
1689
+ var workflow_build_exports = /* @__PURE__ */ __exportAll({
1690
+ WorkflowBuildExecutionError: () => WorkflowBuildExecutionError,
1691
+ WorkflowBuildFailedError: () => WorkflowBuildFailedError,
1692
+ WorkflowNotFoundError: () => WorkflowNotFoundError,
1693
+ renderBuildFailure: () => renderBuildFailure,
1694
+ renderBuildHeader: () => renderBuildHeader,
1695
+ renderBuildSummary: () => renderBuildSummary,
1696
+ runWorkflowBuild: () => runWorkflowBuild,
1697
+ workflowBuildDependencies: () => workflowBuildDependencies
1698
+ });
1699
+ const workflowBuildDependencies = {
1700
+ assertWorkflowProjectRoot,
1701
+ build
1702
+ };
1703
+ var WorkflowNotFoundError = class extends Error {
1704
+ workflowName;
1705
+ availableNames;
1706
+ constructor(workflowName, availableNames) {
1707
+ super(`Workflow "${workflowName}" not found.`);
1708
+ this.name = "WorkflowNotFoundError";
1709
+ this.workflowName = workflowName;
1710
+ this.availableNames = availableNames;
1711
+ }
1712
+ };
1713
+ var WorkflowBuildExecutionError = class extends Error {
1714
+ causeValue;
1715
+ constructor(causeValue) {
1716
+ const message = causeValue instanceof Error ? causeValue.message : String(causeValue);
1717
+ super(`Build error: ${message}`);
1718
+ this.name = "WorkflowBuildExecutionError";
1719
+ this.causeValue = causeValue;
1720
+ }
1721
+ };
1722
+ var WorkflowBuildFailedError = class extends Error {
1723
+ errors;
1724
+ constructor(errors) {
1725
+ super("Build failed with errors.");
1726
+ this.name = "WorkflowBuildFailedError";
1727
+ this.errors = errors;
1728
+ }
1729
+ };
1730
+ async function runWorkflowBuild(options) {
1731
+ const projectConfig = await workflowBuildDependencies.assertWorkflowProjectRoot(options.workflowsDir);
1732
+ const outDir = resolveConfiguredBuildOutputDir(options.workflowsDir, projectConfig.build);
1733
+ let result;
1734
+ try {
1735
+ result = await workflowBuildDependencies.build({
1736
+ projectRoot: options.workflowsDir,
1737
+ outDir,
1738
+ force: options.force,
1739
+ targetFiles: options.targetFiles,
1740
+ metadataLoaderConcurrency: options.metadataLoaderConcurrency,
1741
+ releaseBundleMemory: options.releaseBundleMemory,
1742
+ sourceMaps: options.sourceMaps,
1743
+ onProgressEvent: options.onProgressEvent
1744
+ });
1745
+ } catch (error) {
1746
+ throw new WorkflowBuildExecutionError(error);
1747
+ }
1748
+ if (!result.success) throw new WorkflowBuildFailedError(result.failures);
1749
+ if (options.name) assertWorkflowRefExists(result, options.name);
1750
+ if (options.workflowRef) assertWorkflowRefExists(result, options.workflowRef);
1751
+ return {
1752
+ result,
1753
+ outDir: result.output?.outputDir ?? outDir
1754
+ };
1755
+ }
1756
+ function renderBuildHeader(workflowName) {
1757
+ if (workflowName) {
1758
+ ui.header(`Building workflow "${workflowName}"...`);
1759
+ return;
1760
+ }
1761
+ ui.header("Building workflows and agents...");
1762
+ }
1763
+ function renderBuildSummary(result, outDir) {
1764
+ ui.success("Build complete");
1765
+ const check = style("✓", `${ANSI.bold}${ANSI.green}`);
1766
+ const workflowLine = `Workflows: ${result.artifacts.length}`;
1767
+ const agentLine = `Agents: ${result.agentArtifacts.length}`;
1768
+ originalConsole.info(` ${check} ${workflowLine}`);
1769
+ logger.info(` ✓ ${workflowLine}`);
1770
+ originalConsole.info(` ${check} ${agentLine}`);
1771
+ logger.info(` ✓ ${agentLine}`);
1772
+ if (result.output?.metadata) {
1773
+ const metadataLine = `Metadata: ${result.output.metadata.fileCount} file(s)`;
1774
+ originalConsole.info(` ${check} ${metadataLine}`);
1775
+ logger.info(` ✓ ${metadataLine}`);
1776
+ }
1777
+ const totalLine = `Total: ${formatTotalTime(result.totalMs)}`;
1778
+ originalConsole.info(` ${check} ${totalLine}`);
1779
+ logger.info(` ✓ ${totalLine}`);
1780
+ if (result.warnings.length > 0) {
1781
+ ui.warn(`Build produced ${result.warnings.length} warning(s):`);
1782
+ for (const warning of result.warnings) ui.hint(`- ${warning}`);
1783
+ }
1784
+ ui.hint(`Output: ${outDir}`);
1785
+ }
1786
+ function formatTotalTime(ms) {
1787
+ if (ms < 1e3) return `${Math.round(ms)}ms`;
1788
+ const seconds = ms / 1e3;
1789
+ return seconds < 60 ? `${seconds.toFixed(1)}s` : `${Math.floor(seconds / 60)}m ${(seconds % 60).toFixed(1)}s`;
1790
+ }
1791
+ function renderBuildFailure(error) {
1792
+ if (error instanceof WorkflowNotFoundError) {
1793
+ ui.error(`Workflow "${error.workflowName}" not found.`);
1794
+ if (error.availableNames.length === 0) {
1795
+ ui.hint("No workflows were discovered in this project.");
1796
+ return;
1797
+ }
1798
+ ui.hint(`Available workflows: ${error.availableNames.join(", ")}`);
1799
+ return;
1800
+ }
1801
+ if (error instanceof WorkflowBuildExecutionError) {
1802
+ ui.error(error.message);
1803
+ return;
1804
+ }
1805
+ if (error instanceof WorkflowBuildFailedError) {
1806
+ ui.error("Build failed with errors:");
1807
+ for (const buildError of error.errors) ui.hint(`- ${formatBuildFailure(buildError)}`);
1808
+ return;
1809
+ }
1810
+ ui.error(`Build error: ${toErrorMessage(error)}`);
1811
+ }
1812
+ function assertWorkflowRefExists(result, workflowRef) {
1813
+ if (result.artifacts.find((artifact) => artifact.manifest.id === workflowRef || artifact.manifest.name === workflowRef)) return;
1814
+ const availableNames = result.artifacts.map((artifact) => artifact.manifest.name).sort((left, right) => left.localeCompare(right));
1815
+ const availableIds = result.artifacts.map((artifact) => artifact.manifest.id).sort((left, right) => left.localeCompare(right));
1816
+ throw new WorkflowNotFoundError(workflowRef, availableNames.length > 0 ? availableNames : availableIds);
1817
+ }
1818
+ //#endregion
1819
+ export { runWorkflowBuild as a, renderBuildSummary as i, renderBuildFailure as n, workflow_build_exports as o, renderBuildHeader as r, build as s, WorkflowNotFoundError as t };