@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,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { D as throwReportedCliExit, h as toErrorMessage, i as logger, t as ui } from "./keystroke.mjs";
|
|
4
|
+
import { d as trackProject } from "./dist-CUK7yBM0.mjs";
|
|
5
|
+
import { n as deployFromDir } from "./dist-BkJUoBiG.mjs";
|
|
6
|
+
import { t as requireWorkflowsDir } from "./resolve-project-DDJ29sCF.mjs";
|
|
7
|
+
import { a as runWorkflowBuild, n as renderBuildFailure, r as renderBuildHeader } from "./workflow-build-DBQaBfnn.mjs";
|
|
8
|
+
import { r as isLocalMode } from "./env-91KwMKov.mjs";
|
|
9
|
+
import { a as validateApiKey, i as requireClient } from "./context-T7HZuB97.mjs";
|
|
10
|
+
import { t as createBuildProgress } from "./build-progress-DgYKb4hB.mjs";
|
|
11
|
+
import { t as createDeployProgress } from "./deploy-progress-BmGUNFKg.mjs";
|
|
12
|
+
//#region src/commands/sync/sync.handler.ts
|
|
13
|
+
async function handleSync(options, ctx) {
|
|
14
|
+
try {
|
|
15
|
+
await runSingleSync(options, ctx);
|
|
16
|
+
if (!options.watch) return;
|
|
17
|
+
ui.hint("Watching for changes. Press Ctrl+C to stop.");
|
|
18
|
+
const keepAlive = setInterval(() => {}, 1e3);
|
|
19
|
+
await new Promise(() => keepAlive);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
const message = toErrorMessage(error);
|
|
22
|
+
logger.error("Sync error", { error: message });
|
|
23
|
+
ui.error(`Sync error: ${message}`);
|
|
24
|
+
throwReportedCliExit(`Sync error: ${message}`, { cause: error });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function runSingleSync(options, ctx) {
|
|
28
|
+
const workflowsDir = await requireWorkflowsDir();
|
|
29
|
+
trackProject(workflowsDir);
|
|
30
|
+
const client = requireClient(ctx);
|
|
31
|
+
await validateApiKey(client);
|
|
32
|
+
logger.info("Starting sync", {
|
|
33
|
+
workflowsDir,
|
|
34
|
+
force: options.force,
|
|
35
|
+
watch: options.watch
|
|
36
|
+
});
|
|
37
|
+
renderBuildHeader();
|
|
38
|
+
const buildProgress = createBuildProgress("workflow");
|
|
39
|
+
let outDir;
|
|
40
|
+
try {
|
|
41
|
+
outDir = (await runWorkflowBuild({
|
|
42
|
+
workflowsDir,
|
|
43
|
+
verbose: false,
|
|
44
|
+
force: options.force,
|
|
45
|
+
onProgressEvent: buildProgress.handleEvent
|
|
46
|
+
})).outDir;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
renderBuildFailure(error);
|
|
49
|
+
throwReportedCliExit("Build failed during sync.", { cause: error });
|
|
50
|
+
} finally {
|
|
51
|
+
buildProgress.stop();
|
|
52
|
+
}
|
|
53
|
+
const deployProgress = createDeployProgress();
|
|
54
|
+
try {
|
|
55
|
+
const result = await deployFromDir({
|
|
56
|
+
outDir,
|
|
57
|
+
workflowsDir,
|
|
58
|
+
client,
|
|
59
|
+
isLocalMode: isLocalMode(),
|
|
60
|
+
force: options.force,
|
|
61
|
+
onDeployProgressEvent: deployProgress.handleEvent
|
|
62
|
+
});
|
|
63
|
+
if (!result.success) {
|
|
64
|
+
ui.error("Sync failed during deploy.");
|
|
65
|
+
throwReportedCliExit("Sync failed during deploy.");
|
|
66
|
+
}
|
|
67
|
+
const deployedWorkflows = result.workflows.filter((workflow) => workflow.status === "deployed");
|
|
68
|
+
const deployedAgents = result.agents.filter((agent) => agent.status === "deployed");
|
|
69
|
+
if (deployedWorkflows.length === 0 && deployedAgents.length === 0) {
|
|
70
|
+
ui.success("Sync complete. All workflows and agents are up to date.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const parts = [];
|
|
74
|
+
if (deployedWorkflows.length > 0) parts.push(`${deployedWorkflows.length} workflow(s)`);
|
|
75
|
+
if (deployedAgents.length > 0) parts.push(`${deployedAgents.length} agent(s)`);
|
|
76
|
+
ui.success(`Sync complete. Deployed ${parts.join(" and ")}.`);
|
|
77
|
+
} finally {
|
|
78
|
+
deployProgress.stop();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { handleSync };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { n as __exportAll } from "./chunk-CH6r78ws.mjs";
|
|
4
|
+
import { t as TaskBuildManifestSchema } from "./schemas-CDib1RhE.mjs";
|
|
5
|
+
//#region ../../packages/workflow-core/src/task/index.ts
|
|
6
|
+
var task_exports = /* @__PURE__ */ __exportAll({ TaskBuildManifestSchema: () => TaskBuildManifestSchema });
|
|
7
|
+
//#endregion
|
|
8
|
+
export { task_exports as t };
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { t as readCredentialKeysFromSchemaObject } from "./read-credential-keys-77a91T8M-KA0Iw0Z1.mjs";
|
|
4
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
8
|
+
//#region ../../packages/workflow-builder/dist/builder-options-BT2McCyF.mjs
|
|
9
|
+
function createBuilderBundleOptions(options) {
|
|
10
|
+
return { sourceMaps: options.disableSourcemaps !== true };
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ../../packages/workflow-builder/dist/task-target-build.mjs
|
|
14
|
+
const TASK_METADATA_BUNDLE_EXTERNALS = [
|
|
15
|
+
/^node:/,
|
|
16
|
+
"@swc/core",
|
|
17
|
+
/^@swc\/core-/,
|
|
18
|
+
/^@swc\/wasm/,
|
|
19
|
+
"playwright-core",
|
|
20
|
+
/^@keystroke\//,
|
|
21
|
+
"zod"
|
|
22
|
+
];
|
|
23
|
+
async function buildTaskTargets(options) {
|
|
24
|
+
const builtTasks = await buildTaskTargetEntries(options);
|
|
25
|
+
const { preparedTasks, failures } = await prepareTaskTargetBuiltTasks({
|
|
26
|
+
builtTasks,
|
|
27
|
+
projectRoot: options.projectRoot,
|
|
28
|
+
retainBuiltTasks: options.retainBuiltTasks
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
builtTasks: options.retainBuiltTasks ? builtTasks : [],
|
|
32
|
+
preparedTasks,
|
|
33
|
+
failures
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async function buildTaskTargetEntries(options) {
|
|
37
|
+
const targetFiles = resolveTaskTargetFiles(options);
|
|
38
|
+
const bundleOptions = createBuilderBundleOptions(options);
|
|
39
|
+
const builtTasks = [];
|
|
40
|
+
for (const targetFile of targetFiles) {
|
|
41
|
+
const builtTargetTasks = await buildTaskTargetFile({
|
|
42
|
+
targetFile,
|
|
43
|
+
projectRoot: options.projectRoot,
|
|
44
|
+
sourceMaps: bundleOptions.sourceMaps
|
|
45
|
+
});
|
|
46
|
+
builtTasks.push(...builtTargetTasks);
|
|
47
|
+
}
|
|
48
|
+
return builtTasks;
|
|
49
|
+
}
|
|
50
|
+
async function prepareTaskTargetBuiltTasks(options) {
|
|
51
|
+
const failures = [];
|
|
52
|
+
for (const builtTask of options.builtTasks) failures.push(...await attachTaskTargetTriggers({
|
|
53
|
+
artifact: builtTask.artifact,
|
|
54
|
+
entry: builtTask.entry,
|
|
55
|
+
projectRoot: options.projectRoot
|
|
56
|
+
}));
|
|
57
|
+
const preparedTasks = failures.length === 0 ? await prepareTaskTargetOutput({ builtTasks: options.builtTasks }) : [];
|
|
58
|
+
if (!options.retainBuiltTasks) releaseBuiltTaskTargets(options.builtTasks);
|
|
59
|
+
return {
|
|
60
|
+
preparedTasks,
|
|
61
|
+
failures
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function resolveTaskTargetFiles(options) {
|
|
65
|
+
const projectRoot = path.resolve(options.projectRoot);
|
|
66
|
+
if (options.targetFiles.length === 0) throw new Error("Target-only task deploy requires at least one --target file.");
|
|
67
|
+
return [...new Set(options.targetFiles.map((targetFile) => path.resolve(path.isAbsolute(targetFile) ? targetFile : path.join(projectRoot, targetFile))))].sort((left, right) => left.localeCompare(right));
|
|
68
|
+
}
|
|
69
|
+
async function buildTaskTargetFile(options) {
|
|
70
|
+
const runtimeBundlePath = getTaskRuntimeBundlePath(options.projectRoot, { bindingKey: options.targetFile });
|
|
71
|
+
const bundle = await bundleTaskTargetModule({
|
|
72
|
+
filePath: options.targetFile,
|
|
73
|
+
projectRoot: options.projectRoot,
|
|
74
|
+
sourceMap: options.sourceMaps
|
|
75
|
+
});
|
|
76
|
+
await writeRuntimeBundle(runtimeBundlePath, bundle.code);
|
|
77
|
+
bundle.code = "";
|
|
78
|
+
const moduleUrl = pathToFileURL(runtimeBundlePath);
|
|
79
|
+
moduleUrl.searchParams.set("keystrokeTaskMetadata", randomUUID());
|
|
80
|
+
const importedModule = await import(moduleUrl.href);
|
|
81
|
+
const builtTasks = [];
|
|
82
|
+
for (const [moduleExportName, exportedValue] of Object.entries(importedModule).sort(([left], [right]) => left.localeCompare(right))) {
|
|
83
|
+
if (!isTaskLike(exportedValue)) continue;
|
|
84
|
+
const exportName = moduleExportName === "__default" ? "default" : moduleExportName;
|
|
85
|
+
const manifest = await tryParseTaskBuildManifest(exportedValue.toManifest());
|
|
86
|
+
if (!manifest) continue;
|
|
87
|
+
const source = createTaskTargetSource({
|
|
88
|
+
projectRoot: options.projectRoot,
|
|
89
|
+
targetFile: options.targetFile,
|
|
90
|
+
exportName,
|
|
91
|
+
localExportName: moduleExportName
|
|
92
|
+
});
|
|
93
|
+
const taskMetadata = {
|
|
94
|
+
manifest,
|
|
95
|
+
triggers: discoverTaskTriggers(exportedValue, importedModule, options.targetFile),
|
|
96
|
+
timing: {
|
|
97
|
+
importMs: 0,
|
|
98
|
+
manifestMs: 0
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
builtTasks.push(createBuiltTaskTarget({
|
|
102
|
+
source,
|
|
103
|
+
taskMetadata,
|
|
104
|
+
runtimeBundlePath,
|
|
105
|
+
bundle
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
if (builtTasks.length === 0) throw new Error(`No task exports were discovered for target ${options.targetFile}.`);
|
|
109
|
+
return builtTasks;
|
|
110
|
+
}
|
|
111
|
+
async function bundleTaskTargetModule(options) {
|
|
112
|
+
const [{ rolldown }, { createEnvAccessPlugin, formatEnvAccessError }] = await Promise.all([import("rolldown"), import("./detect-env-access-CwkOYeYM-D_BCZqV6.mjs").then((n) => n.n).then((n) => n.n)]);
|
|
113
|
+
const entryId = "\0virtual:task-target-entry";
|
|
114
|
+
const trackedDependencies = /* @__PURE__ */ new Set();
|
|
115
|
+
const envViolations = [];
|
|
116
|
+
const exportReference = [
|
|
117
|
+
`import * as __taskTargetModule from ${JSON.stringify(options.filePath)};`,
|
|
118
|
+
`export * from ${JSON.stringify(options.filePath)};`,
|
|
119
|
+
"export const __default = __taskTargetModule.default;"
|
|
120
|
+
].join("\n");
|
|
121
|
+
const bundle = await rolldown({
|
|
122
|
+
input: entryId,
|
|
123
|
+
platform: "node",
|
|
124
|
+
external: [...TASK_METADATA_BUNDLE_EXTERNALS],
|
|
125
|
+
plugins: [createEnvAccessPlugin(envViolations, options.projectRoot), {
|
|
126
|
+
name: "task-target-entry",
|
|
127
|
+
resolveId(source) {
|
|
128
|
+
if (source === entryId) return entryId;
|
|
129
|
+
return null;
|
|
130
|
+
},
|
|
131
|
+
load(id) {
|
|
132
|
+
if (id === entryId) return exportReference;
|
|
133
|
+
return null;
|
|
134
|
+
},
|
|
135
|
+
moduleParsed(moduleInfo) {
|
|
136
|
+
if (!moduleInfo.id.includes("node_modules") && !moduleInfo.id.includes("\0")) trackedDependencies.add(moduleInfo.id);
|
|
137
|
+
}
|
|
138
|
+
}]
|
|
139
|
+
});
|
|
140
|
+
try {
|
|
141
|
+
const { output } = await bundle.generate({
|
|
142
|
+
codeSplitting: false,
|
|
143
|
+
format: "esm",
|
|
144
|
+
sourcemap: options.sourceMap
|
|
145
|
+
});
|
|
146
|
+
if (envViolations.length > 0) throw new Error(formatEnvAccessError(envViolations));
|
|
147
|
+
const chunks = output.filter((candidate) => candidate.type === "chunk");
|
|
148
|
+
if (chunks.length !== 1) throw new Error(`Task target bundle must produce exactly one chunk for ${options.filePath}`);
|
|
149
|
+
const [chunk] = chunks;
|
|
150
|
+
if (!chunk) throw new Error(`Expected rolldown to generate a chunk for ${options.filePath}`);
|
|
151
|
+
const sourceMap = chunk.map ? chunk.map.toString() : null;
|
|
152
|
+
return {
|
|
153
|
+
code: chunk.code,
|
|
154
|
+
sourceMap,
|
|
155
|
+
hash: createHash("sha256").update(chunk.code).digest("hex"),
|
|
156
|
+
...sourceMap ? { sourceMapHash: createHash("sha256").update(sourceMap).digest("hex") } : {},
|
|
157
|
+
localDependencies: Array.from(trackedDependencies).sort((left, right) => left.localeCompare(right)),
|
|
158
|
+
externalImports: [...new Set([...chunk.imports, ...chunk.dynamicImports])].sort((left, right) => left.localeCompare(right)),
|
|
159
|
+
size: Buffer.byteLength(chunk.code)
|
|
160
|
+
};
|
|
161
|
+
} finally {
|
|
162
|
+
await bundle.close();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function createBuiltTaskTarget(options) {
|
|
166
|
+
const manifestData = options.taskMetadata.manifest;
|
|
167
|
+
return {
|
|
168
|
+
artifact: {
|
|
169
|
+
task: {
|
|
170
|
+
bindingKey: options.source.bindingKey,
|
|
171
|
+
exportFilePath: options.source.exportFilePath,
|
|
172
|
+
resolvedFilePath: options.source.resolvedFilePath,
|
|
173
|
+
exportName: options.source.exportName,
|
|
174
|
+
localExportName: options.source.localExportName,
|
|
175
|
+
taskId: manifestData.id,
|
|
176
|
+
taskName: manifestData.name
|
|
177
|
+
},
|
|
178
|
+
manifest: manifestData,
|
|
179
|
+
bundle: {
|
|
180
|
+
code: "",
|
|
181
|
+
sourceMap: options.bundle.sourceMap,
|
|
182
|
+
hash: options.bundle.hash,
|
|
183
|
+
sourceMapHash: options.bundle.sourceMapHash,
|
|
184
|
+
localDependencies: options.bundle.localDependencies,
|
|
185
|
+
externalImports: options.bundle.externalImports,
|
|
186
|
+
size: options.bundle.size
|
|
187
|
+
},
|
|
188
|
+
triggers: [],
|
|
189
|
+
timing: {
|
|
190
|
+
importMs: options.taskMetadata.timing.importMs,
|
|
191
|
+
manifestMs: options.taskMetadata.timing.manifestMs,
|
|
192
|
+
bundleMs: 0,
|
|
193
|
+
triggerMs: 0,
|
|
194
|
+
totalMs: 0
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
entry: {
|
|
198
|
+
source: options.source,
|
|
199
|
+
taskMetadata: options.taskMetadata,
|
|
200
|
+
runtimeBundlePath: options.runtimeBundlePath
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function createTaskTargetSource(options) {
|
|
205
|
+
const resolvedFilePath = path.resolve(options.targetFile);
|
|
206
|
+
return {
|
|
207
|
+
bindingKey: `${path.relative(options.projectRoot, resolvedFilePath)}#${options.exportName}`,
|
|
208
|
+
exportFilePath: path.relative(options.projectRoot, resolvedFilePath),
|
|
209
|
+
resolvedFilePath,
|
|
210
|
+
exportName: options.exportName,
|
|
211
|
+
localExportName: options.localExportName
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
async function attachTaskTargetTriggers(options) {
|
|
215
|
+
if (!hasTriggerRuntimeCallbacks(options.entry.taskMetadata.triggers)) {
|
|
216
|
+
options.artifact.triggers.push(...buildTaskTriggerArtifactsWithoutBundles(options.entry.taskMetadata.triggers, options.artifact.task.taskId, options.artifact.task.taskName));
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
const { buildTriggerArtifacts } = await import("./trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs").then((n) => n.n);
|
|
220
|
+
const triggerResult = await buildTriggerArtifacts(options.entry.taskMetadata.triggers, options.artifact.task.taskId, options.artifact.task.taskName, options.projectRoot, {
|
|
221
|
+
workflowExportName: options.entry.source.localExportName,
|
|
222
|
+
workflowFilePath: options.entry.runtimeBundlePath
|
|
223
|
+
});
|
|
224
|
+
options.artifact.triggers.push(...triggerResult.artifacts);
|
|
225
|
+
return triggerResult.failures;
|
|
226
|
+
}
|
|
227
|
+
async function prepareTaskTargetOutput(options) {
|
|
228
|
+
const preparedTasks = [];
|
|
229
|
+
for (const builtTask of options.builtTasks) {
|
|
230
|
+
const triggers = builtTask.artifact.triggers.map(toTriggerUploadData);
|
|
231
|
+
releaseTriggerBundleCode(builtTask.artifact.triggers);
|
|
232
|
+
preparedTasks.push(createPreparedTaskTarget(builtTask.artifact, triggers));
|
|
233
|
+
}
|
|
234
|
+
return preparedTasks;
|
|
235
|
+
}
|
|
236
|
+
function hasTriggerRuntimeCallbacks(triggers) {
|
|
237
|
+
return triggers.some((trigger) => {
|
|
238
|
+
const callbacks = trigger.triggerManifest.runtime.callbacks;
|
|
239
|
+
return trigger.hasTransform || Boolean(callbacks?.verify || callbacks?.filter || callbacks?.idempotencyKey || callbacks?.poll);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function buildTaskTriggerArtifactsWithoutBundles(loadedTriggers, workflowId, workflowName) {
|
|
243
|
+
return loadedTriggers.map((loaded) => {
|
|
244
|
+
const triggerManifest = loaded.triggerManifest;
|
|
245
|
+
const triggerName = triggerManifest.name;
|
|
246
|
+
const triggerType = triggerManifest.triggerType;
|
|
247
|
+
const runtime = triggerManifest.runtime;
|
|
248
|
+
const callbacks = runtime.callbacks;
|
|
249
|
+
const webhookSource = "source" in runtime && runtime.source && typeof runtime.source === "object" ? runtime.source : null;
|
|
250
|
+
const projectedConfig = webhookSource ? webhookSource.type === "app" ? { source: {
|
|
251
|
+
type: "app",
|
|
252
|
+
appRef: webhookSource.appRef
|
|
253
|
+
} } : { source: {
|
|
254
|
+
type: "custom",
|
|
255
|
+
method: webhookSource.method,
|
|
256
|
+
path: webhookSource.path,
|
|
257
|
+
...webhookSource.response ? { response: webhookSource.response } : {}
|
|
258
|
+
} } : void 0;
|
|
259
|
+
return {
|
|
260
|
+
triggerId: generateTaskTriggerId(workflowId, triggerName),
|
|
261
|
+
triggerType,
|
|
262
|
+
triggerName,
|
|
263
|
+
workflowId,
|
|
264
|
+
workflowName,
|
|
265
|
+
sourceFilePath: loaded.sourceFilePath,
|
|
266
|
+
hasTransform: loaded.hasTransform,
|
|
267
|
+
hasFilter: loaded.hasFilter,
|
|
268
|
+
enabled: triggerManifest.enabled,
|
|
269
|
+
..."schedule" in runtime && typeof runtime.schedule === "string" ? { schedule: runtime.schedule } : {},
|
|
270
|
+
..."timezone" in runtime && typeof runtime.timezone === "string" ? { timezone: runtime.timezone } : {},
|
|
271
|
+
...webhookSource ? { triggerSource: webhookSource.type } : {},
|
|
272
|
+
...webhookSource?.type === "custom" && webhookSource.path ? { path: webhookSource.path } : {},
|
|
273
|
+
...webhookSource?.type === "custom" && webhookSource.method ? { method: webhookSource.method } : {},
|
|
274
|
+
...projectedConfig ? { config: projectedConfig } : {},
|
|
275
|
+
...triggerManifest.modeDefault ? { modeDefault: triggerManifest.modeDefault } : {},
|
|
276
|
+
...triggerManifest.credentialSets ? { requiredCredentials: buildTaskTriggerCredentialRequirements(triggerManifest.credentialSets, callbacks) } : {},
|
|
277
|
+
...loaded.staticPayload !== void 0 ? { staticPayload: loaded.staticPayload } : {},
|
|
278
|
+
trigger: loaded.triggerManifest
|
|
279
|
+
};
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function generateTaskTriggerId(workflowId, triggerName) {
|
|
283
|
+
return createHash("sha256").update(`${workflowId}::${triggerName}`).digest("hex").slice(0, 16);
|
|
284
|
+
}
|
|
285
|
+
function buildTaskTriggerCredentialRequirements(credentialSets, callbacks) {
|
|
286
|
+
if (!credentialSets || credentialSets.length === 0) return {
|
|
287
|
+
required: [],
|
|
288
|
+
byCallback: {}
|
|
289
|
+
};
|
|
290
|
+
const entries = credentialSets.map((credentialSet) => {
|
|
291
|
+
const optionalCredentialKeys = readOptionalJsonSchemaKeysFromSchemaObject(credentialSet.auth);
|
|
292
|
+
const resolveCacheMs = "resolveCacheMs" in credentialSet && typeof credentialSet.resolveCacheMs === "number" ? credentialSet.resolveCacheMs : void 0;
|
|
293
|
+
const topLevelRevoked = "onCredentialRevoked" in credentialSet ? credentialSet.onCredentialRevoked : void 0;
|
|
294
|
+
return {
|
|
295
|
+
credentialSetId: credentialSet.resolvedCredentialSetId,
|
|
296
|
+
credentialKeys: readCredentialKeysFromSchemaObject(credentialSet.auth),
|
|
297
|
+
...optionalCredentialKeys.length > 0 ? { optionalCredentialKeys } : {},
|
|
298
|
+
...typeof resolveCacheMs === "number" && resolveCacheMs > 0 ? { resolveCacheMs } : {},
|
|
299
|
+
...topLevelRevoked ? { onCredentialRevoked: topLevelRevoked } : {}
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
const requiredIds = credentialSets.map((credentialSet) => credentialSet.resolvedCredentialSetId);
|
|
303
|
+
const byCallback = {};
|
|
304
|
+
if (callbacks?.poll) byCallback.callback = entries;
|
|
305
|
+
if (callbacks?.verify) byCallback.verify = entries;
|
|
306
|
+
return {
|
|
307
|
+
required: requiredIds,
|
|
308
|
+
byCallback
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function createPreparedTaskTarget(artifact, triggers) {
|
|
312
|
+
return {
|
|
313
|
+
taskId: artifact.task.taskId,
|
|
314
|
+
name: artifact.task.taskName,
|
|
315
|
+
bundleHash: createHash("sha256").update(JSON.stringify(artifact.manifest)).digest("hex"),
|
|
316
|
+
bundleSize: artifact.bundle.size,
|
|
317
|
+
manifestData: artifact.manifest,
|
|
318
|
+
triggers
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
async function tryParseTaskBuildManifest(manifest) {
|
|
322
|
+
const { TaskBuildManifestSchema } = await import("./task-B2sZMaZu.mjs").then((n) => n.t);
|
|
323
|
+
const result = TaskBuildManifestSchema.safeParse(manifest);
|
|
324
|
+
return result.success ? result.data : null;
|
|
325
|
+
}
|
|
326
|
+
function readOptionalJsonSchemaKeysFromSchemaObject(schema) {
|
|
327
|
+
if (!isRecord(schema)) return [];
|
|
328
|
+
const properties = isRecord(schema.properties) ? Object.keys(schema.properties) : [];
|
|
329
|
+
const required = Array.isArray(schema.required) ? new Set(schema.required.filter((key) => typeof key === "string")) : /* @__PURE__ */ new Set();
|
|
330
|
+
return properties.filter((key) => !required.has(key));
|
|
331
|
+
}
|
|
332
|
+
function getTaskRuntimeBundlePath(projectRoot, target) {
|
|
333
|
+
const hash = createHash("sha256").update(target.bindingKey).digest("hex").slice(0, 16);
|
|
334
|
+
return path.join(projectRoot, ".keystroke", "task-target-build", `${hash}.mjs`);
|
|
335
|
+
}
|
|
336
|
+
async function writeRuntimeBundle(bundlePath, code) {
|
|
337
|
+
await mkdir(path.dirname(bundlePath), { recursive: true });
|
|
338
|
+
await writeFile(bundlePath, code, "utf-8");
|
|
339
|
+
}
|
|
340
|
+
function discoverTaskTriggers(task, importedModule, sourceFilePath) {
|
|
341
|
+
const triggers = [];
|
|
342
|
+
const triggerEntries = task.triggers ?? [];
|
|
343
|
+
for (let triggerIndex = 0; triggerIndex < triggerEntries.length; triggerIndex += 1) {
|
|
344
|
+
const entry = triggerEntries[triggerIndex];
|
|
345
|
+
const isBound = isBoundTriggerLike(entry);
|
|
346
|
+
const trigger = isBound ? entry.trigger : entry;
|
|
347
|
+
if (!isTriggerLike(trigger)) throw new Error(`Task trigger at index ${triggerIndex} is not manifest-capable.`);
|
|
348
|
+
const triggerManifest = trigger.toManifest();
|
|
349
|
+
const staticPayload = triggerManifest.triggerType === "cron" && hasPayload(trigger) ? trigger.payload : void 0;
|
|
350
|
+
triggers.push({
|
|
351
|
+
triggerManifest,
|
|
352
|
+
triggerExportName: findTriggerExportName(entry, trigger, importedModule),
|
|
353
|
+
sourceFilePath,
|
|
354
|
+
hasTransform: isBound && typeof entry.transform === "function",
|
|
355
|
+
hasFilter: isBound ? typeof entry.filter === "function" : typeof trigger.filter === "function",
|
|
356
|
+
staticPayload,
|
|
357
|
+
triggerIndex
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
return triggers;
|
|
361
|
+
}
|
|
362
|
+
function isRecord(value) {
|
|
363
|
+
return value !== null && (typeof value === "object" || typeof value === "function");
|
|
364
|
+
}
|
|
365
|
+
function isTaskLike(value) {
|
|
366
|
+
return isRecord(value) && typeof value.toManifest === "function";
|
|
367
|
+
}
|
|
368
|
+
function isTriggerLike(value) {
|
|
369
|
+
return isRecord(value) && typeof value.name === "string" && typeof value.toManifest === "function";
|
|
370
|
+
}
|
|
371
|
+
function isBoundTriggerLike(value) {
|
|
372
|
+
return isRecord(value) && value.isBoundTrigger === true && isTriggerLike(value.trigger);
|
|
373
|
+
}
|
|
374
|
+
function hasPayload(value) {
|
|
375
|
+
return isRecord(value) && "payload" in value;
|
|
376
|
+
}
|
|
377
|
+
function findTriggerExportName(entry, trigger, importedModule) {
|
|
378
|
+
for (const [name, value] of Object.entries(importedModule)) {
|
|
379
|
+
if (value === entry || value === trigger) return name;
|
|
380
|
+
if (isBoundTriggerLike(value) && (value === entry || value.trigger === trigger)) return name;
|
|
381
|
+
if (isTriggerLike(value) && value.name === trigger.name) return name;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function toTriggerUploadData(trigger) {
|
|
385
|
+
const callbackExports = trigger.callbackExports;
|
|
386
|
+
const transformCallbackExports = trigger.transformCallbackExports;
|
|
387
|
+
return {
|
|
388
|
+
id: trigger.triggerId,
|
|
389
|
+
type: trigger.triggerType,
|
|
390
|
+
...trigger.triggerSource ? { triggerSource: trigger.triggerSource } : {},
|
|
391
|
+
enabled: trigger.enabled,
|
|
392
|
+
...trigger.path ? { path: trigger.path } : {},
|
|
393
|
+
...trigger.method ? { method: trigger.method } : {},
|
|
394
|
+
...trigger.schedule ? { schedule: trigger.schedule } : {},
|
|
395
|
+
...trigger.timezone ? { timezone: trigger.timezone } : {},
|
|
396
|
+
...trigger.config ? { config: trigger.config } : {},
|
|
397
|
+
...trigger.requiredCredentials ? { requiredCredentials: trigger.requiredCredentials } : {},
|
|
398
|
+
...callbackExports ? { callbackExports } : {},
|
|
399
|
+
...trigger.callbackBundle ? { callbackBundle: {
|
|
400
|
+
code: trigger.callbackBundle.code,
|
|
401
|
+
hash: trigger.callbackBundle.hash ?? createHash("sha256").update(trigger.callbackBundle.code).digest("hex"),
|
|
402
|
+
size: trigger.callbackBundle.size
|
|
403
|
+
} } : {},
|
|
404
|
+
...transformCallbackExports ? { transformCallbackExports } : {},
|
|
405
|
+
...trigger.transformCallbackBundle ? { transformCallbackBundle: {
|
|
406
|
+
code: trigger.transformCallbackBundle.code,
|
|
407
|
+
hash: trigger.transformCallbackBundle.hash ?? createHash("sha256").update(trigger.transformCallbackBundle.code).digest("hex"),
|
|
408
|
+
size: trigger.transformCallbackBundle.size
|
|
409
|
+
} } : {}
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function releaseTriggerBundleCode(triggers) {
|
|
413
|
+
for (const trigger of triggers) {
|
|
414
|
+
if (trigger.callbackBundle) {
|
|
415
|
+
trigger.callbackBundle.code = "";
|
|
416
|
+
trigger.callbackBundle.released = true;
|
|
417
|
+
}
|
|
418
|
+
if (trigger.transformCallbackBundle) {
|
|
419
|
+
trigger.transformCallbackBundle.code = "";
|
|
420
|
+
trigger.transformCallbackBundle.released = true;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
function releaseBuiltTaskTargets(builtTasks) {
|
|
425
|
+
for (const builtTask of builtTasks) {
|
|
426
|
+
builtTask.entry.taskMetadata.triggers = [];
|
|
427
|
+
builtTask.artifact.triggers = [];
|
|
428
|
+
}
|
|
429
|
+
builtTasks.length = 0;
|
|
430
|
+
}
|
|
431
|
+
//#endregion
|
|
432
|
+
export { buildTaskTargetEntries, buildTaskTargets, prepareTaskTargetBuiltTasks };
|