@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,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { V as SHA256HashSchema } from "./schedule-BXx3uXwr.mjs";
|
|
4
|
+
import "./_manifest-JSRE3H8k.mjs";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
//#region ../../packages/shared-types/src/deployments/api/snapshot-payload.ts
|
|
7
|
+
function sortObjectKeysDeep(value) {
|
|
8
|
+
if (value == null) return null;
|
|
9
|
+
if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") return value;
|
|
10
|
+
if (Array.isArray(value)) return value.map((item) => sortObjectKeysDeep(item));
|
|
11
|
+
if (typeof value !== "object") return String(value);
|
|
12
|
+
const record = value;
|
|
13
|
+
const sortedEntries = Object.keys(record).sort((left, right) => left.localeCompare(right)).map((key) => [key, sortObjectKeysDeep(record[key])]);
|
|
14
|
+
return Object.fromEntries(sortedEntries);
|
|
15
|
+
}
|
|
16
|
+
function normalizeStepManifest(step) {
|
|
17
|
+
return sortObjectKeysDeep({
|
|
18
|
+
nodeId: step.nodeId,
|
|
19
|
+
stepName: step.stepName,
|
|
20
|
+
label: step.label,
|
|
21
|
+
callKind: step.callKind,
|
|
22
|
+
...step.stepId !== void 0 ? { stepId: step.stepId } : {},
|
|
23
|
+
...step.outputBinding !== void 0 ? { outputBinding: step.outputBinding } : {},
|
|
24
|
+
...step.scopeOverride !== void 0 ? { scopeOverride: step.scopeOverride } : {},
|
|
25
|
+
...step.description !== void 0 ? { description: step.description } : {},
|
|
26
|
+
...step.exportName !== void 0 ? { exportName: step.exportName } : {},
|
|
27
|
+
...step.importSource !== void 0 ? { importSource: step.importSource } : {},
|
|
28
|
+
...step.inputSchema !== void 0 ? { inputSchema: step.inputSchema } : {},
|
|
29
|
+
...step.outputSchema !== void 0 ? { outputSchema: step.outputSchema } : {},
|
|
30
|
+
...step.credentialSets !== void 0 ? { credentialSets: step.credentialSets } : {}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function normalizeWorkflowManifest(manifest) {
|
|
34
|
+
return sortObjectKeysDeep({
|
|
35
|
+
schemaVersion: manifest.schemaVersion,
|
|
36
|
+
name: manifest.name,
|
|
37
|
+
...manifest.description !== void 0 ? { description: manifest.description } : {},
|
|
38
|
+
...manifest.tags !== void 0 ? { tags: manifest.tags } : {},
|
|
39
|
+
id: manifest.id,
|
|
40
|
+
exportName: manifest.exportName,
|
|
41
|
+
dependencies: manifest.dependencies,
|
|
42
|
+
workflowSchemas: manifest.workflowSchemas,
|
|
43
|
+
...manifest.workflowSource !== void 0 ? { workflowSource: manifest.workflowSource } : {},
|
|
44
|
+
...manifest.workflowGlobals !== void 0 ? { workflowGlobals: manifest.workflowGlobals } : {},
|
|
45
|
+
...manifest.hasCycles !== void 0 ? { hasCycles: manifest.hasCycles } : {},
|
|
46
|
+
...manifest.credentials !== void 0 ? { credentials: manifest.credentials } : {},
|
|
47
|
+
...manifest.sandboxes !== void 0 ? { sandboxes: manifest.sandboxes } : {},
|
|
48
|
+
steps: Object.fromEntries(Object.entries(manifest.steps ?? {}).map(([nodeId, step]) => [nodeId, normalizeStepManifest(step)]))
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function normalizeTrigger(trigger) {
|
|
52
|
+
return sortObjectKeysDeep({
|
|
53
|
+
id: trigger.id,
|
|
54
|
+
type: trigger.type,
|
|
55
|
+
enabled: trigger.enabled,
|
|
56
|
+
...trigger.path !== void 0 ? { path: trigger.path } : {},
|
|
57
|
+
...trigger.method !== void 0 ? { method: trigger.method } : {},
|
|
58
|
+
...trigger.schedule !== void 0 ? { schedule: trigger.schedule } : {},
|
|
59
|
+
...trigger.timezone !== void 0 ? { timezone: trigger.timezone } : {},
|
|
60
|
+
...trigger.config !== void 0 ? { config: trigger.config } : {},
|
|
61
|
+
...trigger.requiredCredentials !== void 0 ? { requiredCredentials: trigger.requiredCredentials } : {},
|
|
62
|
+
...trigger.callbackBundle ? { callbackBundleHash: trigger.callbackBundle.hash } : {},
|
|
63
|
+
...trigger.callbackExports !== void 0 ? { callbackExports: trigger.callbackExports } : {},
|
|
64
|
+
...trigger.transformCallbackBundle ? { transformCallbackBundleHash: trigger.transformCallbackBundle.hash } : {},
|
|
65
|
+
...trigger.transformCallbackExports !== void 0 ? { transformCallbackExports: trigger.transformCallbackExports } : {}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function normalizeAgentManifest(manifest) {
|
|
69
|
+
return sortObjectKeysDeep({
|
|
70
|
+
agentId: manifest.agentId,
|
|
71
|
+
agentName: manifest.agentName,
|
|
72
|
+
exportName: manifest.exportName,
|
|
73
|
+
mode: manifest.mode,
|
|
74
|
+
...manifest.runtime !== void 0 ? { runtime: manifest.runtime } : {},
|
|
75
|
+
...manifest.systemPrompt !== void 0 ? { systemPrompt: manifest.systemPrompt } : {},
|
|
76
|
+
...manifest.maxSteps !== void 0 ? { maxSteps: manifest.maxSteps } : {},
|
|
77
|
+
...manifest.enableMemory !== void 0 ? { enableMemory: manifest.enableMemory } : {},
|
|
78
|
+
...manifest.enableDatabase !== void 0 ? { enableDatabase: manifest.enableDatabase } : {},
|
|
79
|
+
...manifest.inputSchema !== void 0 ? { inputSchema: manifest.inputSchema } : {},
|
|
80
|
+
...manifest.outputSchema !== void 0 ? { outputSchema: manifest.outputSchema } : {},
|
|
81
|
+
...manifest.tools !== void 0 ? { tools: manifest.tools } : {},
|
|
82
|
+
...manifest.credentialSets !== void 0 ? { credentialSets: manifest.credentialSets } : {},
|
|
83
|
+
...manifest.sandbox !== void 0 ? { sandbox: manifest.sandbox } : {}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function buildCanonicalProjectSnapshotPayload(params) {
|
|
87
|
+
return {
|
|
88
|
+
workflows: params.workflows.map((workflow) => ({
|
|
89
|
+
workflowName: workflow.workflowName,
|
|
90
|
+
authoredWorkflowId: workflow.manifest.id,
|
|
91
|
+
bundleHash: workflow.bundleHash,
|
|
92
|
+
manifest: normalizeWorkflowManifest(workflow.manifest),
|
|
93
|
+
triggers: (workflow.triggers ?? []).map((trigger) => normalizeTrigger(trigger)).sort((left, right) => left.id.localeCompare(right.id))
|
|
94
|
+
})).sort((left, right) => left.authoredWorkflowId.localeCompare(right.authoredWorkflowId) || left.workflowName.localeCompare(right.workflowName)),
|
|
95
|
+
agents: params.agents.map((agent) => ({
|
|
96
|
+
agentId: agent.agentId,
|
|
97
|
+
agentName: agent.agentName,
|
|
98
|
+
bundleHash: agent.bundleHash,
|
|
99
|
+
manifest: normalizeAgentManifest(agent.manifest)
|
|
100
|
+
})).sort((left, right) => left.agentId.localeCompare(right.agentId) || left.agentName.localeCompare(right.agentName))
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region ../../packages/workflow-deploy/dist/task-target-deploy-CA6elFpF.mjs
|
|
105
|
+
function computeProjectSnapshotHash(params) {
|
|
106
|
+
const hex = createHash("sha256").update(JSON.stringify(buildCanonicalProjectSnapshotPayload({
|
|
107
|
+
workflows: params.workflows,
|
|
108
|
+
agents: params.agents
|
|
109
|
+
}))).digest("hex");
|
|
110
|
+
return SHA256HashSchema.parse(hex);
|
|
111
|
+
}
|
|
112
|
+
async function deployTaskTargets(options) {
|
|
113
|
+
const startedAt = Date.now();
|
|
114
|
+
const { preparedTasks, onDeployProgressEvent } = options;
|
|
115
|
+
if (preparedTasks.length === 0) return finalizeTaskTargetResult([], startedAt);
|
|
116
|
+
if (options.dryRun) return finalizeTaskTargetResult(preparedTasks.map((task) => ({
|
|
117
|
+
name: task.name,
|
|
118
|
+
status: "skipped"
|
|
119
|
+
})), startedAt);
|
|
120
|
+
const taskArtifacts = (await lookupTaskHashes(options)).tasks || {};
|
|
121
|
+
const { tasksToDeploy, skippedTasks } = splitChangedTasks({
|
|
122
|
+
preparedTasks,
|
|
123
|
+
existingArtifacts: taskArtifacts,
|
|
124
|
+
force: options.force
|
|
125
|
+
});
|
|
126
|
+
onDeployProgressEvent?.({
|
|
127
|
+
phase: "filter",
|
|
128
|
+
status: "complete",
|
|
129
|
+
workflowsToUpload: 0,
|
|
130
|
+
workflowsSkipped: 0,
|
|
131
|
+
agentsToUpload: 0,
|
|
132
|
+
agentsSkipped: 0,
|
|
133
|
+
tasksToUpload: tasksToDeploy.length,
|
|
134
|
+
tasksSkipped: skippedTasks.length,
|
|
135
|
+
force: options.force,
|
|
136
|
+
elapsedMs: 0
|
|
137
|
+
});
|
|
138
|
+
if (tasksToDeploy.length === 0) return finalizeTaskTargetResult(skippedTasks, startedAt);
|
|
139
|
+
onDeployProgressEvent?.({
|
|
140
|
+
phase: "register-tasks",
|
|
141
|
+
status: "start",
|
|
142
|
+
count: tasksToDeploy.length
|
|
143
|
+
});
|
|
144
|
+
const registerStartedAt = Date.now();
|
|
145
|
+
let deployResult;
|
|
146
|
+
try {
|
|
147
|
+
deployResult = await options.client.public.projects.deploy({ ...buildTaskTargetDeployRequest({
|
|
148
|
+
options,
|
|
149
|
+
taskArtifacts,
|
|
150
|
+
tasksToDeploy
|
|
151
|
+
}) });
|
|
152
|
+
} finally {
|
|
153
|
+
releasePreparedTaskCallbackBundleCode(tasksToDeploy);
|
|
154
|
+
}
|
|
155
|
+
const taskResults = deployResult.tasks ?? [];
|
|
156
|
+
onDeployProgressEvent?.({
|
|
157
|
+
phase: "register-tasks",
|
|
158
|
+
status: "complete",
|
|
159
|
+
succeeded: taskResults.filter((item) => item.status === "deployed").length,
|
|
160
|
+
failed: taskResults.filter((item) => item.status === "failed").length,
|
|
161
|
+
elapsedMs: Date.now() - registerStartedAt
|
|
162
|
+
});
|
|
163
|
+
return finalizeTaskTargetResult([...skippedTasks, ...taskResults.map(mapTaskResultStatus)], startedAt);
|
|
164
|
+
}
|
|
165
|
+
function buildTaskTargetDeployRequest(params) {
|
|
166
|
+
return {
|
|
167
|
+
organizationId: params.options.organizationId,
|
|
168
|
+
projectId: params.options.projectId,
|
|
169
|
+
projectRoot: params.options.projectRoot,
|
|
170
|
+
scope: "targets",
|
|
171
|
+
snapshotHash: computeProjectSnapshotHash({
|
|
172
|
+
workflows: [],
|
|
173
|
+
agents: []
|
|
174
|
+
}),
|
|
175
|
+
force: params.options.force,
|
|
176
|
+
workflows: [],
|
|
177
|
+
agents: [],
|
|
178
|
+
tasks: params.tasksToDeploy.map((task) => buildTaskTargetRegistrationItem(task, params.taskArtifacts, params.options.force))
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
async function lookupTaskHashes(options) {
|
|
182
|
+
const hashCheckStartedAt = Date.now();
|
|
183
|
+
options.onDeployProgressEvent?.({
|
|
184
|
+
phase: "hash-check",
|
|
185
|
+
status: "start",
|
|
186
|
+
workflowCount: 0,
|
|
187
|
+
agentCount: 0,
|
|
188
|
+
taskCount: options.preparedTasks.length
|
|
189
|
+
});
|
|
190
|
+
const hashLookup = await options.client.bundles.getHashes({
|
|
191
|
+
organizationId: options.organizationId,
|
|
192
|
+
projectId: options.projectId,
|
|
193
|
+
tasks: options.preparedTasks.map((task) => ({
|
|
194
|
+
taskId: task.taskId,
|
|
195
|
+
bundleHash: task.bundleHash
|
|
196
|
+
}))
|
|
197
|
+
});
|
|
198
|
+
options.onDeployProgressEvent?.({
|
|
199
|
+
phase: "hash-check",
|
|
200
|
+
status: "complete",
|
|
201
|
+
elapsedMs: Date.now() - hashCheckStartedAt
|
|
202
|
+
});
|
|
203
|
+
return { tasks: hashLookup.tasks || {} };
|
|
204
|
+
}
|
|
205
|
+
function splitChangedTasks(options) {
|
|
206
|
+
if (options.force) return {
|
|
207
|
+
tasksToDeploy: options.preparedTasks,
|
|
208
|
+
skippedTasks: []
|
|
209
|
+
};
|
|
210
|
+
const tasksToDeploy = [];
|
|
211
|
+
const skippedTasks = [];
|
|
212
|
+
for (const task of options.preparedTasks) {
|
|
213
|
+
if (options.existingArtifacts[task.taskId]?.bundleHash === task.bundleHash) {
|
|
214
|
+
skippedTasks.push({
|
|
215
|
+
name: task.name,
|
|
216
|
+
status: "skipped"
|
|
217
|
+
});
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
tasksToDeploy.push(task);
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
tasksToDeploy,
|
|
224
|
+
skippedTasks
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function buildTaskTargetRegistrationItem(task, existingArtifacts, force) {
|
|
228
|
+
return {
|
|
229
|
+
taskId: task.taskId,
|
|
230
|
+
taskName: task.name,
|
|
231
|
+
storagePath: existingArtifacts[task.taskId]?.storagePath,
|
|
232
|
+
manifest: task.manifestData,
|
|
233
|
+
bundleSize: task.bundleSize,
|
|
234
|
+
bundleHash: task.bundleHash,
|
|
235
|
+
triggers: task.triggers,
|
|
236
|
+
skipVersionBump: !force && existingArtifacts[task.taskId]?.bundleHash === task.bundleHash
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function mapTaskResultStatus(result) {
|
|
240
|
+
if (result.status === "failed") return {
|
|
241
|
+
name: result.name,
|
|
242
|
+
status: "failed",
|
|
243
|
+
error: result.error
|
|
244
|
+
};
|
|
245
|
+
if (result.status === "skipped") return {
|
|
246
|
+
name: result.name,
|
|
247
|
+
status: "skipped"
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
name: result.name,
|
|
251
|
+
status: "deployed",
|
|
252
|
+
taskId: result.taskId
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function releasePreparedTaskCallbackBundleCode(preparedTasks) {
|
|
256
|
+
for (const task of preparedTasks) for (const trigger of task.triggers) {
|
|
257
|
+
if (trigger.callbackBundle) trigger.callbackBundle.code = "";
|
|
258
|
+
if (trigger.transformCallbackBundle) trigger.transformCallbackBundle.code = "";
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function finalizeTaskTargetResult(tasks, startedAt) {
|
|
262
|
+
return {
|
|
263
|
+
success: tasks.every((task) => task.status !== "failed"),
|
|
264
|
+
workflows: [],
|
|
265
|
+
agents: [],
|
|
266
|
+
tasks,
|
|
267
|
+
totalTime: Date.now() - startedAt
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
export { deployTaskTargets as n, computeProjectSnapshotHash as t };
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { l as resolveAuthOptions } from "./dist-CUK7yBM0.mjs";
|
|
4
|
+
import { n as findProjectRoot, t as assertWorkflowProjectRoot } from "./project-config-D1qsQlO7.mjs";
|
|
5
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
//#region src/lib/process-handoff.ts
|
|
9
|
+
function replaceProcessOrSpawn(options) {
|
|
10
|
+
const execve = process.execve;
|
|
11
|
+
if (execve) {
|
|
12
|
+
execve(options.file, options.args, options.env);
|
|
13
|
+
throw new Error("process.execve returned unexpectedly.");
|
|
14
|
+
}
|
|
15
|
+
const result = spawnSync(options.file, options.args.slice(1), {
|
|
16
|
+
stdio: "inherit",
|
|
17
|
+
env: options.env
|
|
18
|
+
});
|
|
19
|
+
if (result.error) throw result.error;
|
|
20
|
+
process.exit(result.status ?? 1);
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/task-target-deploy-runner.ts
|
|
24
|
+
const TASK_TARGET_DESCRIPTOR_PATH = path.join(".keystroke", "task-target-deploy", "descriptor.json");
|
|
25
|
+
const TASK_TARGET_BUILD_DESCRIPTOR_PATH = path.join(".keystroke", "task-target-deploy", "build-descriptor.json");
|
|
26
|
+
function parseArgs(argv) {
|
|
27
|
+
const options = {
|
|
28
|
+
targetFiles: [],
|
|
29
|
+
force: false,
|
|
30
|
+
dryRun: false,
|
|
31
|
+
disableSourcemaps: false,
|
|
32
|
+
stage: "deploy"
|
|
33
|
+
};
|
|
34
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
35
|
+
const arg = argv[index];
|
|
36
|
+
if (arg === "--path") {
|
|
37
|
+
options.path = argv[index + 1];
|
|
38
|
+
index += 1;
|
|
39
|
+
} else if (arg === "--target") {
|
|
40
|
+
const targetFile = argv[index + 1];
|
|
41
|
+
if (targetFile) options.targetFiles.push(targetFile);
|
|
42
|
+
index += 1;
|
|
43
|
+
} else if (arg === "--force") options.force = true;
|
|
44
|
+
else if (arg === "--dry-run") options.dryRun = true;
|
|
45
|
+
else if (arg === "--disable-sourcemaps") options.disableSourcemaps = true;
|
|
46
|
+
else if (arg === "--stage") {
|
|
47
|
+
const stage = argv[index + 1];
|
|
48
|
+
options.stage = stage === "deploy-only" ? "deploy-only" : stage === "prepare" ? "prepare" : "deploy";
|
|
49
|
+
index += 1;
|
|
50
|
+
} else if (arg === "--api-key") {
|
|
51
|
+
options.apiKey = argv[index + 1];
|
|
52
|
+
index += 1;
|
|
53
|
+
} else if (arg === "--base-url") {
|
|
54
|
+
options.baseUrl = argv[index + 1];
|
|
55
|
+
index += 1;
|
|
56
|
+
} else if (arg === "--org") {
|
|
57
|
+
options.org = argv[index + 1];
|
|
58
|
+
index += 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return options;
|
|
62
|
+
}
|
|
63
|
+
async function resolveProjectRoot(explicitPath) {
|
|
64
|
+
if (explicitPath) return path.resolve(explicitPath);
|
|
65
|
+
const discovered = await findProjectRoot(process.cwd());
|
|
66
|
+
if (!discovered) throw new Error("No keystroke.config.ts found. Run `keystroke init` or pass --path.");
|
|
67
|
+
return discovered;
|
|
68
|
+
}
|
|
69
|
+
function descriptorPath(projectRoot) {
|
|
70
|
+
return path.join(projectRoot, TASK_TARGET_DESCRIPTOR_PATH);
|
|
71
|
+
}
|
|
72
|
+
function buildDescriptorPath(projectRoot) {
|
|
73
|
+
return path.join(projectRoot, TASK_TARGET_BUILD_DESCRIPTOR_PATH);
|
|
74
|
+
}
|
|
75
|
+
async function writeDescriptor(projectRoot, descriptor) {
|
|
76
|
+
const filePath = descriptorPath(projectRoot);
|
|
77
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
78
|
+
await writeFile(filePath, `${JSON.stringify(descriptor)}\n`, "utf-8");
|
|
79
|
+
}
|
|
80
|
+
async function readDescriptor(projectRoot) {
|
|
81
|
+
return JSON.parse(await readFile(descriptorPath(projectRoot), "utf-8"));
|
|
82
|
+
}
|
|
83
|
+
async function writeBuildDescriptor(projectRoot, descriptor) {
|
|
84
|
+
const filePath = buildDescriptorPath(projectRoot);
|
|
85
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
86
|
+
await writeFile(filePath, `${JSON.stringify(descriptor)}\n`, "utf-8");
|
|
87
|
+
}
|
|
88
|
+
async function readBuildDescriptor(projectRoot) {
|
|
89
|
+
return JSON.parse(await readFile(buildDescriptorPath(projectRoot), "utf-8"));
|
|
90
|
+
}
|
|
91
|
+
function restartStage(options, projectRoot, stage) {
|
|
92
|
+
const runnerPath = process.argv[1];
|
|
93
|
+
if (!runnerPath) throw new Error("Unable to resolve task target deploy runner path.");
|
|
94
|
+
const args = [
|
|
95
|
+
process.execPath,
|
|
96
|
+
...process.execArgv,
|
|
97
|
+
runnerPath,
|
|
98
|
+
"--path",
|
|
99
|
+
projectRoot,
|
|
100
|
+
"--stage",
|
|
101
|
+
stage,
|
|
102
|
+
...options.dryRun ? ["--dry-run"] : [],
|
|
103
|
+
...options.force ? ["--force"] : [],
|
|
104
|
+
...options.disableSourcemaps ? ["--disable-sourcemaps"] : [],
|
|
105
|
+
...options.apiKey ? ["--api-key", options.apiKey] : [],
|
|
106
|
+
...options.baseUrl ? ["--base-url", options.baseUrl] : [],
|
|
107
|
+
...options.org ? ["--org", options.org] : [],
|
|
108
|
+
...options.targetFiles.flatMap((targetFile) => ["--target", targetFile])
|
|
109
|
+
];
|
|
110
|
+
replaceProcessOrSpawn({
|
|
111
|
+
file: process.execPath,
|
|
112
|
+
args,
|
|
113
|
+
env: { ...process.env }
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async function runBuildPhase(options, projectRoot) {
|
|
117
|
+
const projectConfig = await assertWorkflowProjectRoot(projectRoot);
|
|
118
|
+
const { buildTaskTargetEntries } = await import("./task-target-build-CBeCKbu2.mjs");
|
|
119
|
+
await writeBuildDescriptor(projectRoot, {
|
|
120
|
+
projectRoot,
|
|
121
|
+
projectConfig,
|
|
122
|
+
builtTasks: await buildTaskTargetEntries({
|
|
123
|
+
projectRoot,
|
|
124
|
+
targetFiles: options.targetFiles,
|
|
125
|
+
disableSourcemaps: options.disableSourcemaps
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async function runPreparePhase(projectRoot) {
|
|
130
|
+
const buildDescriptor = await readBuildDescriptor(projectRoot);
|
|
131
|
+
const { prepareTaskTargetBuiltTasks } = await import("./task-target-build-CBeCKbu2.mjs");
|
|
132
|
+
const prepareResult = await prepareTaskTargetBuiltTasks({
|
|
133
|
+
builtTasks: buildDescriptor.builtTasks,
|
|
134
|
+
projectRoot
|
|
135
|
+
});
|
|
136
|
+
if (prepareResult.failures.length > 0) throw new Error(prepareResult.failures.map((failure) => failure.error).join("\n"));
|
|
137
|
+
await writeDescriptor(projectRoot, {
|
|
138
|
+
projectRoot,
|
|
139
|
+
projectConfig: buildDescriptor.projectConfig,
|
|
140
|
+
preparedTasks: prepareResult.preparedTasks
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
async function resolveDeployAuthOptions(options) {
|
|
144
|
+
const resolved = await resolveAuthOptions({
|
|
145
|
+
apiKey: options.apiKey,
|
|
146
|
+
baseUrl: options.baseUrl
|
|
147
|
+
});
|
|
148
|
+
const apiKey = options.apiKey ?? resolved.apiKey ?? process.env.KEYSTROKE_API_KEY;
|
|
149
|
+
const baseUrl = options.baseUrl ?? resolved.baseUrl ?? process.env.SERVER_URL;
|
|
150
|
+
const organizationId = options.org ?? process.env.KEYSTROKE_ORG_ID ?? resolved.activeOrg?.organizationId;
|
|
151
|
+
if (!apiKey || !baseUrl) throw new Error("Not authenticated. Run `keystroke auth` or pass --api-key and --base-url.");
|
|
152
|
+
return {
|
|
153
|
+
apiKey,
|
|
154
|
+
baseUrl,
|
|
155
|
+
...organizationId ? { organizationId } : {}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async function runDeployPhase(options, projectRoot) {
|
|
159
|
+
const descriptor = await readDescriptor(projectRoot);
|
|
160
|
+
const { createDeployClient } = await import("./deploy-7Jjls436.mjs");
|
|
161
|
+
const client = createDeployClient(await resolveDeployAuthOptions(options));
|
|
162
|
+
const auth = await client.public.auth.validate();
|
|
163
|
+
if (auth.organizationId !== descriptor.projectConfig.organizationId) throw new Error(`Project organization mismatch: config=${descriptor.projectConfig.organizationId} auth=${auth.organizationId}`);
|
|
164
|
+
const { deployTaskTargets } = await import("./task-target-deploy-C5X-USeR.mjs");
|
|
165
|
+
const result = await deployTaskTargets({
|
|
166
|
+
preparedTasks: descriptor.preparedTasks,
|
|
167
|
+
client,
|
|
168
|
+
organizationId: descriptor.projectConfig.organizationId,
|
|
169
|
+
projectId: descriptor.projectConfig.projectId,
|
|
170
|
+
projectRoot: descriptor.projectRoot,
|
|
171
|
+
force: options.force
|
|
172
|
+
});
|
|
173
|
+
if (result.success) return;
|
|
174
|
+
const errors = result.tasks.filter((task) => task.status === "failed").map((task) => `${task.name}: ${task.error ?? "Deployment failed"}`);
|
|
175
|
+
throw new Error(errors.length > 0 ? errors.join("\n") : "Task deployment failed");
|
|
176
|
+
}
|
|
177
|
+
async function run() {
|
|
178
|
+
const options = parseArgs(process.argv.slice(2));
|
|
179
|
+
if (options.targetFiles.length === 0) throw new Error("Task target deploy runner requires at least one --target file.");
|
|
180
|
+
const projectRoot = await resolveProjectRoot(options.path);
|
|
181
|
+
if (options.stage === "deploy-only") {
|
|
182
|
+
await runDeployPhase(options, projectRoot);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (options.stage === "prepare") {
|
|
186
|
+
await runPreparePhase(projectRoot);
|
|
187
|
+
if (options.dryRun) {
|
|
188
|
+
process.stdout.write("Dry run complete. Deployment skipped.\n");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
restartStage(options, projectRoot, "deploy-only");
|
|
192
|
+
}
|
|
193
|
+
await runBuildPhase(options, projectRoot);
|
|
194
|
+
restartStage(options, projectRoot, "prepare");
|
|
195
|
+
}
|
|
196
|
+
run().catch((error) => {
|
|
197
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
198
|
+
process.stderr.write(`${message}\n`);
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
});
|
|
201
|
+
//#endregion
|
|
202
|
+
export {};
|