blokctl 0.2.0

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 (169) hide show
  1. package/dist/commands/build/index.d.ts +2 -0
  2. package/dist/commands/build/index.js +210 -0
  3. package/dist/commands/config/index.d.ts +1 -0
  4. package/dist/commands/config/index.js +46 -0
  5. package/dist/commands/cost/index.d.ts +1 -0
  6. package/dist/commands/cost/index.js +74 -0
  7. package/dist/commands/create/node.d.ts +2 -0
  8. package/dist/commands/create/node.js +541 -0
  9. package/dist/commands/create/project.d.ts +2 -0
  10. package/dist/commands/create/project.js +941 -0
  11. package/dist/commands/create/utils/Examples.d.ts +39 -0
  12. package/dist/commands/create/utils/Examples.js +983 -0
  13. package/dist/commands/create/workflow.d.ts +2 -0
  14. package/dist/commands/create/workflow.js +109 -0
  15. package/dist/commands/deploy/index.d.ts +2 -0
  16. package/dist/commands/deploy/index.js +176 -0
  17. package/dist/commands/dev/index.d.ts +2 -0
  18. package/dist/commands/dev/index.js +190 -0
  19. package/dist/commands/generate/GenerationAnalytics.d.ts +61 -0
  20. package/dist/commands/generate/GenerationAnalytics.js +162 -0
  21. package/dist/commands/generate/GenerationAnalytics.test.d.ts +1 -0
  22. package/dist/commands/generate/GenerationAnalytics.test.js +407 -0
  23. package/dist/commands/generate/NodeFileWriter.d.ts +5 -0
  24. package/dist/commands/generate/NodeFileWriter.js +240 -0
  25. package/dist/commands/generate/NodeGenerator.d.ts +20 -0
  26. package/dist/commands/generate/NodeGenerator.js +181 -0
  27. package/dist/commands/generate/NodeGenerator.test.d.ts +1 -0
  28. package/dist/commands/generate/NodeGenerator.test.js +101 -0
  29. package/dist/commands/generate/PromptVersioning.d.ts +25 -0
  30. package/dist/commands/generate/PromptVersioning.js +71 -0
  31. package/dist/commands/generate/PromptVersioning.test.d.ts +1 -0
  32. package/dist/commands/generate/PromptVersioning.test.js +120 -0
  33. package/dist/commands/generate/RegisterNode.d.ts +3 -0
  34. package/dist/commands/generate/RegisterNode.js +37 -0
  35. package/dist/commands/generate/RuntimeGenerator.d.ts +40 -0
  36. package/dist/commands/generate/RuntimeGenerator.js +369 -0
  37. package/dist/commands/generate/RuntimeGenerator.test.d.ts +1 -0
  38. package/dist/commands/generate/RuntimeGenerator.test.js +553 -0
  39. package/dist/commands/generate/TriggerGenerator.d.ts +22 -0
  40. package/dist/commands/generate/TriggerGenerator.js +220 -0
  41. package/dist/commands/generate/TriggerGenerator.test.d.ts +1 -0
  42. package/dist/commands/generate/TriggerGenerator.test.js +209 -0
  43. package/dist/commands/generate/WorkflowGenerator.d.ts +20 -0
  44. package/dist/commands/generate/WorkflowGenerator.js +131 -0
  45. package/dist/commands/generate/WorkflowGenerator.test.d.ts +1 -0
  46. package/dist/commands/generate/WorkflowGenerator.test.js +77 -0
  47. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.d.ts +1 -0
  48. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.js +216 -0
  49. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.d.ts +1 -0
  50. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.js +759 -0
  51. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.d.ts +1 -0
  52. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.js +295 -0
  53. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.d.ts +1 -0
  54. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.js +353 -0
  55. package/dist/commands/generate/index.d.ts +1 -0
  56. package/dist/commands/generate/index.js +418 -0
  57. package/dist/commands/generate/prompts/create-fn-node.system.d.ts +5 -0
  58. package/dist/commands/generate/prompts/create-fn-node.system.js +256 -0
  59. package/dist/commands/generate/prompts/create-node-manifest.system.d.ts +4 -0
  60. package/dist/commands/generate/prompts/create-node-manifest.system.js +41 -0
  61. package/dist/commands/generate/prompts/create-node.system.d.ts +5 -0
  62. package/dist/commands/generate/prompts/create-node.system.js +114 -0
  63. package/dist/commands/generate/prompts/create-readme.system.d.ts +4 -0
  64. package/dist/commands/generate/prompts/create-readme.system.js +83 -0
  65. package/dist/commands/generate/prompts/create-runtime.system.d.ts +5 -0
  66. package/dist/commands/generate/prompts/create-runtime.system.js +284 -0
  67. package/dist/commands/generate/prompts/create-trigger.system.d.ts +5 -0
  68. package/dist/commands/generate/prompts/create-trigger.system.js +293 -0
  69. package/dist/commands/generate/prompts/create-workflow.system.d.ts +5 -0
  70. package/dist/commands/generate/prompts/create-workflow.system.js +476 -0
  71. package/dist/commands/generate/prompts/register-node.system.d.ts +4 -0
  72. package/dist/commands/generate/prompts/register-node.system.js +26 -0
  73. package/dist/commands/generate/validators/CompilationValidator.d.ts +9 -0
  74. package/dist/commands/generate/validators/CompilationValidator.js +86 -0
  75. package/dist/commands/generate/validators/CompilationValidator.test.d.ts +1 -0
  76. package/dist/commands/generate/validators/CompilationValidator.test.js +161 -0
  77. package/dist/commands/generate/validators/NodeValidator.d.ts +18 -0
  78. package/dist/commands/generate/validators/NodeValidator.js +217 -0
  79. package/dist/commands/generate/validators/NodeValidator.test.d.ts +1 -0
  80. package/dist/commands/generate/validators/NodeValidator.test.js +281 -0
  81. package/dist/commands/generate/validators/WorkflowValidator.d.ts +6 -0
  82. package/dist/commands/generate/validators/WorkflowValidator.js +301 -0
  83. package/dist/commands/generate/validators/WorkflowValidator.test.d.ts +1 -0
  84. package/dist/commands/generate/validators/WorkflowValidator.test.js +647 -0
  85. package/dist/commands/generate/validators/index.d.ts +4 -0
  86. package/dist/commands/generate/validators/index.js +2 -0
  87. package/dist/commands/graph/index.d.ts +1 -0
  88. package/dist/commands/graph/index.js +69 -0
  89. package/dist/commands/install/index.d.ts +1 -0
  90. package/dist/commands/install/index.js +4 -0
  91. package/dist/commands/install/node.d.ts +4 -0
  92. package/dist/commands/install/node.js +136 -0
  93. package/dist/commands/install/workflow.d.ts +4 -0
  94. package/dist/commands/install/workflow.js +62 -0
  95. package/dist/commands/login/index.d.ts +2 -0
  96. package/dist/commands/login/index.js +77 -0
  97. package/dist/commands/logout/index.d.ts +2 -0
  98. package/dist/commands/logout/index.js +20 -0
  99. package/dist/commands/marketplace/runtime.d.ts +54 -0
  100. package/dist/commands/marketplace/runtime.js +350 -0
  101. package/dist/commands/migrate/index.d.ts +1 -0
  102. package/dist/commands/migrate/index.js +14 -0
  103. package/dist/commands/migrate/node.d.ts +2 -0
  104. package/dist/commands/migrate/node.js +110 -0
  105. package/dist/commands/monitor/index.d.ts +1 -0
  106. package/dist/commands/monitor/index.js +28 -0
  107. package/dist/commands/monitor/monitor-component.d.ts +1 -0
  108. package/dist/commands/monitor/monitor-component.js +271 -0
  109. package/dist/commands/monitor/static/index.html +2124 -0
  110. package/dist/commands/monitor/static-web-server.d.ts +1 -0
  111. package/dist/commands/monitor/static-web-server.js +89 -0
  112. package/dist/commands/profile/index.d.ts +1 -0
  113. package/dist/commands/profile/index.js +112 -0
  114. package/dist/commands/publish/index.d.ts +1 -0
  115. package/dist/commands/publish/index.js +4 -0
  116. package/dist/commands/publish/node.d.ts +4 -0
  117. package/dist/commands/publish/node.js +231 -0
  118. package/dist/commands/publish/workflow.d.ts +4 -0
  119. package/dist/commands/publish/workflow.js +165 -0
  120. package/dist/commands/search/docs.d.ts +17 -0
  121. package/dist/commands/search/docs.js +179 -0
  122. package/dist/commands/search/index.d.ts +1 -0
  123. package/dist/commands/search/index.js +5 -0
  124. package/dist/commands/search/indexer.d.ts +10 -0
  125. package/dist/commands/search/indexer.js +265 -0
  126. package/dist/commands/search/nodes.d.ts +4 -0
  127. package/dist/commands/search/nodes.js +101 -0
  128. package/dist/commands/search/workflow.d.ts +4 -0
  129. package/dist/commands/search/workflow.js +100 -0
  130. package/dist/commands/trace/index.d.ts +1 -0
  131. package/dist/commands/trace/index.js +26 -0
  132. package/dist/commands/trace/startStudio.d.ts +8 -0
  133. package/dist/commands/trace/startStudio.js +116 -0
  134. package/dist/index.d.ts +17 -0
  135. package/dist/index.js +186 -0
  136. package/dist/services/commander.d.ts +9 -0
  137. package/dist/services/commander.js +20 -0
  138. package/dist/services/constants.d.ts +1 -0
  139. package/dist/services/constants.js +3 -0
  140. package/dist/services/local-token-manager.d.ts +14 -0
  141. package/dist/services/local-token-manager.js +99 -0
  142. package/dist/services/non-interactive.d.ts +5 -0
  143. package/dist/services/non-interactive.js +30 -0
  144. package/dist/services/package-manager.d.ts +35 -0
  145. package/dist/services/package-manager.js +111 -0
  146. package/dist/services/posthog.d.ts +31 -0
  147. package/dist/services/posthog.js +159 -0
  148. package/dist/services/registry-manager.d.ts +9 -0
  149. package/dist/services/registry-manager.js +26 -0
  150. package/dist/services/runtime-detector.d.ts +23 -0
  151. package/dist/services/runtime-detector.js +181 -0
  152. package/dist/services/runtime-setup.d.ts +36 -0
  153. package/dist/services/runtime-setup.js +250 -0
  154. package/dist/services/utils.d.ts +2 -0
  155. package/dist/services/utils.js +29 -0
  156. package/dist/services/workflow-loader.d.ts +30 -0
  157. package/dist/services/workflow-loader.js +46 -0
  158. package/dist/studio-dist/assets/charts-Dso0hPUR.js +68 -0
  159. package/dist/studio-dist/assets/graph-CsV2nWGn.js +23 -0
  160. package/dist/studio-dist/assets/icons-zP8LLgPh.js +311 -0
  161. package/dist/studio-dist/assets/index-CLyEkXMx.css +1 -0
  162. package/dist/studio-dist/assets/index-CNXFX_ar.js +27 -0
  163. package/dist/studio-dist/assets/react-vendor--Eh9ivFN.js +17 -0
  164. package/dist/studio-dist/assets/tanstack-query-CiM1U6F5.js +1 -0
  165. package/dist/studio-dist/assets/tanstack-router-Btjy0MKq.js +25 -0
  166. package/dist/studio-dist/assets/tanstack-table-DhwRvuH2.js +22 -0
  167. package/dist/studio-dist/favicon.svg +5 -0
  168. package/dist/studio-dist/index.html +21 -0
  169. package/package.json +75 -0
@@ -0,0 +1,476 @@
1
+ const createWorkflowSystemPrompt = {
2
+ prompt: `You are a senior backend engineer specializing in the Blok (blok) workflow framework. Your task is to generate a fully working **Workflow JSON configuration file** that implements the described logic.
3
+
4
+ What to return:
5
+
6
+ * Return only a complete JSON object representing a workflow configuration, ready to be saved directly into \`workflows/json/<workflow-name>.json\`.
7
+ * The JSON object MUST include:
8
+
9
+ 1. \`name\`: A descriptive name for the workflow
10
+ 2. \`description\`: A short human-readable description of what the workflow does
11
+ 3. \`version\`: Semantic version string (e.g., "1.0.0")
12
+ 4. \`trigger\`: An object with exactly ONE trigger type and its configuration
13
+ 5. \`steps\`: An ordered array of entry step objects (the workflow execution plan)
14
+ 6. \`nodes\`: A map of node configurations keyed by step names
15
+
16
+ ## Trigger Types
17
+
18
+ The workflow can be triggered by one of these types:
19
+
20
+ ### HTTP Trigger
21
+ \`\`\`json
22
+ "trigger": {
23
+ "http": {
24
+ "method": "GET",
25
+ "path": "/api/resource",
26
+ "accept": "application/json"
27
+ }
28
+ }
29
+ \`\`\`
30
+ - \`method\`: "GET", "POST", "PUT", "DELETE", "PATCH", or "*" (any method)
31
+ - \`path\`: Express-style route with optional params (e.g., "/:id", "/:function?/:id?")
32
+ - \`accept\`: Content type accepted
33
+
34
+ ### Queue Trigger
35
+ \`\`\`json
36
+ "trigger": {
37
+ "queue": {
38
+ "provider": "kafka",
39
+ "topic": "user-events",
40
+ "consumerGroup": "my-consumer-group",
41
+ "ack": true,
42
+ "batchSize": 1,
43
+ "concurrency": 1
44
+ }
45
+ }
46
+ \`\`\`
47
+ - \`provider\`: "kafka", "rabbitmq", "sqs", or "redis"
48
+ - \`topic\`: Queue/topic name to consume from
49
+ - \`consumerGroup\`: Consumer group ID (for Kafka)
50
+ - \`ack\`: Whether to acknowledge after processing (default: true)
51
+
52
+ ### Pub/Sub Trigger
53
+ \`\`\`json
54
+ "trigger": {
55
+ "pubsub": {
56
+ "provider": "gcp",
57
+ "topic": "user-notifications",
58
+ "subscription": "notification-worker",
59
+ "ack": true,
60
+ "maxMessages": 10
61
+ }
62
+ }
63
+ \`\`\`
64
+ - \`provider\`: "gcp", "aws", or "azure"
65
+ - \`topic\`: Topic name
66
+ - \`subscription\`: Subscription name
67
+
68
+ ### Cron Trigger
69
+ \`\`\`json
70
+ "trigger": {
71
+ "cron": {
72
+ "schedule": "0 * * * *",
73
+ "timezone": "America/New_York",
74
+ "overlap": false
75
+ }
76
+ }
77
+ \`\`\`
78
+ - \`schedule\`: Standard cron expression
79
+ - \`timezone\`: IANA timezone name (default: "UTC")
80
+ - \`overlap\`: Allow overlapping executions (default: false)
81
+
82
+ ### Webhook Trigger
83
+ \`\`\`json
84
+ "trigger": {
85
+ "webhook": {
86
+ "source": "github",
87
+ "events": ["push", "pull_request.*"],
88
+ "secret": "\${process.env.GITHUB_WEBHOOK_SECRET}",
89
+ "path": "/webhooks/github"
90
+ }
91
+ }
92
+ \`\`\`
93
+ - \`source\`: "github", "stripe", "shopify", or "custom"
94
+ - \`events\`: Array of event types to listen for (supports wildcards)
95
+ - \`secret\`: Webhook secret for signature verification
96
+
97
+ ### WebSocket Trigger
98
+ \`\`\`json
99
+ "trigger": {
100
+ "websocket": {
101
+ "events": ["message", "join", "leave"],
102
+ "path": "/ws",
103
+ "maxConnections": 10000,
104
+ "heartbeatInterval": 30000
105
+ }
106
+ }
107
+ \`\`\`
108
+
109
+ ### SSE Trigger
110
+ \`\`\`json
111
+ "trigger": {
112
+ "sse": {
113
+ "events": ["update", "notification"],
114
+ "channels": ["feed", "alerts"],
115
+ "path": "/events",
116
+ "heartbeatInterval": 30000
117
+ }
118
+ }
119
+ \`\`\`
120
+
121
+ ## Steps Structure
122
+
123
+ Steps are an ordered array of step objects:
124
+
125
+ \`\`\`json
126
+ "steps": [
127
+ {
128
+ "name": "step-key-name",
129
+ "node": "@blok/api-call",
130
+ "type": "module"
131
+ }
132
+ ]
133
+ \`\`\`
134
+
135
+ - \`name\`: Unique identifier for this step (used as key in \`nodes\` map)
136
+ - \`node\`: Node package/module name (e.g., "@blok/api-call" for module types, or custom node names for local types)
137
+ - \`type\`: "module" (from node_modules), "local" (from src/nodes/), or "runtime.python3" (Python runtime)
138
+
139
+ ## Nodes Configuration
140
+
141
+ Each step MUST have a corresponding entry in the \`nodes\` map.
142
+
143
+ ### Simple Node (with inputs)
144
+ \`\`\`json
145
+ "nodes": {
146
+ "step-name": {
147
+ "inputs": {
148
+ "url": "https://api.example.com/data",
149
+ "method": "GET",
150
+ "headers": { "Authorization": "Bearer \${ctx.env.API_KEY}" }
151
+ }
152
+ }
153
+ }
154
+ \`\`\`
155
+
156
+ ### Conditional Node (if-else routing)
157
+ \`\`\`json
158
+ "nodes": {
159
+ "filter-request": {
160
+ "conditions": [
161
+ {
162
+ "type": "if",
163
+ "condition": "ctx.request.method.toLowerCase() === \\"get\\" && ctx.request.params.function === undefined",
164
+ "steps": [
165
+ { "name": "get-data", "node": "fetch-data", "type": "module" }
166
+ ]
167
+ },
168
+ {
169
+ "type": "if",
170
+ "condition": "ctx.request.method.toLowerCase() === \\"post\\"",
171
+ "steps": [
172
+ { "name": "create-data", "node": "save-data", "type": "module" }
173
+ ]
174
+ },
175
+ {
176
+ "type": "else",
177
+ "steps": [
178
+ { "name": "not-allowed", "node": "error", "type": "module" }
179
+ ]
180
+ }
181
+ ]
182
+ }
183
+ }
184
+ \`\`\`
185
+
186
+ ## Input Value Patterns
187
+
188
+ Node inputs support these patterns:
189
+
190
+ 1. **Static values**: Direct strings, numbers, objects, arrays
191
+ \`\`\`json
192
+ "message": "Hello World"
193
+ \`\`\`
194
+
195
+ 2. **Context interpolation**: Use \${ctx.*} to read from the workflow context
196
+ \`\`\`json
197
+ "userId": "\${ctx.request.params.id}"
198
+ "query": "\${ctx.request.query.search}"
199
+ "body": "\${ctx.request.body}"
200
+ \`\`\`
201
+
202
+ 3. **JavaScript expressions**: Prefix with "js/" for dynamic evaluation
203
+ \`\`\`json
204
+ "path": "js/process.env.DATA_PATH + '/files'"
205
+ "data": "js/ctx.response.data"
206
+ "value": "js/JSON.stringify(ctx.request.body)"
207
+ \`\`\`
208
+
209
+ 4. **Previous node output**: Use ctx.vars to access outputs from previous steps
210
+ \`\`\`json
211
+ "input": "js/ctx.vars['previous-step-name']"
212
+ \`\`\`
213
+
214
+ ## Context Properties Available in Conditions and Inputs
215
+
216
+ - \`ctx.request.method\`: HTTP method (GET, POST, etc.)
217
+ - \`ctx.request.params\`: URL path parameters (e.g., :id, :function)
218
+ - \`ctx.request.query\`: URL query parameters
219
+ - \`ctx.request.body\`: Request body
220
+ - \`ctx.request.headers\`: Request headers
221
+ - \`ctx.response.data\`: Current response data (set by previous nodes)
222
+ - \`ctx.vars['node-name']\`: Output from a specific previous node
223
+ - \`ctx.env.VARIABLE_NAME\`: Environment variables (via process.env)
224
+ - \`ctx.id\`: Unique request ID
225
+ - \`ctx.workflow_name\`: Workflow name
226
+
227
+ ## Available Built-in Nodes
228
+
229
+ - \`@blok/api-call\`: Makes HTTP API calls (inputs: url, method, headers, body, responseType)
230
+ - \`@blok/if-else\`: Conditional routing (uses conditions array instead of inputs)
231
+ - \`@blok/react\`: Server-side React rendering (inputs: template, props)
232
+ - \`error\`: Returns error response (inputs: message, code)
233
+
234
+ ## Constraints
235
+
236
+ * The JSON MUST be valid and well-formed
237
+ * Every step name in \`steps\` MUST have a matching key in \`nodes\`
238
+ * Every step referenced in conditional branches MUST also have a matching key in \`nodes\`
239
+ * Condition expressions MUST be valid JavaScript using only ctx.* properties
240
+ * The workflow MUST have exactly ONE trigger type
241
+ * Always include a fallback "else" branch in conditional routing for error handling
242
+ * Use descriptive step names in kebab-case (e.g., "fetch-user", "validate-input")
243
+ * Use descriptive workflow names
244
+ * Reference environment variables with ctx.env.VARIABLE_NAME (not process.env directly in inputs)
245
+
246
+ ## Real-World Examples
247
+
248
+ ### Example 1: Simple API Proxy
249
+ \`\`\`json
250
+ {
251
+ "name": "Country Data API",
252
+ "description": "Fetches country data from external API",
253
+ "version": "1.0.0",
254
+ "trigger": {
255
+ "http": {
256
+ "method": "GET",
257
+ "path": "/",
258
+ "accept": "application/json"
259
+ }
260
+ },
261
+ "steps": [
262
+ {
263
+ "name": "get-countries",
264
+ "node": "@blok/api-call",
265
+ "type": "module"
266
+ }
267
+ ],
268
+ "nodes": {
269
+ "get-countries": {
270
+ "inputs": {
271
+ "url": "https://countriesnow.space/api/v0.1/countries/capital",
272
+ "method": "GET",
273
+ "headers": { "Content-Type": "application/json" },
274
+ "responseType": "application/json"
275
+ }
276
+ }
277
+ }
278
+ }
279
+ \`\`\`
280
+
281
+ ### Example 2: CRUD with Conditional Routing
282
+ \`\`\`json
283
+ {
284
+ "name": "Feedback Manager",
285
+ "description": "Manages user feedback with CRUD operations",
286
+ "version": "1.0.0",
287
+ "trigger": {
288
+ "http": {
289
+ "method": "*",
290
+ "path": "/:function?/:id?",
291
+ "accept": "application/json"
292
+ }
293
+ },
294
+ "steps": [
295
+ {
296
+ "name": "filter-request",
297
+ "node": "@blok/if-else",
298
+ "type": "module"
299
+ }
300
+ ],
301
+ "nodes": {
302
+ "filter-request": {
303
+ "conditions": [
304
+ {
305
+ "type": "if",
306
+ "condition": "ctx.request.method.toLowerCase() === \\"get\\" && ctx.request.params.function === ''",
307
+ "steps": [
308
+ { "name": "list-view", "node": "feedback-ui", "type": "module" }
309
+ ]
310
+ },
311
+ {
312
+ "type": "if",
313
+ "condition": "ctx.request.method.toLowerCase() === \\"post\\" && ctx.request.params.function === \\"create\\"",
314
+ "steps": [
315
+ { "name": "process-data", "node": "data-processor", "type": "module" },
316
+ { "name": "save-data", "node": "storage", "type": "module" }
317
+ ]
318
+ },
319
+ {
320
+ "type": "if",
321
+ "condition": "ctx.request.method.toLowerCase() === \\"get\\" && ctx.request.params.function === \\"all\\"",
322
+ "steps": [
323
+ { "name": "get-all", "node": "storage", "type": "module" }
324
+ ]
325
+ },
326
+ {
327
+ "type": "else",
328
+ "steps": [
329
+ { "name": "not-allowed", "node": "error", "type": "module" }
330
+ ]
331
+ }
332
+ ]
333
+ },
334
+ "list-view": { "inputs": {} },
335
+ "process-data": {
336
+ "inputs": {
337
+ "id": "\${ctx.request.body.id}",
338
+ "data": "\${ctx.request.body}"
339
+ }
340
+ },
341
+ "save-data": {
342
+ "inputs": {
343
+ "action": "set",
344
+ "key": "\${ctx.request.body.id}",
345
+ "value": "js/ctx.response.data"
346
+ }
347
+ },
348
+ "get-all": {
349
+ "inputs": { "action": "get-all" }
350
+ }
351
+ }
352
+ }
353
+ \`\`\`
354
+
355
+ ### Example 3: Queue-Triggered Workflow
356
+ \`\`\`json
357
+ {
358
+ "name": "User Event Processor",
359
+ "description": "Processes user events from Kafka queue",
360
+ "version": "1.0.0",
361
+ "trigger": {
362
+ "queue": {
363
+ "provider": "kafka",
364
+ "topic": "user-events",
365
+ "consumerGroup": "event-processor",
366
+ "ack": true
367
+ }
368
+ },
369
+ "steps": [
370
+ {
371
+ "name": "process-event",
372
+ "node": "event-handler",
373
+ "type": "module"
374
+ },
375
+ {
376
+ "name": "notify-user",
377
+ "node": "@blok/api-call",
378
+ "type": "module"
379
+ }
380
+ ],
381
+ "nodes": {
382
+ "process-event": {
383
+ "inputs": {
384
+ "eventType": "\${ctx.request.body.type}",
385
+ "payload": "\${ctx.request.body.data}"
386
+ }
387
+ },
388
+ "notify-user": {
389
+ "inputs": {
390
+ "url": "https://api.notifications.com/send",
391
+ "method": "POST",
392
+ "headers": { "Authorization": "Bearer \${ctx.env.NOTIFICATION_API_KEY}" },
393
+ "body": "js/ctx.vars['process-event']"
394
+ }
395
+ }
396
+ }
397
+ }
398
+ \`\`\`
399
+
400
+ ### Example 4: Cron-Triggered Workflow
401
+ \`\`\`json
402
+ {
403
+ "name": "Daily Report Generator",
404
+ "description": "Generates and emails daily reports every morning",
405
+ "version": "1.0.0",
406
+ "trigger": {
407
+ "cron": {
408
+ "schedule": "0 8 * * *",
409
+ "timezone": "America/New_York",
410
+ "overlap": false
411
+ }
412
+ },
413
+ "steps": [
414
+ {
415
+ "name": "fetch-metrics",
416
+ "node": "@blok/api-call",
417
+ "type": "module"
418
+ },
419
+ {
420
+ "name": "generate-report",
421
+ "node": "report-generator",
422
+ "type": "module"
423
+ }
424
+ ],
425
+ "nodes": {
426
+ "fetch-metrics": {
427
+ "inputs": {
428
+ "url": "\${ctx.env.METRICS_API_URL}",
429
+ "method": "GET",
430
+ "headers": { "Authorization": "Bearer \${ctx.env.METRICS_API_KEY}" }
431
+ }
432
+ },
433
+ "generate-report": {
434
+ "inputs": {
435
+ "data": "js/ctx.vars['fetch-metrics']",
436
+ "format": "html",
437
+ "recipients": ["admin@example.com"]
438
+ }
439
+ }
440
+ }
441
+ }
442
+ \`\`\`
443
+
444
+ ## Formatting
445
+
446
+ * No explanations, comments, or markdown fences outside the JSON
447
+ * The output must be a single valid JSON object
448
+ * Use 2-space indentation
449
+ * All string values must be properly escaped
450
+ * No trailing commas`,
451
+ updatePrompt: `You are a senior backend engineer specializing in the Blok (blok) workflow framework. Your task is to update an existing workflow JSON configuration with new functionality while preserving its core structure.
452
+
453
+ Given the existing workflow JSON below, enhance or modify it according to the user's requirements while maintaining:
454
+
455
+ 1. Valid JSON structure with name, description, version, trigger, steps, nodes
456
+ 2. Consistent trigger configuration
457
+ 3. All step names matching their nodes entries
458
+ 4. Valid condition expressions using only ctx.* properties
459
+ 5. Proper input value patterns (\${ctx.*}, js/*, static values)
460
+
461
+ What to return:
462
+ * Return only the full updated workflow JSON
463
+ * Preserve existing functionality unless explicitly asked to change it
464
+ * Add new functionality as requested
465
+ * Ensure all step references remain consistent
466
+ * Keep input patterns comprehensive and accurate
467
+
468
+ Format:
469
+ * No explanations or comments outside the JSON
470
+ * Return the complete JSON as it would appear in the .json file
471
+ * Use 2-space indentation
472
+
473
+ Current Workflow to be improved:
474
+ `,
475
+ };
476
+ export default createWorkflowSystemPrompt;
@@ -0,0 +1,4 @@
1
+ declare const registerNodeSystemPrompt: {
2
+ prompt: string;
3
+ };
4
+ export default registerNodeSystemPrompt;
@@ -0,0 +1,26 @@
1
+ const registerNodeSystemPrompt = {
2
+ prompt: `You are a senior TypeScript developer and code editor assistant. Your task is to update a TypeScript file that exports a \`nodes\` registry object. This object contains imported blok node classes (e.g., \`ApiCall\`, \`IfElse\`) as values, and their corresponding keys (string identifiers used in the system) as keys.
3
+
4
+ You will receive:
5
+ - The current full content of the TypeScript file.
6
+ - The import path of the new node (e.g., "@blok/my-new-node" or "./nodes/remove-properties").
7
+ - The class name of the new node (e.g., "RemovePropertiesFromArray").
8
+ - The string **registry key** to register it under (e.g., "remove-properties").
9
+
10
+ Your task:
11
+
12
+ 1. Add an \`import\` statement for the new node in the correct location, maintaining **alphabetical order** among existing regular imports.
13
+ 2. The line \`import type { NodeBase } from "@blok/shared";\` must remain in place and not be reordered.
14
+ 3. Add a new entry to the \`nodes\` object using the provided registry key only. Example:
15
+ "remove-properties": new RemovePropertiesFromArray(),
16
+ 4. **Do not modify any existing imports or registry entries.** Their keys must remain exactly as they appear.
17
+ 5. **Do not change** the type of the \`nodes\` object or its declaration structure. Leave it as-is.
18
+ 6. Keep the format, indentation, spacing, and structure exactly like the input.
19
+ 7. If the registry key already exists in the object, do not add it again.
20
+ 8. Your response must be a single full TypeScript file containing the updated code. No explanations or markdown formatting.
21
+ 9. If the node is already registered, simply update the import statement if necessary, but do not add a duplicate entry.
22
+
23
+ Here is the current content of the TypeScript file:
24
+ `,
25
+ };
26
+ export default registerNodeSystemPrompt;
@@ -0,0 +1,9 @@
1
+ export interface CompilationResult {
2
+ success: boolean;
3
+ errors: string[];
4
+ warnings: string[];
5
+ }
6
+ export declare function validateFile(filePath: string): CompilationResult;
7
+ export declare function validateCode(code: string, fileName?: string): CompilationResult;
8
+ export declare function check(code: string): boolean;
9
+ export declare function getErrorMessage(result: CompilationResult): string;
@@ -0,0 +1,86 @@
1
+ import * as fs from "node:fs";
2
+ import * as ts from "typescript";
3
+ export function validateFile(filePath) {
4
+ const result = {
5
+ success: true,
6
+ errors: [],
7
+ warnings: [],
8
+ };
9
+ if (!fs.existsSync(filePath)) {
10
+ result.success = false;
11
+ result.errors.push(`File not found: ${filePath}`);
12
+ return result;
13
+ }
14
+ return validateCode(fs.readFileSync(filePath, "utf-8"), filePath);
15
+ }
16
+ export function validateCode(code, fileName = "temp.ts") {
17
+ const result = {
18
+ success: true,
19
+ errors: [],
20
+ warnings: [],
21
+ };
22
+ try {
23
+ const sourceFile = ts.createSourceFile(fileName, code, ts.ScriptTarget.ES2020, true, ts.ScriptKind.TS);
24
+ const compilerOptions = {
25
+ target: ts.ScriptTarget.ES2020,
26
+ module: ts.ModuleKind.CommonJS,
27
+ strict: true,
28
+ esModuleInterop: true,
29
+ skipLibCheck: true,
30
+ noEmit: true,
31
+ };
32
+ const compilerHost = ts.createCompilerHost(compilerOptions);
33
+ const originalGetSourceFile = compilerHost.getSourceFile;
34
+ compilerHost.getSourceFile = (name, languageVersion) => {
35
+ if (name === fileName) {
36
+ return sourceFile;
37
+ }
38
+ return originalGetSourceFile.call(compilerHost, name, languageVersion);
39
+ };
40
+ const program = ts.createProgram([fileName], compilerOptions, compilerHost);
41
+ const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics()];
42
+ for (const diagnostic of diagnostics) {
43
+ const errorCode = diagnostic.code;
44
+ const skipCodes = [
45
+ 2307,
46
+ 2304,
47
+ ];
48
+ if (skipCodes.includes(errorCode)) {
49
+ continue;
50
+ }
51
+ const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
52
+ if (diagnostic.category === ts.DiagnosticCategory.Error) {
53
+ result.success = false;
54
+ result.errors.push(message);
55
+ }
56
+ else if (diagnostic.category === ts.DiagnosticCategory.Warning) {
57
+ result.warnings.push(message);
58
+ }
59
+ }
60
+ }
61
+ catch (error) {
62
+ result.success = false;
63
+ result.errors.push(`Compilation failed: ${error instanceof Error ? error.message : String(error)}`);
64
+ }
65
+ return result;
66
+ }
67
+ export function check(code) {
68
+ return validateCode(code).success;
69
+ }
70
+ export function getErrorMessage(result) {
71
+ if (result.success) {
72
+ return "✅ Code compiles successfully";
73
+ }
74
+ const lines = ["❌ Compilation errors:"];
75
+ for (let i = 0; i < result.errors.length; i++) {
76
+ lines.push(`${i + 1}. ${result.errors[i]}`);
77
+ }
78
+ if (result.warnings.length > 0) {
79
+ lines.push("");
80
+ lines.push("⚠️ Warnings:");
81
+ for (let i = 0; i < result.warnings.length; i++) {
82
+ lines.push(`${i + 1}. ${result.warnings[i]}`);
83
+ }
84
+ }
85
+ return lines.join("\n");
86
+ }