@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.
- package/AGENTS-blurb.md +123 -0
- package/LICENSE +42 -0
- package/README.md +177 -0
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/bin/keystroke.mjs +107 -0
- package/dist/_manifest-JSRE3H8k.mjs +385 -0
- package/dist/agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs +2344 -0
- package/dist/agent-manifest-CDnbkR2f.mjs +245 -0
- package/dist/agents-CZJGxVqV.mjs +228 -0
- package/dist/api-keys-D2lgguuY.mjs +40 -0
- package/dist/auth-DN2VusyU.mjs +59 -0
- package/dist/auth.handler-CT1BQUvu.mjs +340 -0
- package/dist/browser-qwFrUH82.mjs +24 -0
- package/dist/build-agents-BmM_AsSd-BGi9wtzt.mjs +514 -0
- package/dist/build-metadata-BWS7uhd_-DR8gJjTX.mjs +1422 -0
- package/dist/build-progress-DgYKb4hB.mjs +183 -0
- package/dist/build-tasks-CdihpudT-D5r5HUHe.mjs +91 -0
- package/dist/build-workflows-CfxBnIWh-CdYPv8w2.mjs +370 -0
- package/dist/build.handler-4799CjWH.mjs +36 -0
- package/dist/chunk-CH6r78ws.mjs +37 -0
- package/dist/clear-cache.handler-B9tqSoSM.mjs +11 -0
- package/dist/clear.handler-BTIXXPTJ.mjs +42 -0
- package/dist/clear.handler-BydlX-zE.mjs +11 -0
- package/dist/commander-DfTVqQ-3.mjs +133 -0
- package/dist/concurrency-gXn9Rw8x-DNl2YtrS.mjs +20 -0
- package/dist/connect-BUXkeH0F.mjs +43 -0
- package/dist/connect.handler-CYel9cy6.mjs +430 -0
- package/dist/constants-CPpPdSNg.mjs +8 -0
- package/dist/context-T7HZuB97.mjs +138 -0
- package/dist/credential-env-map-CI8yWHVy.mjs +28 -0
- package/dist/credential-schema-mismatch-BKo5PjcQ.mjs +76 -0
- package/dist/credentials-CvmjU0lK.mjs +171 -0
- package/dist/credentials-OfVHOtG3.mjs +151216 -0
- package/dist/current-deployment-workflow-poHt27i3.mjs +94 -0
- package/dist/current.handler-B8zKzfPp.mjs +21 -0
- package/dist/delete.handler-bAu1iXVQ.mjs +17 -0
- package/dist/deploy-7Jjls436.mjs +26 -0
- package/dist/deploy-BOPIpRWm.mjs +74 -0
- package/dist/deploy-progress-BmGUNFKg.mjs +70 -0
- package/dist/deploy.handler-BAzgiNhd.mjs +370 -0
- package/dist/detect-env-access-CwkOYeYM-D_BCZqV6.mjs +209 -0
- package/dist/diff-utils-NEfcjqxt.mjs +185 -0
- package/dist/diff.handler-Du7SY8K4.mjs +47 -0
- package/dist/dist-BkJUoBiG.mjs +1116 -0
- package/dist/dist-CUK7yBM0.mjs +308 -0
- package/dist/env-91KwMKov.mjs +140 -0
- package/dist/env.handler-BAzBuMzQ.mjs +277 -0
- package/dist/error-boundary-VL-JLfIa.mjs +34 -0
- package/dist/file-metadata-D1vm-XY2.mjs +191 -0
- package/dist/get-intrinsic-zLxwtrLK.mjs +658 -0
- package/dist/import-module-CV84H5fZ-B_CBCmb4.mjs +1747 -0
- package/dist/init-DpMCotSK.mjs +45 -0
- package/dist/init.handler-CPRnif52.mjs +585 -0
- package/dist/inspect.handler-DT_cD036.mjs +146 -0
- package/dist/integration-catalog-Bt-L3GjF.mjs +104 -0
- package/dist/integrations-DlatPK4W.mjs +79 -0
- package/dist/keystroke.d.mts +3 -0
- package/dist/keystroke.mjs +707 -0
- package/dist/layout-CbMtQ2tm.mjs +67 -0
- package/dist/list-enrichment-y-cwizLr.mjs +189 -0
- package/dist/list.handler-BTWvCyjA.mjs +52 -0
- package/dist/list.handler-CWF_Dj15.mjs +24 -0
- package/dist/list.handler-CZ6G2x_G.mjs +75 -0
- package/dist/list.handler-DWaQkJaR.mjs +51 -0
- package/dist/list.handler-DqbFcBW7.mjs +180 -0
- package/dist/list.handler-lq3ZGAn4.mjs +104 -0
- package/dist/logs-BEg9L5l8.mjs +28 -0
- package/dist/logs.handler-6hoMBzqw.mjs +35 -0
- package/dist/logs.handler-BD_dXiL1.mjs +231 -0
- package/dist/metadata-layout-GUYIUo0i-_aG2zjue.mjs +5877 -0
- package/dist/normalize-path-CojS-CgQ-DLCOvnD1.mjs +20 -0
- package/dist/options-CeaTcFxP.mjs +43 -0
- package/dist/org-xLzBtt2_.mjs +41 -0
- package/dist/output-DM4b7KgY.mjs +72 -0
- package/dist/oxc-B3KI3rf_-n9d1hKNq.mjs +119 -0
- package/dist/paused.handler-BMFm9Cff.mjs +94 -0
- package/dist/project-config-D1qsQlO7.mjs +107 -0
- package/dist/projects-CHkRE9rS.mjs +1574 -0
- package/dist/projects-Cjb7sovS.mjs +30 -0
- package/dist/read-credential-keys-77a91T8M-KA0Iw0Z1.mjs +9 -0
- package/dist/register.handler-BPCdor1_.mjs +86 -0
- package/dist/requirements.handler-DPXdSks3.mjs +201 -0
- package/dist/resolve-project-DDJ29sCF.mjs +35 -0
- package/dist/rolldown-runtime-twds-ZHy-BWWzu8VG.mjs +15 -0
- package/dist/run-polling-CAgFRdK3.mjs +20 -0
- package/dist/runs-D9hNLb9A.mjs +259 -0
- package/dist/schedule-BXx3uXwr.mjs +1142 -0
- package/dist/schema-17qMfNyI.mjs +18 -0
- package/dist/schema-display-CgmeKigW.mjs +130 -0
- package/dist/schemas-CDib1RhE.mjs +125 -0
- package/dist/skills-sync.handler-DIy8GR16.mjs +34 -0
- package/dist/skills.command-CrjI2dN9.mjs +35 -0
- package/dist/skills.handler-Bz8bJKql.mjs +9 -0
- package/dist/source-analysis-Cj-ADyu--BJQcFPCG.mjs +144 -0
- package/dist/spinner-progress-DMVwgqO9.mjs +173 -0
- package/dist/src-C0X6u_Mw.mjs +1340 -0
- package/dist/src-eHwu-Gfw.mjs +369 -0
- package/dist/status.handler-BO4nwvWn.mjs +101 -0
- package/dist/switch.handler-D_9213Vf.mjs +51 -0
- package/dist/sync-BL_Mo5st.mjs +39 -0
- package/dist/sync-keystroke-agent-skills-Kx_H7UTd.mjs +70 -0
- package/dist/sync.handler-BUFPdzWz.mjs +82 -0
- package/dist/task-B2sZMaZu.mjs +8 -0
- package/dist/task-target-build-CBeCKbu2.mjs +432 -0
- package/dist/task-target-deploy-C5X-USeR.mjs +4 -0
- package/dist/task-target-deploy-CA6elFpF-BEr4gkol.mjs +271 -0
- package/dist/task-target-deploy-runner.d.mts +3 -0
- package/dist/task-target-deploy-runner.mjs +202 -0
- package/dist/test-BHTgR3UA.mjs +698 -0
- package/dist/test.handler-BcPQ8b74.mjs +13 -0
- package/dist/trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs +239 -0
- package/dist/trigger-manifest-CY7brZeg.mjs +30 -0
- package/dist/try-deploy.handler-DqybNhXx.mjs +490 -0
- package/dist/upload-CkU--iDC.mjs +207 -0
- package/dist/upload.handler-DCtiznQp.mjs +441 -0
- package/dist/utils-CywxCDM7.mjs +14 -0
- package/dist/validate.handler-DOcTaJL0.mjs +280 -0
- package/dist/workflow-build-DBQaBfnn.mjs +1819 -0
- package/dist/workflow-bundler-BPiqVscj-X1PFFAuP.mjs +167 -0
- package/dist/workflows-g9z87AJJ.mjs +799 -0
- package/dist/writer-BG8poUm3-BbXlU2kI.mjs +426 -0
- package/package.json +87 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { i as logger } from "./keystroke.mjs";
|
|
4
|
+
import { n as formatProgressDuration, t as createSpinnerProgress } from "./spinner-progress-DMVwgqO9.mjs";
|
|
5
|
+
//#region src/lib/build-progress.ts
|
|
6
|
+
const NEW_STAGE_LABELS = {
|
|
7
|
+
start: "Starting build",
|
|
8
|
+
cached: "Using cached artifact",
|
|
9
|
+
success: "Complete",
|
|
10
|
+
failure: "Failed"
|
|
11
|
+
};
|
|
12
|
+
const PHASE_SCAN = "scan";
|
|
13
|
+
const PHASE_BUILD = "build";
|
|
14
|
+
const PHASE_OUTPUT = "output";
|
|
15
|
+
const PHASE_METADATA = "metadata";
|
|
16
|
+
function formatArtifactCount(count, kind) {
|
|
17
|
+
return `${count} ${kind}(s)`;
|
|
18
|
+
}
|
|
19
|
+
function formatArtifactSummaryCount(count, kind) {
|
|
20
|
+
return `${count} ${kind}${count === 1 ? "" : "s"}`;
|
|
21
|
+
}
|
|
22
|
+
function formatArtifactSummary(workflowCount, agentCount) {
|
|
23
|
+
const parts = [];
|
|
24
|
+
if (workflowCount > 0 || agentCount === 0) parts.push(formatArtifactSummaryCount(workflowCount, "workflow"));
|
|
25
|
+
if (agentCount > 0) parts.push(formatArtifactSummaryCount(agentCount, "agent"));
|
|
26
|
+
return parts.length > 1 ? `${parts.slice(0, -1).join(", ")} and ${parts.at(-1)}` : parts[0] ?? formatArtifactSummaryCount(0, "workflow");
|
|
27
|
+
}
|
|
28
|
+
function formatOutputCompleteLabel(event) {
|
|
29
|
+
const { writtenCount, skippedWriteCount } = event;
|
|
30
|
+
if (skippedWriteCount === void 0 || skippedWriteCount === 0) return writtenCount === 1 ? "Wrote 1 artifact" : `Wrote ${writtenCount} artifact(s)`;
|
|
31
|
+
return `Wrote ${writtenCount - skippedWriteCount} of ${writtenCount} artifact(s)\n${skippedWriteCount === 1 ? "1 unchanged on disk" : `${skippedWriteCount} unchanged on disk`}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Multi-line label: line 1 is short; following lines are dim detail (see spinner-worker).
|
|
35
|
+
* Avoids one huge truncated line in narrow terminals.
|
|
36
|
+
*/
|
|
37
|
+
function formatBuildCompleteLabel(event) {
|
|
38
|
+
const workflowTotal = event.workflowBuiltCount + event.cachedWorkflowCount;
|
|
39
|
+
const agentTotal = event.agentBuiltCount + event.cachedAgentCount;
|
|
40
|
+
const builtParts = [];
|
|
41
|
+
if (workflowTotal > 0 || agentTotal === 0) builtParts.push(formatArtifactCount(workflowTotal, "workflow"));
|
|
42
|
+
if (agentTotal > 0) builtParts.push(formatArtifactCount(agentTotal, "agent"));
|
|
43
|
+
const lines = [`Bundled ${builtParts.length > 1 ? `${builtParts.slice(0, -1).join(", ")} and ${builtParts.at(-1)}` : builtParts[0] ?? formatArtifactCount(0, "workflow")}`];
|
|
44
|
+
const hasTiming = event.cacheResolutionMs !== void 0 && event.bundlePipelineMs !== void 0;
|
|
45
|
+
if (event.cacheResolutionMs !== void 0 && event.bundlePipelineMs !== void 0) lines.push(`cache ${formatProgressDuration(event.cacheResolutionMs)} · bundle ${formatProgressDuration(event.bundlePipelineMs)}`);
|
|
46
|
+
const builtWf = event.workflowBuiltCount;
|
|
47
|
+
const builtAg = event.agentBuiltCount;
|
|
48
|
+
const cachedWf = event.cachedWorkflowCount;
|
|
49
|
+
const cachedAg = event.cachedAgentCount;
|
|
50
|
+
if (builtWf === 0 && builtAg === 0 && cachedWf + cachedAg > 0) {
|
|
51
|
+
if (!hasTiming) lines.push("all bundle cache hits");
|
|
52
|
+
} else if (cachedWf > 0 || cachedAg > 0) {
|
|
53
|
+
const fromCacheParts = [];
|
|
54
|
+
if (cachedWf > 0) fromCacheParts.push(`${cachedWf} workflow${cachedWf === 1 ? "" : "s"}`);
|
|
55
|
+
if (cachedAg > 0) fromCacheParts.push(`${cachedAg} agent${cachedAg === 1 ? "" : "s"}`);
|
|
56
|
+
const fromCacheStr = `from cache: ${fromCacheParts.join(", ")}`;
|
|
57
|
+
if (builtWf > 0 || builtAg > 0) {
|
|
58
|
+
const rebuiltParts = [];
|
|
59
|
+
if (builtWf > 0) rebuiltParts.push(`${builtWf} workflow${builtWf === 1 ? "" : "s"}`);
|
|
60
|
+
if (builtAg > 0) rebuiltParts.push(`${builtAg} agent${builtAg === 1 ? "" : "s"}`);
|
|
61
|
+
lines.push(`${fromCacheStr} · rebuilt: ${rebuiltParts.join(", ")}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return lines.join("\n");
|
|
65
|
+
}
|
|
66
|
+
function formatDiscoveryStartLabel(filesTotal) {
|
|
67
|
+
return filesTotal === 1 ? "Scanning 1 file for workflows and agents..." : `Scanning ${filesTotal} files for workflows and agents...`;
|
|
68
|
+
}
|
|
69
|
+
function formatDiscoveryScanLabel(filesScanned, filesTotal) {
|
|
70
|
+
return `Scanning files for workflows and agents... (${filesScanned}/${filesTotal})`;
|
|
71
|
+
}
|
|
72
|
+
function formatDiscoveryCompleteLabel(workflowCount, agentCount, filesScanned) {
|
|
73
|
+
return `Found ${formatArtifactSummary(workflowCount, agentCount)} in ${filesScanned} file(s)`;
|
|
74
|
+
}
|
|
75
|
+
function formatBuildStartLabel(workflowName, workflowCount, agentCount) {
|
|
76
|
+
return workflowCount === 1 && agentCount === 0 ? `Building "${workflowName}"...` : `Building ${formatArtifactSummary(workflowCount, agentCount)}...`;
|
|
77
|
+
}
|
|
78
|
+
function formatMetadataStartLabel(fileCount) {
|
|
79
|
+
if (fileCount === 0) return "Discovering metadata files...";
|
|
80
|
+
if (fileCount === 1) return "Generating metadata for 1 file...";
|
|
81
|
+
return `Generating metadata for ${fileCount} file(s)...`;
|
|
82
|
+
}
|
|
83
|
+
function createBuildProgress(workflowName) {
|
|
84
|
+
logger.info(`[build] Starting: "${workflowName}"`);
|
|
85
|
+
const spinner = createSpinnerProgress("[build]");
|
|
86
|
+
let buildStartTime;
|
|
87
|
+
function getStageLabel(stage) {
|
|
88
|
+
return NEW_STAGE_LABELS[stage];
|
|
89
|
+
}
|
|
90
|
+
function getFailureMessage(event) {
|
|
91
|
+
let message = "Build failed";
|
|
92
|
+
if ("failure" in event) message = event.failure.error;
|
|
93
|
+
else if ("error" in event && typeof event.error === "string" && event.error.length > 0) message = event.error;
|
|
94
|
+
const firstLine = message.split("\n")[0] ?? message;
|
|
95
|
+
return firstLine.length > 120 ? `${firstLine.slice(0, 120)}…` : firstLine;
|
|
96
|
+
}
|
|
97
|
+
spinner.addPendingPhase(PHASE_SCAN, "Scan workflows and agents");
|
|
98
|
+
spinner.addPendingPhase(PHASE_BUILD, "Build workflows and agents");
|
|
99
|
+
spinner.addPendingPhase(PHASE_OUTPUT, "Write build output");
|
|
100
|
+
spinner.addPendingPhase(PHASE_METADATA, "File metadata");
|
|
101
|
+
function handleWorkflowStage(event) {
|
|
102
|
+
const { stage, workflowIndex, workflowCount } = event;
|
|
103
|
+
if (stage === "start") {
|
|
104
|
+
logger.info(`[build] → workflow ${workflowIndex}/${workflowCount}: ${stage}`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (stage === "cached" || stage === "success") {
|
|
108
|
+
logger.info(`[build] ✓ workflow ${workflowIndex}/${workflowCount} ${stage === "cached" ? "cached" : "succeeded"} (${formatProgressDuration(event.elapsedMs)})`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (stage === "failure") {
|
|
112
|
+
spinner.failPhase(PHASE_BUILD, "Build failed", event.elapsedMs, getFailureMessage(event));
|
|
113
|
+
logger.info(`[build] ✗ workflow ${workflowIndex}/${workflowCount} failed: ${getFailureMessage(event)}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
spinner.updatePhase(PHASE_BUILD, getStageLabel(stage));
|
|
117
|
+
}
|
|
118
|
+
function handleEvent(event) {
|
|
119
|
+
switch (event.phase) {
|
|
120
|
+
case "discovery-start":
|
|
121
|
+
spinner.startPhase(PHASE_SCAN, formatDiscoveryStartLabel(event.filesTotal));
|
|
122
|
+
return;
|
|
123
|
+
case "discovery-scan":
|
|
124
|
+
spinner.updatePhase(PHASE_SCAN, formatDiscoveryScanLabel(event.filesScanned, event.filesTotal));
|
|
125
|
+
return;
|
|
126
|
+
case "discovery-complete":
|
|
127
|
+
spinner.completePhase(PHASE_SCAN, formatDiscoveryCompleteLabel(event.workflowCount, event.agentCount, event.filesScanned), event.elapsedMs);
|
|
128
|
+
return;
|
|
129
|
+
case "cache-stats":
|
|
130
|
+
logger.info(`[build] cache stats: cacheHits=${event.cacheHits}, cacheMisses=${event.cacheMisses}, invalidated=${event.invalidated}`);
|
|
131
|
+
return;
|
|
132
|
+
case "build-start":
|
|
133
|
+
buildStartTime = Date.now();
|
|
134
|
+
spinner.startPhase(PHASE_BUILD, formatBuildStartLabel(workflowName, event.workflowCount, event.agentCount));
|
|
135
|
+
return;
|
|
136
|
+
case "workflow-stage":
|
|
137
|
+
handleWorkflowStage(event);
|
|
138
|
+
return;
|
|
139
|
+
case "build-complete":
|
|
140
|
+
if (buildStartTime !== void 0 && event.failedCount === 0) spinner.completePhase(PHASE_BUILD, formatBuildCompleteLabel(event), event.elapsedMs);
|
|
141
|
+
return;
|
|
142
|
+
case "duplicate-id-conflict":
|
|
143
|
+
logger.info(`[build] duplicate workflow id conflict: ${event.workflowId} (${event.files.join(", ")})`);
|
|
144
|
+
return;
|
|
145
|
+
case "output-start":
|
|
146
|
+
spinner.startPhase(PHASE_OUTPUT, event.artifactCount === 1 ? "Writing 1 artifact to disk..." : `Writing ${event.artifactCount} artifact(s) to disk...`);
|
|
147
|
+
return;
|
|
148
|
+
case "output-complete":
|
|
149
|
+
spinner.completePhase(PHASE_OUTPUT, formatOutputCompleteLabel(event), event.elapsedMs);
|
|
150
|
+
return;
|
|
151
|
+
case "metadata-start":
|
|
152
|
+
spinner.startPhase(PHASE_METADATA, formatMetadataStartLabel(event.fileCount));
|
|
153
|
+
return;
|
|
154
|
+
case "metadata-scan":
|
|
155
|
+
spinner.updatePhase(PHASE_METADATA, `Generating metadata... (${event.filesProcessed}/${event.filesTotal})`);
|
|
156
|
+
return;
|
|
157
|
+
case "metadata-cache-stats":
|
|
158
|
+
spinner.updatePhase(PHASE_METADATA, "Merging metadata...");
|
|
159
|
+
logger.info(`[build] metadata cache stats: cacheHits=${event.cacheHits}, cacheMisses=${event.cacheMisses}, invalidated=${event.invalidated}`);
|
|
160
|
+
return;
|
|
161
|
+
case "metadata-complete":
|
|
162
|
+
spinner.completePhase(PHASE_METADATA, `Generated metadata for ${event.fileCount} file(s)`, event.elapsedMs);
|
|
163
|
+
return;
|
|
164
|
+
case "metadata-output-complete":
|
|
165
|
+
logger.info(`[build] metadata output: written=${event.writtenCount}, cleaned=${event.cleanedCount} (${formatProgressDuration(event.elapsedMs)})`);
|
|
166
|
+
return;
|
|
167
|
+
case "convention-errors":
|
|
168
|
+
spinner.failPhase(PHASE_METADATA, `${event.errorCount} file convention error(s)`, 0);
|
|
169
|
+
return;
|
|
170
|
+
case "complete": return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function stop() {
|
|
174
|
+
if (spinner.isRunning()) logger.info(`[build] stopped (phase: "${spinner.currentLabel()}")`);
|
|
175
|
+
spinner.stop();
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
handleEvent,
|
|
179
|
+
stop
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
export { createBuildProgress as t };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { t as TaskBuildManifestSchema } from "./schemas-CDib1RhE.mjs";
|
|
4
|
+
import "./task-B2sZMaZu.mjs";
|
|
5
|
+
import { n as bundleWorkflowTarget } from "./workflow-bundler-BPiqVscj-X1PFFAuP.mjs";
|
|
6
|
+
import { t as buildTriggerArtifacts } from "./trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs";
|
|
7
|
+
import { performance } from "node:perf_hooks";
|
|
8
|
+
//#region ../../packages/workflow-builder/dist/build-tasks-CdihpudT.mjs
|
|
9
|
+
async function buildTaskArtifact(options) {
|
|
10
|
+
const { discoveredWorkflow, taskMetadata, projectRoot } = options;
|
|
11
|
+
const totalStartedAt = performance.now();
|
|
12
|
+
const bundle = await bundleWorkflowTarget({
|
|
13
|
+
filePath: discoveredWorkflow.resolvedFilePath,
|
|
14
|
+
localExportName: discoveredWorkflow.localExportName,
|
|
15
|
+
projectRoot,
|
|
16
|
+
sourceMap: options.sourceMaps
|
|
17
|
+
});
|
|
18
|
+
const bundleMs = performance.now() - totalStartedAt - taskMetadata.timing.importMs;
|
|
19
|
+
const manifestData = TaskBuildManifestSchema.parse(taskMetadata.manifest);
|
|
20
|
+
const triggerStartedAt = performance.now();
|
|
21
|
+
const triggerResult = await buildTriggerArtifacts(taskMetadata.triggers, manifestData.id, manifestData.name, projectRoot, {
|
|
22
|
+
workflowExportName: discoveredWorkflow.localExportName,
|
|
23
|
+
workflowFilePath: discoveredWorkflow.resolvedFilePath
|
|
24
|
+
});
|
|
25
|
+
const triggerMs = performance.now() - triggerStartedAt;
|
|
26
|
+
return {
|
|
27
|
+
artifact: {
|
|
28
|
+
task: {
|
|
29
|
+
bindingKey: discoveredWorkflow.bindingKey,
|
|
30
|
+
exportFilePath: discoveredWorkflow.exportFilePath,
|
|
31
|
+
resolvedFilePath: discoveredWorkflow.resolvedFilePath,
|
|
32
|
+
exportName: discoveredWorkflow.exportName,
|
|
33
|
+
localExportName: discoveredWorkflow.localExportName,
|
|
34
|
+
taskId: manifestData.id,
|
|
35
|
+
taskName: manifestData.name
|
|
36
|
+
},
|
|
37
|
+
manifest: manifestData,
|
|
38
|
+
bundle: {
|
|
39
|
+
code: bundle.code,
|
|
40
|
+
sourceMap: bundle.sourceMap,
|
|
41
|
+
localDependencies: bundle.localDependencies,
|
|
42
|
+
externalImports: bundle.externalImports,
|
|
43
|
+
size: bundle.size
|
|
44
|
+
},
|
|
45
|
+
triggers: triggerResult.artifacts,
|
|
46
|
+
timing: {
|
|
47
|
+
importMs: taskMetadata.timing.importMs,
|
|
48
|
+
manifestMs: taskMetadata.timing.manifestMs,
|
|
49
|
+
bundleMs,
|
|
50
|
+
triggerMs,
|
|
51
|
+
totalMs: performance.now() - totalStartedAt
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
triggerFailures: triggerResult.failures
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function buildTaskArtifacts(options) {
|
|
58
|
+
const taskArtifacts = [];
|
|
59
|
+
const failures = [];
|
|
60
|
+
for (const entry of options.entries) try {
|
|
61
|
+
const result = await buildTaskArtifact({
|
|
62
|
+
discoveredWorkflow: entry.discoveredWorkflow,
|
|
63
|
+
taskMetadata: entry.taskMetadata,
|
|
64
|
+
projectRoot: options.projectRoot,
|
|
65
|
+
sourceMaps: options.sourceMaps
|
|
66
|
+
});
|
|
67
|
+
taskArtifacts.push(result.artifact);
|
|
68
|
+
failures.push(...result.triggerFailures);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
failures.push({
|
|
71
|
+
kind: "task",
|
|
72
|
+
task: {
|
|
73
|
+
bindingKey: entry.discoveredWorkflow.bindingKey,
|
|
74
|
+
exportFilePath: entry.discoveredWorkflow.exportFilePath,
|
|
75
|
+
resolvedFilePath: entry.discoveredWorkflow.resolvedFilePath,
|
|
76
|
+
exportName: entry.discoveredWorkflow.exportName,
|
|
77
|
+
localExportName: entry.discoveredWorkflow.localExportName,
|
|
78
|
+
taskId: entry.discoveredWorkflow.exportName,
|
|
79
|
+
taskName: entry.discoveredWorkflow.exportName
|
|
80
|
+
},
|
|
81
|
+
phase: "bundle",
|
|
82
|
+
error: `Task bundle failed: ${error instanceof Error ? error.message : String(error)}`
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
taskArtifacts,
|
|
87
|
+
failures
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { buildTaskArtifacts };
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { _ as deduplicateCredentialRequirementEntries } from "./schedule-BXx3uXwr.mjs";
|
|
4
|
+
import { i as WORKFLOW_MANIFEST_GENERATOR, s as WorkflowManifestSchema } from "./_manifest-JSRE3H8k.mjs";
|
|
5
|
+
import { a as MANIFEST_FILE_NAME, i as FLOW_FILE_NAME, r as BUNDLE_FILE_NAME, s as SOURCE_MAP_FILE_NAME, t as BUILD_DIR_NAME } from "./layout-CbMtQ2tm.mjs";
|
|
6
|
+
import { t as runWithConcurrency } from "./concurrency-gXn9Rw8x-DNl2YtrS.mjs";
|
|
7
|
+
import { n as WorkflowLoaderProtocolError, r as WorkflowMetadataLoadError, s as createLoaderProtocolFailure } from "./import-module-CV84H5fZ-B_CBCmb4.mjs";
|
|
8
|
+
import { r as toRelativeFilePath } from "./normalize-path-CojS-CgQ-DLCOvnD1.mjs";
|
|
9
|
+
import { n as bundleWorkflowTarget } from "./workflow-bundler-BPiqVscj-X1PFFAuP.mjs";
|
|
10
|
+
import { t as buildTriggerArtifacts } from "./trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs";
|
|
11
|
+
import { realpathSync } from "node:fs";
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import * as path$1 from "node:path";
|
|
14
|
+
import { createHash } from "node:crypto";
|
|
15
|
+
import { performance } from "node:perf_hooks";
|
|
16
|
+
//#region ../../packages/workflow-builder/dist/build-workflows-CfxBnIWh.mjs
|
|
17
|
+
/**
|
|
18
|
+
* Resolves and categorizes all dependencies for a workflow manifest.
|
|
19
|
+
* - Local files: relative paths with SHA256 content hashes
|
|
20
|
+
* - npm packages: package name -> declared version
|
|
21
|
+
* - Workspace packages: @keystroke/* -> version specifier
|
|
22
|
+
* - Builtins: node:* specifiers
|
|
23
|
+
*/
|
|
24
|
+
async function resolveDependencies(options) {
|
|
25
|
+
const { projectRoot, localDependencies, externalImports } = options;
|
|
26
|
+
const localFiles = {};
|
|
27
|
+
await Promise.all(localDependencies.map(async (absPath) => {
|
|
28
|
+
const relPath = path$1.relative(projectRoot, absPath);
|
|
29
|
+
try {
|
|
30
|
+
const content = await readFile(absPath);
|
|
31
|
+
localFiles[relPath] = createHash("sha256").update(content).digest("hex");
|
|
32
|
+
} catch {
|
|
33
|
+
localFiles[relPath] = "unknown";
|
|
34
|
+
}
|
|
35
|
+
}));
|
|
36
|
+
const builtins = [];
|
|
37
|
+
const packageSpecifiers = [];
|
|
38
|
+
for (const specifier of externalImports) if (specifier.startsWith("node:")) builtins.push(specifier);
|
|
39
|
+
else packageSpecifiers.push(specifier);
|
|
40
|
+
const packageVersions = options.packageVersionCache ?? await readPackageVersions(projectRoot);
|
|
41
|
+
const packages = {};
|
|
42
|
+
const workspacePackages = {};
|
|
43
|
+
for (const specifier of packageSpecifiers) {
|
|
44
|
+
const packageName = extractPackageName(specifier);
|
|
45
|
+
const version = packageVersions.get(packageName);
|
|
46
|
+
if (specifier.startsWith("@keystroke/")) workspacePackages[packageName] = version ?? "workspace:*";
|
|
47
|
+
else packages[packageName] = version ?? "unknown";
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
localFiles: sortRecord(localFiles),
|
|
51
|
+
packages: sortRecord(packages),
|
|
52
|
+
workspacePackages: sortRecord(workspacePackages),
|
|
53
|
+
builtins: builtins.sort()
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Extracts the npm package name from a module specifier.
|
|
58
|
+
* Handles scoped packages: `@scope/pkg/subpath` -> `@scope/pkg`
|
|
59
|
+
* Handles regular packages: `lodash/fp` -> `lodash`
|
|
60
|
+
*/
|
|
61
|
+
function extractPackageName(specifier) {
|
|
62
|
+
if (specifier.startsWith("@")) {
|
|
63
|
+
const [scope, name] = specifier.split("/");
|
|
64
|
+
if (scope && name) return `${scope}/${name}`;
|
|
65
|
+
return specifier;
|
|
66
|
+
}
|
|
67
|
+
const [name] = specifier.split("/");
|
|
68
|
+
return name ?? specifier;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reads package.json files starting from projectRoot and walking up to find
|
|
72
|
+
* all declared dependency versions. Merges dependencies and devDependencies.
|
|
73
|
+
*/
|
|
74
|
+
async function readPackageVersions(projectRoot) {
|
|
75
|
+
const versions = /* @__PURE__ */ new Map();
|
|
76
|
+
let currentDir = path$1.resolve(projectRoot);
|
|
77
|
+
while (true) {
|
|
78
|
+
const candidate = path$1.join(currentDir, "package.json");
|
|
79
|
+
try {
|
|
80
|
+
const content = await readFile(candidate, "utf8");
|
|
81
|
+
const pkg = JSON.parse(content);
|
|
82
|
+
if (pkg.dependencies) {
|
|
83
|
+
for (const [name, version] of Object.entries(pkg.dependencies)) if (!versions.has(name)) versions.set(name, version);
|
|
84
|
+
}
|
|
85
|
+
if (pkg.devDependencies) {
|
|
86
|
+
for (const [name, version] of Object.entries(pkg.devDependencies)) if (!versions.has(name)) versions.set(name, version);
|
|
87
|
+
}
|
|
88
|
+
} catch {}
|
|
89
|
+
const parentDir = path$1.dirname(currentDir);
|
|
90
|
+
if (parentDir === currentDir) break;
|
|
91
|
+
currentDir = parentDir;
|
|
92
|
+
}
|
|
93
|
+
return versions;
|
|
94
|
+
}
|
|
95
|
+
function sortRecord(record) {
|
|
96
|
+
return Object.fromEntries(Object.entries(record).sort(([a], [b]) => a.localeCompare(b)));
|
|
97
|
+
}
|
|
98
|
+
function resolveBundleConcurrencyLimit() {
|
|
99
|
+
const raw = process.env.KEYSTROKE_WORKFLOW_BUNDLE_CONCURRENCY?.trim();
|
|
100
|
+
if (!raw) return Number.POSITIVE_INFINITY;
|
|
101
|
+
const parsed = Number.parseInt(raw, 10);
|
|
102
|
+
if (!Number.isFinite(parsed) || parsed < 1) return Number.POSITIVE_INFINITY;
|
|
103
|
+
return parsed;
|
|
104
|
+
}
|
|
105
|
+
function createWorkflowMetadataFailure(discoveredWorkflow, error) {
|
|
106
|
+
const message = error instanceof Error ? error.message : "No metadata loaded";
|
|
107
|
+
return error instanceof WorkflowMetadataLoadError ? {
|
|
108
|
+
kind: "workflow",
|
|
109
|
+
workflow: discoveredWorkflow,
|
|
110
|
+
phase: error.phase,
|
|
111
|
+
error: message
|
|
112
|
+
} : error instanceof WorkflowLoaderProtocolError ? createLoaderProtocolFailure(discoveredWorkflow, error.source, message, error.rawOutput) : {
|
|
113
|
+
kind: "workflow",
|
|
114
|
+
workflow: discoveredWorkflow,
|
|
115
|
+
phase: "import",
|
|
116
|
+
error: message
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async function buildWorkflowArtifacts(options) {
|
|
120
|
+
const artifacts = [];
|
|
121
|
+
const failures = [];
|
|
122
|
+
const warnings = [];
|
|
123
|
+
const packageVersionCache = await readPackageVersions(options.projectRoot);
|
|
124
|
+
const workflowDelegateRegistry = buildWorkflowDelegateRegistry({
|
|
125
|
+
workflowsByKey: options.workflowsByKey,
|
|
126
|
+
metadataByKey: options.metadataByKey
|
|
127
|
+
});
|
|
128
|
+
const bundleJobs = options.entries.map((entry) => async () => {
|
|
129
|
+
const { discoveredWorkflow, metadata, workflowIndex } = entry;
|
|
130
|
+
const totalStartedAt = performance.now();
|
|
131
|
+
options.onProgressEvent?.({
|
|
132
|
+
phase: "workflow-stage",
|
|
133
|
+
stage: "start",
|
|
134
|
+
workflow: discoveredWorkflow,
|
|
135
|
+
workflowIndex,
|
|
136
|
+
workflowCount: options.workflowCount,
|
|
137
|
+
elapsedMs: 0
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
const { manifest: loadedManifest, flowGraph, triggers: sameFileTriggers, credentialsByCallsiteFingerprint, credentialAttributionWarnings, timing } = metadata;
|
|
141
|
+
const nestingErrors = flowGraph.diagnostics?.filter((d) => d.startsWith("[nesting-error]"));
|
|
142
|
+
if (nestingErrors && nestingErrors.length > 0) {
|
|
143
|
+
for (const nestingError of nestingErrors) failures.push({
|
|
144
|
+
kind: "workflow",
|
|
145
|
+
workflow: discoveredWorkflow,
|
|
146
|
+
phase: "flow-graph",
|
|
147
|
+
error: nestingError.replace("[nesting-error] ", "")
|
|
148
|
+
});
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
warnings.push(...credentialAttributionWarnings.map((warning) => `${discoveredWorkflow.resolvedFilePath}: [${warning.category}] Could not match declared credential requirements for "${warning.bindingName}" (${warning.credentialSetIds.join(", ")}) to a static callsite fingerprint.`));
|
|
152
|
+
const bundle = await bundleWorkflowTarget({
|
|
153
|
+
filePath: discoveredWorkflow.resolvedFilePath,
|
|
154
|
+
localExportName: discoveredWorkflow.localExportName,
|
|
155
|
+
projectRoot: options.projectRoot,
|
|
156
|
+
delegateRegistry: workflowDelegateRegistry,
|
|
157
|
+
sourceMap: options.sourceMaps
|
|
158
|
+
});
|
|
159
|
+
const bundleMs = performance.now() - totalStartedAt - timing.importMs;
|
|
160
|
+
const manifest = await finalizeWorkflowManifest({
|
|
161
|
+
coreManifest: loadedManifest,
|
|
162
|
+
flowGraph,
|
|
163
|
+
exportName: discoveredWorkflow.exportName,
|
|
164
|
+
workflowFilePath: discoveredWorkflow.resolvedFilePath,
|
|
165
|
+
bundle,
|
|
166
|
+
credentialsByCallsiteFingerprint,
|
|
167
|
+
projectRoot: options.projectRoot,
|
|
168
|
+
packageVersionCache
|
|
169
|
+
});
|
|
170
|
+
const triggerStartedAt = performance.now();
|
|
171
|
+
const triggerResult = await buildTriggerArtifacts(sameFileTriggers, manifest.id, manifest.name, options.projectRoot, {
|
|
172
|
+
workflowExportName: discoveredWorkflow.localExportName,
|
|
173
|
+
workflowFilePath: discoveredWorkflow.resolvedFilePath
|
|
174
|
+
});
|
|
175
|
+
failures.push(...triggerResult.failures);
|
|
176
|
+
const triggerMs = performance.now() - triggerStartedAt;
|
|
177
|
+
const artifact = {
|
|
178
|
+
workflow: {
|
|
179
|
+
...discoveredWorkflow,
|
|
180
|
+
workflowId: manifest.id
|
|
181
|
+
},
|
|
182
|
+
manifest,
|
|
183
|
+
flowGraph,
|
|
184
|
+
bundle,
|
|
185
|
+
triggers: triggerResult.artifacts,
|
|
186
|
+
timing: {
|
|
187
|
+
importMs: timing.importMs,
|
|
188
|
+
manifestMs: timing.manifestMs,
|
|
189
|
+
flowGraphMs: timing.flowGraphMs,
|
|
190
|
+
bundleMs,
|
|
191
|
+
triggerMs,
|
|
192
|
+
totalMs: performance.now() - totalStartedAt
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
artifacts.push(artifact);
|
|
196
|
+
options.onProgressEvent?.({
|
|
197
|
+
phase: "workflow-stage",
|
|
198
|
+
stage: "success",
|
|
199
|
+
workflow: artifact.workflow,
|
|
200
|
+
workflowIndex,
|
|
201
|
+
workflowCount: options.workflowCount,
|
|
202
|
+
elapsedMs: artifact.timing.totalMs
|
|
203
|
+
});
|
|
204
|
+
} catch (error) {
|
|
205
|
+
const failure = {
|
|
206
|
+
kind: "workflow",
|
|
207
|
+
workflow: discoveredWorkflow,
|
|
208
|
+
phase: "bundle",
|
|
209
|
+
error: error instanceof Error ? error.message : String(error)
|
|
210
|
+
};
|
|
211
|
+
failures.push(failure);
|
|
212
|
+
options.onProgressEvent?.({
|
|
213
|
+
phase: "workflow-stage",
|
|
214
|
+
stage: "failure",
|
|
215
|
+
workflow: discoveredWorkflow,
|
|
216
|
+
workflowIndex,
|
|
217
|
+
workflowCount: options.workflowCount,
|
|
218
|
+
elapsedMs: 0,
|
|
219
|
+
failure
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const bundleLimit = resolveBundleConcurrencyLimit();
|
|
224
|
+
const effectiveBundleConcurrency = Number.isFinite(bundleLimit) ? Math.min(bundleLimit, bundleJobs.length) : bundleJobs.length;
|
|
225
|
+
await runWithConcurrency(bundleJobs, Math.max(1, effectiveBundleConcurrency), (job) => job());
|
|
226
|
+
return {
|
|
227
|
+
artifacts,
|
|
228
|
+
failures,
|
|
229
|
+
warnings
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/** @internal Exported for tests. */
|
|
233
|
+
function buildCredentialRequirements(flowGraph, credentialsByCallsiteFingerprint) {
|
|
234
|
+
const byStep = {};
|
|
235
|
+
const allCredentialSetIds = /* @__PURE__ */ new Set();
|
|
236
|
+
const toCredentialRequirementEntries = (entries) => entries.map((entry) => ({
|
|
237
|
+
credentialSetId: entry.resolvedCredentialSetId,
|
|
238
|
+
credentialKeys: entry.credentialKeys,
|
|
239
|
+
...entry.optionalCredentialKeys && entry.optionalCredentialKeys.length > 0 ? { optionalCredentialKeys: entry.optionalCredentialKeys } : {},
|
|
240
|
+
...entry.storedCredentialKeys && entry.storedCredentialKeys.length > 0 ? { storedCredentialKeys: entry.storedCredentialKeys } : {},
|
|
241
|
+
...entry.optionalStoredCredentialKeys && entry.optionalStoredCredentialKeys.length > 0 ? { optionalStoredCredentialKeys: entry.optionalStoredCredentialKeys } : {},
|
|
242
|
+
...entry.schemaFingerprint ? { schemaFingerprint: entry.schemaFingerprint } : {},
|
|
243
|
+
...entry.proxy ? { proxy: entry.proxy } : {},
|
|
244
|
+
...entry.needsRawSecret === true ? { needsRawSecret: true } : {},
|
|
245
|
+
...entry.needsResolve === true ? { needsResolve: true } : {},
|
|
246
|
+
...typeof entry.resolveCacheMs === "number" && entry.resolveCacheMs > 0 ? { resolveCacheMs: entry.resolveCacheMs } : {},
|
|
247
|
+
...entry.onCredentialRevoked ? { onCredentialRevoked: entry.onCredentialRevoked } : {},
|
|
248
|
+
...entry.requiredOAuthScopes?.length ? { requiredOAuthScopes: entry.requiredOAuthScopes } : {}
|
|
249
|
+
}));
|
|
250
|
+
for (const node of flowGraph.nodes) {
|
|
251
|
+
if (node.type !== "step" || node.data.kind !== "call") continue;
|
|
252
|
+
const operationScopes = "requiredOAuthScopes" in node.data && node.data.requiredOAuthScopes?.length ? node.data.requiredOAuthScopes : void 0;
|
|
253
|
+
const nodeEntries = node.data.credentialSets?.map((entry) => ({
|
|
254
|
+
credentialSetId: entry.resolvedId,
|
|
255
|
+
credentialKeys: entry.credentialKeys,
|
|
256
|
+
...entry.optionalCredentialKeys && entry.optionalCredentialKeys.length > 0 ? { optionalCredentialKeys: entry.optionalCredentialKeys } : {},
|
|
257
|
+
...entry.storedCredentialKeys && entry.storedCredentialKeys.length > 0 ? { storedCredentialKeys: entry.storedCredentialKeys } : {},
|
|
258
|
+
...entry.optionalStoredCredentialKeys && entry.optionalStoredCredentialKeys.length > 0 ? { optionalStoredCredentialKeys: entry.optionalStoredCredentialKeys } : {},
|
|
259
|
+
...entry.schemaFingerprint ? { schemaFingerprint: entry.schemaFingerprint } : {},
|
|
260
|
+
...entry.proxy ? { proxy: entry.proxy } : {},
|
|
261
|
+
...entry.needsRawSecret === true ? { needsRawSecret: true } : {},
|
|
262
|
+
...entry.needsResolve === true ? { needsResolve: true } : {},
|
|
263
|
+
...typeof entry.resolveCacheMs === "number" && entry.resolveCacheMs > 0 ? { resolveCacheMs: entry.resolveCacheMs } : {},
|
|
264
|
+
...entry.onCredentialRevoked ? { onCredentialRevoked: entry.onCredentialRevoked } : {},
|
|
265
|
+
...operationScopes ? { requiredOAuthScopes: [...operationScopes] } : {}
|
|
266
|
+
})) ?? [];
|
|
267
|
+
const callsiteEntries = node.data.callsiteFingerprint ? toCredentialRequirementEntries(credentialsByCallsiteFingerprint[node.data.callsiteFingerprint] ?? []) : [];
|
|
268
|
+
const entries = deduplicateCredentialRequirementEntries([...nodeEntries, ...callsiteEntries]);
|
|
269
|
+
if (entries.length === 0) continue;
|
|
270
|
+
byStep[node.id] = entries;
|
|
271
|
+
for (const entry of entries) allCredentialSetIds.add(entry.credentialSetId);
|
|
272
|
+
}
|
|
273
|
+
if (allCredentialSetIds.size === 0) return void 0;
|
|
274
|
+
return {
|
|
275
|
+
required: [...allCredentialSetIds].sort(),
|
|
276
|
+
byStep
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function extractStepsFromFlowGraph(flowGraph) {
|
|
280
|
+
const steps = {};
|
|
281
|
+
for (const node of flowGraph.nodes) if (node.type === "step" && node.data.kind === "call") steps[node.id] = {
|
|
282
|
+
nodeId: node.id,
|
|
283
|
+
stepName: node.data.stepName,
|
|
284
|
+
label: node.label,
|
|
285
|
+
callKind: node.data.callKind,
|
|
286
|
+
...node.data.exportName ? { exportName: node.data.exportName } : {},
|
|
287
|
+
...node.data.stepId ? { stepId: node.data.stepId } : {},
|
|
288
|
+
...node.data.source ? { source: node.data.source } : {},
|
|
289
|
+
...node.data.astKind ? { astKind: node.data.astKind } : {},
|
|
290
|
+
...node.data.importSource ? { importSource: node.data.importSource } : {},
|
|
291
|
+
...node.data.outputBinding ? { outputBinding: node.data.outputBinding } : {},
|
|
292
|
+
...node.data.scopeOverride ? { scopeOverride: node.data.scopeOverride } : {},
|
|
293
|
+
...node.data.description ? { description: node.data.description } : {},
|
|
294
|
+
...node.data.inputSchema ? { inputSchema: node.data.inputSchema } : {},
|
|
295
|
+
...node.data.outputSchema ? { outputSchema: node.data.outputSchema } : {},
|
|
296
|
+
..."credentialSets" in node.data && node.data.credentialSets ? { credentialSets: node.data.credentialSets } : {}
|
|
297
|
+
};
|
|
298
|
+
return steps;
|
|
299
|
+
}
|
|
300
|
+
async function finalizeWorkflowManifest(options) {
|
|
301
|
+
const credentials = buildCredentialRequirements(options.flowGraph, options.credentialsByCallsiteFingerprint);
|
|
302
|
+
const workflowSourceFilePath = toRelativeFilePath(options.projectRoot, options.workflowFilePath);
|
|
303
|
+
const dependencies = await resolveDependencies({
|
|
304
|
+
projectRoot: options.projectRoot,
|
|
305
|
+
localDependencies: options.bundle.localDependencies,
|
|
306
|
+
externalImports: options.bundle.externalImports,
|
|
307
|
+
packageVersionCache: options.packageVersionCache
|
|
308
|
+
});
|
|
309
|
+
return WorkflowManifestSchema.parse({
|
|
310
|
+
...options.coreManifest,
|
|
311
|
+
exportName: options.exportName,
|
|
312
|
+
workflowSource: {
|
|
313
|
+
filePath: workflowSourceFilePath,
|
|
314
|
+
line: 1,
|
|
315
|
+
column: 1,
|
|
316
|
+
endLine: 1,
|
|
317
|
+
endColumn: 1,
|
|
318
|
+
synthetic: true
|
|
319
|
+
},
|
|
320
|
+
dependencies,
|
|
321
|
+
steps: extractStepsFromFlowGraph(options.flowGraph),
|
|
322
|
+
...credentials ? { credentials } : {},
|
|
323
|
+
buildInfo: {
|
|
324
|
+
...options.coreManifest.buildInfo,
|
|
325
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
326
|
+
builderVersion: "workflow-builder",
|
|
327
|
+
generatedBy: WORKFLOW_MANIFEST_GENERATOR,
|
|
328
|
+
nodeVersion: process.version,
|
|
329
|
+
platform: process.platform,
|
|
330
|
+
sourceChecksumAlgorithm: "sha256",
|
|
331
|
+
sourceChecksum: "0".repeat(64),
|
|
332
|
+
generatedFiles: [
|
|
333
|
+
MANIFEST_FILE_NAME,
|
|
334
|
+
FLOW_FILE_NAME,
|
|
335
|
+
`${BUILD_DIR_NAME}/${BUNDLE_FILE_NAME}`,
|
|
336
|
+
...options.bundle.sourceMap ? [`${BUILD_DIR_NAME}/${SOURCE_MAP_FILE_NAME}`] : []
|
|
337
|
+
]
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function buildWorkflowDelegateRegistry(options) {
|
|
342
|
+
const registry = {};
|
|
343
|
+
for (const [bindingKey, { workflow }] of options.workflowsByKey) {
|
|
344
|
+
const metadata = options.metadataByKey.get(bindingKey);
|
|
345
|
+
if (!metadata?.ok) continue;
|
|
346
|
+
const entry = "agentMetadata" in metadata ? {
|
|
347
|
+
exportName: workflow.localExportName,
|
|
348
|
+
kind: "agent",
|
|
349
|
+
authoredId: typeof metadata.agentMetadata.manifest.authoredAgentId === "string" ? metadata.agentMetadata.manifest.authoredAgentId : typeof metadata.agentMetadata.manifest.id === "string" ? metadata.agentMetadata.manifest.id : workflow.exportName,
|
|
350
|
+
displayName: typeof metadata.agentMetadata.manifest.name === "string" ? metadata.agentMetadata.manifest.name : workflow.exportName
|
|
351
|
+
} : "taskMetadata" in metadata ? {
|
|
352
|
+
exportName: workflow.localExportName,
|
|
353
|
+
kind: "task",
|
|
354
|
+
authoredId: metadata.taskMetadata.manifest.id,
|
|
355
|
+
displayName: metadata.taskMetadata.manifest.name
|
|
356
|
+
} : {
|
|
357
|
+
exportName: workflow.localExportName,
|
|
358
|
+
kind: "workflow",
|
|
359
|
+
authoredId: metadata.metadata.manifest.id,
|
|
360
|
+
displayName: metadata.metadata.manifest.name
|
|
361
|
+
};
|
|
362
|
+
const resolvedFilePath = realpathSync.native(workflow.resolvedFilePath);
|
|
363
|
+
const existing = registry[resolvedFilePath] ?? [];
|
|
364
|
+
existing.push(entry);
|
|
365
|
+
registry[resolvedFilePath] = existing;
|
|
366
|
+
}
|
|
367
|
+
return registry;
|
|
368
|
+
}
|
|
369
|
+
//#endregion
|
|
370
|
+
export { buildWorkflowArtifacts, createWorkflowMetadataFailure };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { C as CliExitError } from "./keystroke.mjs";
|
|
4
|
+
import { d as trackProject } from "./dist-CUK7yBM0.mjs";
|
|
5
|
+
import { t as requireWorkflowsDir } from "./resolve-project-DDJ29sCF.mjs";
|
|
6
|
+
import { a as runWorkflowBuild, i as renderBuildSummary, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-DBQaBfnn.mjs";
|
|
7
|
+
import { t as createBuildProgress } from "./build-progress-DgYKb4hB.mjs";
|
|
8
|
+
import { t as withErrorBoundary } from "./error-boundary-VL-JLfIa.mjs";
|
|
9
|
+
//#region src/commands/workflows/build.handler.ts
|
|
10
|
+
async function handleWorkflowsBuild(options, _ctx) {
|
|
11
|
+
return withErrorBoundary("Build", async () => {
|
|
12
|
+
const workflowsDir = await requireWorkflowsDir(options.path);
|
|
13
|
+
trackProject(workflowsDir);
|
|
14
|
+
renderBuildHeader(options.name);
|
|
15
|
+
const progress = createBuildProgress(options.name ?? "workflow");
|
|
16
|
+
try {
|
|
17
|
+
const { result, outDir } = await runWorkflowBuild({
|
|
18
|
+
workflowsDir,
|
|
19
|
+
verbose: options.verbose,
|
|
20
|
+
name: options.name,
|
|
21
|
+
force: options.force,
|
|
22
|
+
targetFiles: options.target,
|
|
23
|
+
...options.disableSourcemaps ? { sourceMaps: false } : {},
|
|
24
|
+
onProgressEvent: progress.handleEvent
|
|
25
|
+
});
|
|
26
|
+
renderBuildSummary(result, outDir);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
renderBuildFailure(error);
|
|
29
|
+
throw new CliExitError("Build failed");
|
|
30
|
+
} finally {
|
|
31
|
+
progress.stop();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { handleWorkflowsBuild };
|