@keystrokehq/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/AGENTS-blurb.md +123 -0
  2. package/LICENSE +42 -0
  3. package/README.md +177 -0
  4. package/THIRD_PARTY_NOTICES.md +16 -0
  5. package/bin/keystroke.mjs +107 -0
  6. package/dist/_manifest-JSRE3H8k.mjs +385 -0
  7. package/dist/agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs +2344 -0
  8. package/dist/agent-manifest-CDnbkR2f.mjs +245 -0
  9. package/dist/agents-CZJGxVqV.mjs +228 -0
  10. package/dist/api-keys-D2lgguuY.mjs +40 -0
  11. package/dist/auth-DN2VusyU.mjs +59 -0
  12. package/dist/auth.handler-CT1BQUvu.mjs +340 -0
  13. package/dist/browser-qwFrUH82.mjs +24 -0
  14. package/dist/build-agents-BmM_AsSd-BGi9wtzt.mjs +514 -0
  15. package/dist/build-metadata-BWS7uhd_-DR8gJjTX.mjs +1422 -0
  16. package/dist/build-progress-DgYKb4hB.mjs +183 -0
  17. package/dist/build-tasks-CdihpudT-D5r5HUHe.mjs +91 -0
  18. package/dist/build-workflows-CfxBnIWh-CdYPv8w2.mjs +370 -0
  19. package/dist/build.handler-4799CjWH.mjs +36 -0
  20. package/dist/chunk-CH6r78ws.mjs +37 -0
  21. package/dist/clear-cache.handler-B9tqSoSM.mjs +11 -0
  22. package/dist/clear.handler-BTIXXPTJ.mjs +42 -0
  23. package/dist/clear.handler-BydlX-zE.mjs +11 -0
  24. package/dist/commander-DfTVqQ-3.mjs +133 -0
  25. package/dist/concurrency-gXn9Rw8x-DNl2YtrS.mjs +20 -0
  26. package/dist/connect-BUXkeH0F.mjs +43 -0
  27. package/dist/connect.handler-CYel9cy6.mjs +430 -0
  28. package/dist/constants-CPpPdSNg.mjs +8 -0
  29. package/dist/context-T7HZuB97.mjs +138 -0
  30. package/dist/credential-env-map-CI8yWHVy.mjs +28 -0
  31. package/dist/credential-schema-mismatch-BKo5PjcQ.mjs +76 -0
  32. package/dist/credentials-CvmjU0lK.mjs +171 -0
  33. package/dist/credentials-OfVHOtG3.mjs +151216 -0
  34. package/dist/current-deployment-workflow-poHt27i3.mjs +94 -0
  35. package/dist/current.handler-B8zKzfPp.mjs +21 -0
  36. package/dist/delete.handler-bAu1iXVQ.mjs +17 -0
  37. package/dist/deploy-7Jjls436.mjs +26 -0
  38. package/dist/deploy-BOPIpRWm.mjs +74 -0
  39. package/dist/deploy-progress-BmGUNFKg.mjs +70 -0
  40. package/dist/deploy.handler-BAzgiNhd.mjs +370 -0
  41. package/dist/detect-env-access-CwkOYeYM-D_BCZqV6.mjs +209 -0
  42. package/dist/diff-utils-NEfcjqxt.mjs +185 -0
  43. package/dist/diff.handler-Du7SY8K4.mjs +47 -0
  44. package/dist/dist-BkJUoBiG.mjs +1116 -0
  45. package/dist/dist-CUK7yBM0.mjs +308 -0
  46. package/dist/env-91KwMKov.mjs +140 -0
  47. package/dist/env.handler-BAzBuMzQ.mjs +277 -0
  48. package/dist/error-boundary-VL-JLfIa.mjs +34 -0
  49. package/dist/file-metadata-D1vm-XY2.mjs +191 -0
  50. package/dist/get-intrinsic-zLxwtrLK.mjs +658 -0
  51. package/dist/import-module-CV84H5fZ-B_CBCmb4.mjs +1747 -0
  52. package/dist/init-DpMCotSK.mjs +45 -0
  53. package/dist/init.handler-CPRnif52.mjs +585 -0
  54. package/dist/inspect.handler-DT_cD036.mjs +146 -0
  55. package/dist/integration-catalog-Bt-L3GjF.mjs +104 -0
  56. package/dist/integrations-DlatPK4W.mjs +79 -0
  57. package/dist/keystroke.d.mts +3 -0
  58. package/dist/keystroke.mjs +707 -0
  59. package/dist/layout-CbMtQ2tm.mjs +67 -0
  60. package/dist/list-enrichment-y-cwizLr.mjs +189 -0
  61. package/dist/list.handler-BTWvCyjA.mjs +52 -0
  62. package/dist/list.handler-CWF_Dj15.mjs +24 -0
  63. package/dist/list.handler-CZ6G2x_G.mjs +75 -0
  64. package/dist/list.handler-DWaQkJaR.mjs +51 -0
  65. package/dist/list.handler-DqbFcBW7.mjs +180 -0
  66. package/dist/list.handler-lq3ZGAn4.mjs +104 -0
  67. package/dist/logs-BEg9L5l8.mjs +28 -0
  68. package/dist/logs.handler-6hoMBzqw.mjs +35 -0
  69. package/dist/logs.handler-BD_dXiL1.mjs +231 -0
  70. package/dist/metadata-layout-GUYIUo0i-_aG2zjue.mjs +5877 -0
  71. package/dist/normalize-path-CojS-CgQ-DLCOvnD1.mjs +20 -0
  72. package/dist/options-CeaTcFxP.mjs +43 -0
  73. package/dist/org-xLzBtt2_.mjs +41 -0
  74. package/dist/output-DM4b7KgY.mjs +72 -0
  75. package/dist/oxc-B3KI3rf_-n9d1hKNq.mjs +119 -0
  76. package/dist/paused.handler-BMFm9Cff.mjs +94 -0
  77. package/dist/project-config-D1qsQlO7.mjs +107 -0
  78. package/dist/projects-CHkRE9rS.mjs +1574 -0
  79. package/dist/projects-Cjb7sovS.mjs +30 -0
  80. package/dist/read-credential-keys-77a91T8M-KA0Iw0Z1.mjs +9 -0
  81. package/dist/register.handler-BPCdor1_.mjs +86 -0
  82. package/dist/requirements.handler-DPXdSks3.mjs +201 -0
  83. package/dist/resolve-project-DDJ29sCF.mjs +35 -0
  84. package/dist/rolldown-runtime-twds-ZHy-BWWzu8VG.mjs +15 -0
  85. package/dist/run-polling-CAgFRdK3.mjs +20 -0
  86. package/dist/runs-D9hNLb9A.mjs +259 -0
  87. package/dist/schedule-BXx3uXwr.mjs +1142 -0
  88. package/dist/schema-17qMfNyI.mjs +18 -0
  89. package/dist/schema-display-CgmeKigW.mjs +130 -0
  90. package/dist/schemas-CDib1RhE.mjs +125 -0
  91. package/dist/skills-sync.handler-DIy8GR16.mjs +34 -0
  92. package/dist/skills.command-CrjI2dN9.mjs +35 -0
  93. package/dist/skills.handler-Bz8bJKql.mjs +9 -0
  94. package/dist/source-analysis-Cj-ADyu--BJQcFPCG.mjs +144 -0
  95. package/dist/spinner-progress-DMVwgqO9.mjs +173 -0
  96. package/dist/src-C0X6u_Mw.mjs +1340 -0
  97. package/dist/src-eHwu-Gfw.mjs +369 -0
  98. package/dist/status.handler-BO4nwvWn.mjs +101 -0
  99. package/dist/switch.handler-D_9213Vf.mjs +51 -0
  100. package/dist/sync-BL_Mo5st.mjs +39 -0
  101. package/dist/sync-keystroke-agent-skills-Kx_H7UTd.mjs +70 -0
  102. package/dist/sync.handler-BUFPdzWz.mjs +82 -0
  103. package/dist/task-B2sZMaZu.mjs +8 -0
  104. package/dist/task-target-build-CBeCKbu2.mjs +432 -0
  105. package/dist/task-target-deploy-C5X-USeR.mjs +4 -0
  106. package/dist/task-target-deploy-CA6elFpF-BEr4gkol.mjs +271 -0
  107. package/dist/task-target-deploy-runner.d.mts +3 -0
  108. package/dist/task-target-deploy-runner.mjs +202 -0
  109. package/dist/test-BHTgR3UA.mjs +698 -0
  110. package/dist/test.handler-BcPQ8b74.mjs +13 -0
  111. package/dist/trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs +239 -0
  112. package/dist/trigger-manifest-CY7brZeg.mjs +30 -0
  113. package/dist/try-deploy.handler-DqybNhXx.mjs +490 -0
  114. package/dist/upload-CkU--iDC.mjs +207 -0
  115. package/dist/upload.handler-DCtiznQp.mjs +441 -0
  116. package/dist/utils-CywxCDM7.mjs +14 -0
  117. package/dist/validate.handler-DOcTaJL0.mjs +280 -0
  118. package/dist/workflow-build-DBQaBfnn.mjs +1819 -0
  119. package/dist/workflow-bundler-BPiqVscj-X1PFFAuP.mjs +167 -0
  120. package/dist/workflows-g9z87AJJ.mjs +799 -0
  121. package/dist/writer-BG8poUm3-BbXlU2kI.mjs +426 -0
  122. package/package.json +87 -0
@@ -0,0 +1,799 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { n as JsonOptionSchema, t as JSON_OPTION_CONFIG } from "./output-DM4b7KgY.mjs";
4
+ import { t as createTypedCommand } from "./commander-DfTVqQ-3.mjs";
5
+ import { V as SHA256HashSchema, p as TriggerUploadDataSchema, z as JsonSchemaSchema } from "./schedule-BXx3uXwr.mjs";
6
+ import { c as FlowGraphSchema, s as WorkflowManifestSchema } from "./_manifest-JSRE3H8k.mjs";
7
+ import { n as WorkflowsRunOptionsSchema, t as RUN_OPTIONS_CONFIG } from "./options-CeaTcFxP.mjs";
8
+ import { z } from "zod";
9
+ const GitProviderSchema = z.enum(["codestorage", "github"]);
10
+ const GitTreeEntryTypeSchema = z.enum(["file", "directory"]);
11
+ const GitFileEditActionSchema = z.enum([
12
+ "create",
13
+ "update",
14
+ "delete"
15
+ ]);
16
+ z.object({
17
+ id: z.string().min(1),
18
+ cloneUrl: z.string().min(1),
19
+ defaultBranch: z.string().min(1).default("main")
20
+ });
21
+ z.object({
22
+ path: z.string().min(1),
23
+ type: GitTreeEntryTypeSchema,
24
+ sizeBytes: z.number().int().nonnegative().optional()
25
+ });
26
+ z.object({
27
+ path: z.string().min(1),
28
+ content: z.string()
29
+ });
30
+ const GitFileEditSchema = z.object({
31
+ path: z.string().min(1),
32
+ action: GitFileEditActionSchema,
33
+ content: z.string().optional()
34
+ });
35
+ const GitCommitAuthorSchema = z.object({
36
+ name: z.string().min(1),
37
+ email: z.email()
38
+ });
39
+ z.object({
40
+ organizationId: z.string().min(1),
41
+ projectId: z.string().min(1),
42
+ repoName: z.string().min(1)
43
+ });
44
+ z.object({
45
+ branch: z.string().min(1).default("main"),
46
+ message: z.string().min(1),
47
+ author: GitCommitAuthorSchema,
48
+ edits: z.array(GitFileEditSchema).min(1)
49
+ });
50
+ z.object({
51
+ sha: z.string().min(1),
52
+ branch: z.string().min(1)
53
+ });
54
+ z.object({
55
+ branch: z.string().min(1).optional(),
56
+ limit: z.number().int().positive().max(200).optional()
57
+ });
58
+ z.object({
59
+ sha: z.string().min(1),
60
+ message: z.string().min(1),
61
+ authoredAt: z.string().min(1),
62
+ author: GitCommitAuthorSchema
63
+ });
64
+ z.object({
65
+ cloneUrl: z.string().min(1),
66
+ expiresAt: z.string().optional().nullable()
67
+ });
68
+ z.object({
69
+ tag: z.string().min(1),
70
+ commitSha: z.string().min(1)
71
+ });
72
+ z.uuid();
73
+ const ProjectBaseSchema = z.object({
74
+ organizationId: z.uuid(),
75
+ name: z.string().min(1).max(255),
76
+ description: z.string().optional().nullable(),
77
+ isDefault: z.boolean().default(false),
78
+ githubRepoUrl: z.url().optional().nullable(),
79
+ gitRepoId: z.string().optional().nullable(),
80
+ gitProvider: GitProviderSchema.optional().nullable()
81
+ });
82
+ ProjectBaseSchema.extend({
83
+ id: z.uuid(),
84
+ currentDeploymentId: z.string().optional().nullable(),
85
+ createdBy: z.uuid().optional().nullable(),
86
+ createdAt: z.date(),
87
+ updatedAt: z.date(),
88
+ deletedAt: z.date().optional().nullable()
89
+ });
90
+ z.enum([
91
+ "active",
92
+ "hibernated",
93
+ "creating",
94
+ "error",
95
+ "deleted"
96
+ ]);
97
+ const ActivationStatusSchema = z.enum([
98
+ "active",
99
+ "paused",
100
+ "disabled"
101
+ ]);
102
+ z.enum(["automatic", "requires_activation"]);
103
+ z.enum(["workflow", "task"]);
104
+ const activationSharedFields = {
105
+ id: z.string(),
106
+ projectId: z.uuid(),
107
+ organizationId: z.uuid(),
108
+ logicalTriggerKey: z.string(),
109
+ status: ActivationStatusSchema,
110
+ /**
111
+ * Per-callback trigger credential bindings.
112
+ * Key: "<callbackName>:<credentialSetResolvedId>" (e.g. "verify:keystroke:slack").
113
+ * Value: credential set ID or "<scope>.default".
114
+ */
115
+ triggerCredentialBindings: z.record(z.string(), z.string()).optional(),
116
+ /**
117
+ * Per-step workflow credential bindings (workflow-target only).
118
+ * Key: "<stepNodeId>:<credentialSetResolvedId>" (e.g. "step_1:keystroke:slack").
119
+ * Value: credential set ID or "<scope>.default".
120
+ */
121
+ workflowCredentialBindings: z.record(z.string(), z.string()).optional(),
122
+ config: z.unknown().optional(),
123
+ state: z.unknown().optional(),
124
+ nextRunAt: z.string().datetime().nullable(),
125
+ lastRunAt: z.string().datetime().nullable(),
126
+ createdAt: z.string().datetime(),
127
+ updatedAt: z.string().datetime(),
128
+ deletedAt: z.string().datetime().nullable()
129
+ };
130
+ const WorkflowActivationSchema = z.object({
131
+ ...activationSharedFields,
132
+ targetKind: z.literal("workflow"),
133
+ workflowId: z.uuid(),
134
+ taskId: z.null(),
135
+ userId: z.uuid().nullable()
136
+ });
137
+ const TaskActivationSchema = z.object({
138
+ ...activationSharedFields,
139
+ targetKind: z.literal("task"),
140
+ taskId: z.string(),
141
+ workflowId: z.null(),
142
+ userId: z.null()
143
+ });
144
+ z.discriminatedUnion("targetKind", [WorkflowActivationSchema, TaskActivationSchema]);
145
+ z.object({
146
+ id: z.string(),
147
+ projectId: z.uuid(),
148
+ activationId: z.string(),
149
+ idempotencyKey: z.string(),
150
+ createdAt: z.string().datetime(),
151
+ expiresAt: z.string().datetime()
152
+ });
153
+ //#endregion
154
+ //#region ../../packages/shared-types/src/workflows/domain/log.ts
155
+ const LogLevelSchema = z.enum([
156
+ "debug",
157
+ "info",
158
+ "warn",
159
+ "error"
160
+ ]);
161
+ const LogSourceSchema = z.enum([
162
+ "system",
163
+ "workflow",
164
+ "step"
165
+ ]);
166
+ z.object({
167
+ level: LogLevelSchema,
168
+ source: LogSourceSchema,
169
+ message: z.string(),
170
+ metadata: z.record(z.string(), z.unknown()).optional(),
171
+ timestamp: z.iso.datetime(),
172
+ correlationId: z.string().optional()
173
+ });
174
+ //#endregion
175
+ //#region ../../packages/shared-types/src/workflows/domain/reactflow-edit.ts
176
+ /** A user-initiated node drag that changes its canvas position. */
177
+ const MoveNodeMutationSchema = z.object({
178
+ kind: z.literal("move-node"),
179
+ nodeId: z.string().min(1),
180
+ x: z.number().finite(),
181
+ y: z.number().finite()
182
+ });
183
+ const WorkflowMutationSchema = z.discriminatedUnion("kind", [MoveNodeMutationSchema]);
184
+ z.enum([
185
+ "active",
186
+ "paused",
187
+ "disabled",
188
+ "archived"
189
+ ]);
190
+ const WorkflowBaseSchema = z.object({
191
+ organizationId: z.uuid(),
192
+ projectId: z.uuid(),
193
+ name: z.string().min(1).max(255),
194
+ description: z.string().optional().nullable(),
195
+ tags: z.array(z.string()).optional().nullable(),
196
+ icon: z.string().max(50).optional().nullable(),
197
+ isArchived: z.boolean().default(false)
198
+ });
199
+ WorkflowBaseSchema.extend({
200
+ authoredWorkflowId: z.string().min(1),
201
+ createdBy: z.uuid().optional().nullable(),
202
+ updatedBy: z.uuid().optional().nullable(),
203
+ createdAt: z.string(),
204
+ updatedAt: z.string(),
205
+ deletedAt: z.string().optional().nullable()
206
+ });
207
+ const NewWorkflowSchema = WorkflowBaseSchema;
208
+ const StepBaseSchema = z.object({
209
+ organizationId: z.uuid(),
210
+ projectId: z.uuid(),
211
+ name: z.string().min(1).max(255),
212
+ slug: z.string().min(1).max(255).regex(/^[a-z0-9-]+$/, "Slug must be alphanumeric and can contain hyphens"),
213
+ description: z.string().optional().nullable(),
214
+ tags: z.array(z.string()).optional().nullable(),
215
+ icon: z.string().max(50).optional().nullable(),
216
+ credentialSets: z.array(z.string()).default([]),
217
+ isArchived: z.boolean().default(false)
218
+ });
219
+ StepBaseSchema.extend({
220
+ id: z.string().startsWith("sdef_"),
221
+ createdBy: z.uuid().optional().nullable(),
222
+ updatedBy: z.uuid().optional().nullable(),
223
+ createdAt: z.string(),
224
+ updatedAt: z.string(),
225
+ deletedAt: z.string().optional().nullable()
226
+ });
227
+ const NewStepSchema = StepBaseSchema;
228
+ z.object({
229
+ stepId: z.string().startsWith("sdef_"),
230
+ version: z.number().int().positive(),
231
+ storagePath: z.string().max(1024).optional().nullable(),
232
+ sourceCode: z.string(),
233
+ exportName: z.string().min(1).max(255),
234
+ inputSchema: JsonSchemaSchema.optional().nullable(),
235
+ outputSchema: JsonSchemaSchema.optional().nullable(),
236
+ credentialSets: z.array(z.unknown()).default([]),
237
+ timeout: z.string().max(50).optional().nullable(),
238
+ retryConfig: JsonSchemaSchema.optional().nullable(),
239
+ isLatest: z.boolean().default(false),
240
+ isDeprecated: z.boolean().default(false)
241
+ }).extend({
242
+ id: z.string().startsWith("sdv_"),
243
+ publishedBy: z.uuid().optional().nullable(),
244
+ publishedAt: z.string(),
245
+ createdAt: z.string()
246
+ });
247
+ z.object({
248
+ limit: z.number(),
249
+ offset: z.number(),
250
+ total: z.number()
251
+ });
252
+ /**
253
+ * Pagination query parameters for list endpoints.
254
+ * Uses consistent validation across all endpoints:
255
+ * - limit: 1-100 (default: 20)
256
+ * - offset: >= 0 (default: 0)
257
+ */
258
+ const PaginationQuerySchema = z.object({
259
+ limit: z.coerce.number().min(1).max(100).optional().default(20),
260
+ offset: z.coerce.number().min(0).optional().default(0)
261
+ });
262
+ z.object({
263
+ error: z.string(),
264
+ message: z.string().optional(),
265
+ code: z.string().optional()
266
+ });
267
+ z.object({
268
+ error: z.literal("Not found"),
269
+ resource: z.string(),
270
+ id: z.string()
271
+ });
272
+ z.object({
273
+ error: z.literal("Validation failed"),
274
+ message: z.string(),
275
+ fields: z.record(z.string(), z.array(z.string())).optional()
276
+ });
277
+ /** Matches UUID v1-v5 format. Used to distinguish UUIDs from slugs at runtime. */
278
+ const UUID_FORMAT = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
279
+ z.string().min(1).max(255).regex(/^[a-z0-9-]+$/, "Slug must be alphanumeric and can contain hyphens").refine((val) => !UUID_FORMAT.test(val), "Slug must not be in UUID format");
280
+ //#endregion
281
+ //#region src/commands/workflows/build.command.ts
282
+ const WorkflowsBuildOptionsSchema = z.object({
283
+ path: z.string().optional(),
284
+ verbose: z.boolean().default(false),
285
+ name: z.string().optional(),
286
+ target: z.array(z.string()).default([]),
287
+ force: z.boolean().default(false),
288
+ disableSourcemaps: z.boolean().default(false)
289
+ });
290
+ const BUILD_OPTIONS_CONFIG = {
291
+ path: {
292
+ flag: "--path <path>",
293
+ description: "Path to project root (directory containing keystroke.config.ts); auto-discovered from CWD if omitted"
294
+ },
295
+ verbose: {
296
+ flag: "--verbose",
297
+ description: "Show detailed build logs"
298
+ },
299
+ name: {
300
+ flag: "--name <workflow>",
301
+ description: "Build only one workflow by exact workflow name"
302
+ },
303
+ target: {
304
+ flag: "--target <file>",
305
+ description: "Build deployable exports from a target source file; repeat for multiple files",
306
+ collect: true
307
+ },
308
+ force: {
309
+ flag: "--force",
310
+ description: "Build all workflows regardless of cache"
311
+ },
312
+ disableSourcemaps: {
313
+ flag: "--disable-sourcemaps",
314
+ description: "Disable sourcemap generation for build bundles"
315
+ }
316
+ };
317
+ function createWorkflowsBuildCommand() {
318
+ return createTypedCommand({
319
+ name: "build",
320
+ description: "Build workflows locally",
321
+ schema: WorkflowsBuildOptionsSchema,
322
+ optionsConfig: BUILD_OPTIONS_CONFIG,
323
+ loadHandler: async () => (await import("./build.handler-4799CjWH.mjs")).handleWorkflowsBuild
324
+ });
325
+ }
326
+ //#endregion
327
+ //#region src/commands/workflows/diff/diff.command.ts
328
+ const WorkflowsDiffOptionsSchema = JsonOptionSchema.extend({
329
+ workflow: z.string(),
330
+ path: z.string().optional()
331
+ });
332
+ const DIFF_OPTIONS_CONFIG = {
333
+ ...JSON_OPTION_CONFIG,
334
+ path: {
335
+ flag: "--path <dir>",
336
+ description: "Path to project root; auto-discovered from CWD if omitted"
337
+ }
338
+ };
339
+ function createWorkflowsDiffCommand() {
340
+ return createTypedCommand({
341
+ name: "diff",
342
+ description: "Compare local workflow definition against the current project deployment",
343
+ schema: WorkflowsDiffOptionsSchema,
344
+ optionsConfig: DIFF_OPTIONS_CONFIG,
345
+ argument: {
346
+ name: "workflow",
347
+ description: "Authored workflow id (preferred) or workflow name",
348
+ key: "workflow"
349
+ },
350
+ loadHandler: async () => (await import("./diff.handler-Du7SY8K4.mjs")).handleWorkflowsDiff
351
+ });
352
+ }
353
+ //#endregion
354
+ //#region src/commands/workflows/env/env.command.ts
355
+ const WorkflowsEnvOptionsSchema = JsonOptionSchema.extend({
356
+ workflow: z.string().optional(),
357
+ path: z.string().optional(),
358
+ check: z.boolean().optional().default(false)
359
+ });
360
+ const ENV_OPTIONS_CONFIG = {
361
+ ...JSON_OPTION_CONFIG,
362
+ path: {
363
+ flag: "--path <dir>",
364
+ description: "Path to project root; auto-discovered from CWD if omitted"
365
+ },
366
+ check: {
367
+ flag: "--check",
368
+ description: "Exit non-zero if any required env var is missing (useful for CI)"
369
+ }
370
+ };
371
+ function createWorkflowsEnvCommand() {
372
+ return createTypedCommand({
373
+ name: "env",
374
+ description: "Show environment variables and credentials required by a workflow",
375
+ schema: WorkflowsEnvOptionsSchema,
376
+ optionsConfig: ENV_OPTIONS_CONFIG,
377
+ argument: {
378
+ name: "workflow",
379
+ description: "Authored workflow id (preferred) or workflow name — omit to show all",
380
+ key: "workflow",
381
+ required: false
382
+ },
383
+ loadHandler: async () => (await import("./env.handler-BAzBuMzQ.mjs")).handleWorkflowsEnv
384
+ });
385
+ }
386
+ //#endregion
387
+ //#region src/commands/workflows/inspect/inspect.command.ts
388
+ const WorkflowsInspectOptionsSchema = JsonOptionSchema.extend({
389
+ workflow: z.string(),
390
+ path: z.string().optional(),
391
+ deployed: z.boolean().optional().default(false)
392
+ });
393
+ const INSPECT_OPTIONS_CONFIG = {
394
+ ...JSON_OPTION_CONFIG,
395
+ path: {
396
+ flag: "--path <dir>",
397
+ description: "Path to project root; auto-discovered from CWD if omitted"
398
+ },
399
+ deployed: {
400
+ flag: "--deployed",
401
+ description: "Fetch manifest from the current deployment for this project"
402
+ }
403
+ };
404
+ function createWorkflowsInspectCommand() {
405
+ return createTypedCommand({
406
+ name: "inspect",
407
+ description: "Show the full manifest for a workflow (schemas, steps, credentials)",
408
+ schema: WorkflowsInspectOptionsSchema,
409
+ optionsConfig: INSPECT_OPTIONS_CONFIG,
410
+ argument: {
411
+ name: "workflow",
412
+ description: "Authored workflow id (preferred) or workflow name",
413
+ key: "workflow"
414
+ },
415
+ loadHandler: async () => (await import("./inspect.handler-DT_cD036.mjs")).handleWorkflowsInspect
416
+ });
417
+ }
418
+ //#endregion
419
+ //#region src/commands/workflows/logs/logs.command.ts
420
+ const LogsLevelOptionSchema = z.enum([
421
+ "debug",
422
+ "info",
423
+ "warn",
424
+ "error"
425
+ ]);
426
+ const WorkflowsLogsOptionsSchema = JsonOptionSchema.extend({
427
+ workflow: z.string().optional(),
428
+ runId: z.string().optional(),
429
+ latest: z.boolean().optional().default(false),
430
+ limit: z.coerce.number().int().min(1).max(100).default(10),
431
+ status: z.string().optional(),
432
+ level: LogsLevelOptionSchema.optional(),
433
+ tail: z.coerce.number().int().min(1).max(200).optional(),
434
+ follow: z.boolean().optional().default(false),
435
+ verbose: z.boolean().optional().default(false)
436
+ }).superRefine((value, ctx) => {
437
+ const logMode = value.latest || value.runId !== void 0;
438
+ if (!value.workflow && !value.runId) ctx.addIssue({
439
+ code: z.ZodIssueCode.custom,
440
+ path: ["workflow"],
441
+ message: "Provide an authored workflow id or a workflow name, or use --run-id <id> to inspect a specific run."
442
+ });
443
+ if (value.latest && value.runId) ctx.addIssue({
444
+ code: z.ZodIssueCode.custom,
445
+ path: ["latest"],
446
+ message: "Use either --latest or --run-id, not both."
447
+ });
448
+ if (value.latest && !value.workflow) ctx.addIssue({
449
+ code: z.ZodIssueCode.custom,
450
+ path: ["workflow"],
451
+ message: "--latest requires an authored workflow id or a workflow name."
452
+ });
453
+ if (value.status && logMode) ctx.addIssue({
454
+ code: z.ZodIssueCode.custom,
455
+ path: ["status"],
456
+ message: "--status only applies when listing runs."
457
+ });
458
+ if ((value.level || value.tail || value.follow) && !logMode) ctx.addIssue({
459
+ code: z.ZodIssueCode.custom,
460
+ path: ["runId"],
461
+ message: "--level, --tail, and --follow require --latest or --run-id."
462
+ });
463
+ });
464
+ const LOGS_OPTIONS_CONFIG = {
465
+ ...JSON_OPTION_CONFIG,
466
+ runId: {
467
+ flag: "--run-id <runId>",
468
+ description: "Show logs for a specific run ID"
469
+ },
470
+ latest: {
471
+ flag: "--latest",
472
+ description: "Show logs for the latest run of the specified workflow"
473
+ },
474
+ limit: {
475
+ flag: "--limit <n>",
476
+ description: "List mode only: max runs to display (default: 10)"
477
+ },
478
+ status: {
479
+ flag: "--status <status>",
480
+ description: "List mode only: filter runs by status (pending/running/completed/failed/cancelled)"
481
+ },
482
+ level: {
483
+ flag: "--level <level>",
484
+ description: "Log mode only: filter log lines by level (debug/info/warn/error)"
485
+ },
486
+ tail: {
487
+ flag: "--tail <n>",
488
+ description: "Log mode only: show only the last N fetched log lines (max: 200)"
489
+ },
490
+ follow: {
491
+ flag: "--follow",
492
+ description: "Log mode only: poll for new logs until the selected run reaches a terminal state"
493
+ },
494
+ verbose: {
495
+ flag: "--verbose",
496
+ description: "Include log metadata in output"
497
+ }
498
+ };
499
+ function createWorkflowsLogsCommand() {
500
+ return createTypedCommand({
501
+ name: "logs",
502
+ description: "List recent runs for a workflow id or name, or show logs for the latest or a specific run",
503
+ schema: WorkflowsLogsOptionsSchema,
504
+ optionsConfig: LOGS_OPTIONS_CONFIG,
505
+ argument: {
506
+ name: "workflow",
507
+ description: "Authored workflow id (preferred) or workflow name",
508
+ key: "workflow",
509
+ required: false
510
+ },
511
+ loadHandler: async () => (await import("./logs.handler-BD_dXiL1.mjs")).handleWorkflowsLogs
512
+ });
513
+ }
514
+ //#endregion
515
+ //#region ../../packages/shared-types/src/workflows/api/request.ts
516
+ /** Key format: <stepNodeId>:<credentialSetResolvedId> (e.g. step_1:keystroke:slack)
517
+ * The resolved ID may contain a colon for namespaced IDs (e.g. keystroke:slack) */
518
+ const WORKFLOW_CREDENTIAL_BINDING_KEY_REGEX = /^[a-zA-Z0-9_]+:[a-zA-Z0-9.:_-]+$/;
519
+ /** Key format: <callbackName>:<credentialSetResolvedId> (e.g. verify:keystroke:slack) */
520
+ const TRIGGER_CREDENTIAL_BINDING_KEY_REGEX = /^(verify|filter|transform|idempotencyKey|callback):[a-zA-Z0-9.:_-]+$/;
521
+ /** Value: credential set ID (cset_ + ULID) or <scope>.default */
522
+ const CREDENTIAL_BINDING_VALUE_CREDSET = /^cset_[A-Za-z0-9]{26}$/;
523
+ const CREDENTIAL_BINDING_VALUE_SCOPE_DEFAULT = /^(organization|user|project)\.default$/;
524
+ const WorkflowCredentialBindingsRecordSchema = z.record(z.string(), z.string()).refine((record) => {
525
+ for (const [key, value] of Object.entries(record)) {
526
+ if (!WORKFLOW_CREDENTIAL_BINDING_KEY_REGEX.test(key)) return false;
527
+ if (!CREDENTIAL_BINDING_VALUE_CREDSET.test(value) && !CREDENTIAL_BINDING_VALUE_SCOPE_DEFAULT.test(value)) return false;
528
+ }
529
+ return true;
530
+ }, { message: "workflowCredentialBindings keys must be \"<stepNodeId>:<credentialSetResolvedId>\"; values must be credential set ID (cset_...) or \"<scope>.default\"" }).optional();
531
+ const TriggerCredentialBindingsRecordSchema = z.record(z.string(), z.string()).refine((record) => {
532
+ for (const [key, value] of Object.entries(record)) {
533
+ if (!TRIGGER_CREDENTIAL_BINDING_KEY_REGEX.test(key)) return false;
534
+ if (!CREDENTIAL_BINDING_VALUE_CREDSET.test(value) && !CREDENTIAL_BINDING_VALUE_SCOPE_DEFAULT.test(value)) return false;
535
+ }
536
+ return true;
537
+ }, { message: "triggerCredentialBindings keys must be \"<callbackName>:<credentialSetResolvedId>\"; values must be credential set ID (cset_...) or \"<scope>.default\"" }).optional();
538
+ z.object({
539
+ workflowName: z.string().min(1),
540
+ args: z.array(z.unknown()).optional().default([]),
541
+ /** Organization ID is required for multi-tenant isolation */
542
+ organizationId: z.string().min(1),
543
+ /** User ID for user scope credential resolution (optional) */
544
+ userId: z.string().optional(),
545
+ /**
546
+ * Explicit credential bindings: maps credential set resolved ID to credential set ID.
547
+ * When specified, uses the given credential set instead of the default.
548
+ * Example: { "keystroke:slack": "cset_abc123", "keystroke:anthropic": "cset_def456" }
549
+ */
550
+ credentials: z.record(z.string(), z.string()).optional()
551
+ });
552
+ PaginationQuerySchema.extend({
553
+ authoredWorkflowId: z.string().optional(),
554
+ workflowName: z.string().optional(),
555
+ status: z.string().optional()
556
+ }).strict();
557
+ const PausedRunTypeSchema = z.enum(["wait", "hook"]);
558
+ PaginationQuerySchema.extend({
559
+ authoredWorkflowId: z.string().optional(),
560
+ workflowName: z.string().optional(),
561
+ type: PausedRunTypeSchema.optional()
562
+ });
563
+ z.object({ id: z.string().min(1) });
564
+ z.object({ runId: z.string().min(1) });
565
+ z.object({
566
+ runId: z.string().min(1),
567
+ correlationId: z.string().min(1)
568
+ });
569
+ z.object({
570
+ runId: z.string().min(1),
571
+ correlationId: z.string().min(1)
572
+ });
573
+ z.object({ reason: z.string().optional() });
574
+ z.object({
575
+ stepId: z.string().min(1).optional(),
576
+ correlationId: z.string().min(1).optional(),
577
+ level: LogLevelSchema.optional(),
578
+ limit: z.coerce.number().int().min(1).max(1e3).optional().default(200),
579
+ offset: z.coerce.number().int().min(0).optional().default(0)
580
+ }).strict();
581
+ PaginationQuerySchema.extend({
582
+ projectId: z.union([z.uuid(), z.array(z.uuid())]).optional(),
583
+ tags: z.union([z.string(), z.array(z.string())]).optional()
584
+ });
585
+ z.object({ id: z.string().min(1) });
586
+ NewWorkflowSchema.omit({ organizationId: true });
587
+ NewWorkflowSchema.omit({ organizationId: true }).partial();
588
+ PaginationQuerySchema.extend({ projectId: z.union([z.uuid(), z.array(z.uuid())]).optional() });
589
+ z.object({ id: z.string().startsWith("sdef_") });
590
+ NewStepSchema.omit({ organizationId: true });
591
+ NewStepSchema.omit({ organizationId: true }).partial();
592
+ z.object({
593
+ id: z.string().startsWith("sdef_"),
594
+ version: z.coerce.number().int().positive()
595
+ });
596
+ z.object({
597
+ activationId: z.string().startsWith("tact_"),
598
+ args: z.array(z.unknown()).optional().default([]),
599
+ credentialOverrides: z.record(z.string(), z.string()).optional(),
600
+ runAsUserId: z.uuid().optional()
601
+ }).strict();
602
+ z.object({
603
+ projectId: z.uuid(),
604
+ authoredWorkflowId: z.string().min(1),
605
+ args: z.array(z.unknown()).optional().default([]),
606
+ /** Optional credential overrides: maps credential set resolved ID to credential set ID */
607
+ credentialBindings: z.record(z.string(), z.string()).optional(),
608
+ workflowGlobals: z.unknown().optional()
609
+ }).strict();
610
+ z.object({
611
+ workflowName: z.string().min(1),
612
+ storagePath: z.string().min(1),
613
+ exportName: z.string().min(1),
614
+ manifest: WorkflowManifestSchema,
615
+ flowJson: FlowGraphSchema.optional(),
616
+ triggers: z.array(TriggerUploadDataSchema).optional(),
617
+ bundleHash: SHA256HashSchema,
618
+ bundleSize: z.number(),
619
+ args: z.array(z.unknown()).optional().default([]),
620
+ credentialBindings: z.record(z.string(), z.string()).optional(),
621
+ /** Organization ID from keystroke.config.ts. Required for workflow test. */
622
+ organizationId: ProjectBaseSchema.shape.organizationId,
623
+ /** Project UUID from keystroke.config.ts. Required for workflow test. */
624
+ projectId: z.uuid()
625
+ }).strict();
626
+ z.object({ storagePath: z.string().min(1) }).strict();
627
+ PaginationQuerySchema.extend({
628
+ logicalTriggerKey: z.string().optional(),
629
+ status: ActivationStatusSchema.optional()
630
+ });
631
+ z.object({
632
+ allowed: z.boolean(),
633
+ required: z.boolean(),
634
+ reason: z.string().optional()
635
+ });
636
+ z.object({
637
+ id: z.uuid(),
638
+ activationId: z.string().startsWith("tact_")
639
+ });
640
+ z.object({
641
+ workflowId: z.string().uuid(),
642
+ logicalTriggerKey: z.string().min(1),
643
+ status: ActivationStatusSchema.optional(),
644
+ userId: z.uuid().nullable().optional(),
645
+ workflowCredentialBindings: WorkflowCredentialBindingsRecordSchema,
646
+ triggerCredentialBindings: TriggerCredentialBindingsRecordSchema,
647
+ config: z.unknown().optional(),
648
+ workflowGlobals: z.unknown().optional(),
649
+ state: z.unknown().optional(),
650
+ nextRunAt: z.string().datetime().nullable().optional()
651
+ }).strict();
652
+ z.object({
653
+ status: ActivationStatusSchema.optional(),
654
+ userId: z.uuid().nullable().optional(),
655
+ workflowCredentialBindings: WorkflowCredentialBindingsRecordSchema,
656
+ triggerCredentialBindings: TriggerCredentialBindingsRecordSchema,
657
+ config: z.unknown().optional(),
658
+ workflowGlobals: z.unknown().optional(),
659
+ state: z.unknown().optional(),
660
+ nextRunAt: z.string().datetime().nullable().optional()
661
+ }).strict();
662
+ z.object({
663
+ status: z.enum(["active", "paused"]).optional(),
664
+ workflowCredentialBindings: WorkflowCredentialBindingsRecordSchema,
665
+ triggerCredentialBindings: TriggerCredentialBindingsRecordSchema,
666
+ config: z.unknown().optional(),
667
+ workflowGlobals: z.unknown().optional(),
668
+ state: z.unknown().optional(),
669
+ nextRunAt: z.string().datetime().nullable().optional()
670
+ }).strict();
671
+ z.object({ mutations: z.array(WorkflowMutationSchema).min(1) });
672
+ //#endregion
673
+ //#region src/commands/workflows/paused/paused.command.ts
674
+ const WorkflowsPausedOptionsSchema = JsonOptionSchema.extend({
675
+ workflow: z.string().optional(),
676
+ type: PausedRunTypeSchema.optional(),
677
+ limit: z.coerce.number().int().min(1).max(100).default(20)
678
+ });
679
+ const PAUSED_OPTIONS_CONFIG = {
680
+ ...JSON_OPTION_CONFIG,
681
+ type: {
682
+ flag: "--type <type>",
683
+ description: "Filter paused runs to active waits or hooks"
684
+ },
685
+ limit: {
686
+ flag: "--limit <n>",
687
+ description: "Maximum paused runs to display (default: 20)"
688
+ }
689
+ };
690
+ function createWorkflowsPausedCommand() {
691
+ return createTypedCommand({
692
+ name: "paused",
693
+ description: "List workflow runs paused on active waits or hooks",
694
+ schema: WorkflowsPausedOptionsSchema,
695
+ optionsConfig: PAUSED_OPTIONS_CONFIG,
696
+ argument: {
697
+ name: "workflow",
698
+ description: "Optional authored workflow id or workflow name",
699
+ key: "workflow",
700
+ required: false
701
+ },
702
+ loadHandler: async () => (await import("./paused.handler-BMFm9Cff.mjs")).handleWorkflowsPaused
703
+ });
704
+ }
705
+ //#endregion
706
+ //#region src/commands/workflows/try-deploy.command.ts
707
+ function createWorkflowsTryDeployCommand() {
708
+ return createTypedCommand({
709
+ name: "try-deploy",
710
+ description: "Build, upload, and run a workflow on the server",
711
+ schema: WorkflowsRunOptionsSchema,
712
+ optionsConfig: RUN_OPTIONS_CONFIG,
713
+ argument: {
714
+ name: "workflow",
715
+ description: "Authored workflow id (preferred) or workflow name. Multiple workflows with the same name run sequentially.",
716
+ key: "workflow"
717
+ },
718
+ loadHandler: async () => (await import("./try-deploy.handler-DqybNhXx.mjs").then((n) => n.n)).handleWorkflowsTryDeploy
719
+ });
720
+ }
721
+ //#endregion
722
+ //#region src/commands/workflows/validate/validate.command.ts
723
+ const WorkflowsValidateOptionsSchema = JsonOptionSchema.extend({
724
+ workflow: z.string().optional(),
725
+ path: z.string().optional(),
726
+ verbose: z.boolean().optional().default(false),
727
+ typecheck: z.boolean().default(true)
728
+ });
729
+ const VALIDATE_OPTIONS_CONFIG = {
730
+ ...JSON_OPTION_CONFIG,
731
+ path: {
732
+ flag: "--path <dir>",
733
+ description: "Path to project root; auto-discovered from CWD if omitted"
734
+ },
735
+ verbose: {
736
+ flag: "--verbose",
737
+ description: "Show detailed validation logs"
738
+ },
739
+ typecheck: {
740
+ flag: "--no-typecheck",
741
+ description: "Deprecated no-op retained for validate command compatibility"
742
+ }
743
+ };
744
+ function createWorkflowsValidateCommand() {
745
+ return createTypedCommand({
746
+ name: "validate",
747
+ description: "Run static analysis and type-checking on workflows without building",
748
+ schema: WorkflowsValidateOptionsSchema,
749
+ optionsConfig: VALIDATE_OPTIONS_CONFIG,
750
+ argument: {
751
+ name: "workflow",
752
+ description: "Authored workflow id (preferred) or workflow name — omit to validate all",
753
+ key: "workflow",
754
+ required: false
755
+ },
756
+ loadHandler: async () => (await import("./validate.handler-DOcTaJL0.mjs")).handleWorkflowsValidate
757
+ });
758
+ }
759
+ //#endregion
760
+ //#region src/commands/workflows/workflows.command.ts
761
+ const WorkflowsOptionsSchema = JsonOptionSchema.extend({ path: z.string().optional() });
762
+ const WORKFLOWS_OPTIONS_CONFIG = {
763
+ ...JSON_OPTION_CONFIG,
764
+ path: {
765
+ flag: "--path <dir>",
766
+ description: "Path to project root (directory containing keystroke.config.ts); auto-discovered from CWD if omitted"
767
+ }
768
+ };
769
+ function createWorkflowsCommand() {
770
+ const cmd = createTypedCommand({
771
+ name: "workflows",
772
+ description: "Manage, run, inspect, and debug workflows",
773
+ schema: WorkflowsOptionsSchema,
774
+ optionsConfig: WORKFLOWS_OPTIONS_CONFIG,
775
+ loadHandler: async () => (await import("./list.handler-BTWvCyjA.mjs")).handleWorkflowsList,
776
+ subcommands: [
777
+ createTypedCommand({
778
+ name: "list",
779
+ description: "List all workflows in the project",
780
+ schema: WorkflowsOptionsSchema,
781
+ optionsConfig: WORKFLOWS_OPTIONS_CONFIG,
782
+ loadHandler: async () => (await import("./list.handler-BTWvCyjA.mjs")).handleWorkflowsList
783
+ }),
784
+ createWorkflowsBuildCommand(),
785
+ createWorkflowsTryDeployCommand(),
786
+ createWorkflowsInspectCommand(),
787
+ createWorkflowsValidateCommand(),
788
+ createWorkflowsDiffCommand(),
789
+ createWorkflowsEnvCommand(),
790
+ createWorkflowsLogsCommand(),
791
+ createWorkflowsPausedCommand()
792
+ ]
793
+ });
794
+ cmd.enablePositionalOptions();
795
+ cmd.passThroughOptions();
796
+ return cmd;
797
+ }
798
+ //#endregion
799
+ export { createWorkflowsCommand };