windmill-cli 1.591.3 → 1.592.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 (35) hide show
  1. package/esm/gen/core/OpenAPI.js +1 -1
  2. package/esm/src/commands/app/app_metadata.js +1 -1
  3. package/esm/src/commands/app/dev.js +1 -1
  4. package/esm/src/commands/app/raw_apps.js +1 -1
  5. package/esm/src/commands/gitsync-settings/gitsync-settings.js +28 -2
  6. package/esm/src/commands/init/init.js +14 -15
  7. package/esm/src/commands/sync/sync.js +1 -1
  8. package/esm/src/core/settings.js +1 -1
  9. package/esm/src/guidance/flow_guidance.js +10 -429
  10. package/esm/src/guidance/prompts.js +2620 -0
  11. package/esm/src/guidance/script_guidance.js +9 -435
  12. package/esm/src/main.js +3 -3
  13. package/esm/src/types.js +1 -1
  14. package/package.json +1 -1
  15. package/types/src/commands/app/{apps.d.ts → app.d.ts} +1 -1
  16. package/types/src/commands/app/app.d.ts.map +1 -0
  17. package/types/src/commands/gitsync-settings/gitsync-settings.d.ts +24 -2
  18. package/types/src/commands/gitsync-settings/gitsync-settings.d.ts.map +1 -1
  19. package/types/src/commands/init/init.d.ts.map +1 -1
  20. package/types/src/commands/worker-groups/{worker_groups.d.ts → worker-groups.d.ts} +1 -1
  21. package/types/src/commands/worker-groups/{worker_groups.d.ts.map → worker-groups.d.ts.map} +1 -1
  22. package/types/src/guidance/flow_guidance.d.ts +1 -1
  23. package/types/src/guidance/flow_guidance.d.ts.map +1 -1
  24. package/types/src/guidance/prompts.d.ts +4 -0
  25. package/types/src/guidance/prompts.d.ts.map +1 -0
  26. package/types/src/guidance/script_guidance.d.ts +1 -1
  27. package/types/src/guidance/script_guidance.d.ts.map +1 -1
  28. package/types/src/main.d.ts +2 -2
  29. package/types/src/main.d.ts.map +1 -1
  30. package/esm/src/commands/gitsync-settings/index.js +0 -28
  31. package/types/src/commands/app/apps.d.ts.map +0 -1
  32. package/types/src/commands/gitsync-settings/index.d.ts +0 -25
  33. package/types/src/commands/gitsync-settings/index.d.ts.map +0 -1
  34. /package/esm/src/commands/app/{apps.js → app.js} +0 -0
  35. /package/esm/src/commands/worker-groups/{worker_groups.js → worker-groups.js} +0 -0
@@ -32,7 +32,7 @@ export const OpenAPI = {
32
32
  PASSWORD: undefined,
33
33
  TOKEN: getEnv("WM_TOKEN"),
34
34
  USERNAME: undefined,
35
- VERSION: '1.591.3',
35
+ VERSION: '1.592.0',
36
36
  WITH_CREDENTIALS: true,
37
37
  interceptors: {
38
38
  request: new Interceptors(),
@@ -8,7 +8,7 @@ import { generateHash, getHeaders, writeIfChanged } from "../../utils/utils.js";
8
8
  import { exts } from "../script/script.js";
9
9
  import { FSFSElement, yamlOptions } from "../sync/sync.js";
10
10
  import { loadRunnablesFromBackend, writeRunnableToBackend, } from "./raw_apps.js";
11
- import { replaceInlineScripts } from "./apps.js";
11
+ import { replaceInlineScripts } from "./app.js";
12
12
  import { newPathAssigner, newRawAppPathAssigner, } from "../../../windmill-utils-internal/src/path-utils/path-assigner.js";
13
13
  import { mergeConfigWithConfigFile } from "../../core/conf.js";
14
14
  import { resolveWorkspace } from "../../core/context.js";
@@ -13,7 +13,7 @@ import * as wmill from "../../../gen/services.gen.js";
13
13
  import { resolveWorkspace } from "../../core/context.js";
14
14
  import { requireLogin } from "../../core/auth.js";
15
15
  import { GLOBAL_CONFIG_OPT } from "../../core/conf.js";
16
- import { replaceInlineScripts } from "./apps.js";
16
+ import { replaceInlineScripts } from "./app.js";
17
17
  import { APP_BACKEND_FOLDER, inferRunnableSchemaFromFile, } from "./app_metadata.js";
18
18
  import { loadRunnablesFromBackend } from "./raw_apps.js";
19
19
  const DEFAULT_PORT = 4000;
@@ -6,7 +6,7 @@ import { colors, log, SEP, windmillUtils, yamlParseFile, yamlStringify, } from "
6
6
  import * as wmill from "../../../gen/services.gen.js";
7
7
  import path from "node:path";
8
8
  import { isSuperset } from "../../types.js";
9
- import { replaceInlineScripts, repopulateFields } from "./apps.js";
9
+ import { replaceInlineScripts, repopulateFields } from "./app.js";
10
10
  import { createBundle, detectFrameworks } from "./bundle.js";
11
11
  import { APP_BACKEND_FOLDER } from "./app_metadata.js";
12
12
  import { writeIfChanged } from "../../utils/utils.js";
@@ -1,2 +1,28 @@
1
- export { pullGitSyncSettings, pushGitSyncSettings } from "./index.js";
2
- export { default } from "./index.js";
1
+ import { Command } from "../../../deps.js";
2
+ import { pullGitSyncSettings } from "./pull.js";
3
+ import { pushGitSyncSettings } from "./push.js";
4
+ const command = new Command()
5
+ .description("Manage git-sync settings between local wmill.yaml and Windmill backend")
6
+ .command("pull")
7
+ .description("Pull git-sync settings from Windmill backend to local wmill.yaml")
8
+ .option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo)")
9
+ .option("--default", "Write settings to top-level defaults instead of overrides")
10
+ .option("--replace", "Replace existing settings (non-interactive mode)")
11
+ .option("--override", "Add branch-specific override (non-interactive mode)")
12
+ .option("--diff", "Show differences without applying changes")
13
+ .option("--json-output", "Output in JSON format")
14
+ .option("--with-backend-settings <json:string>", "Use provided JSON settings instead of querying backend (for testing)")
15
+ .option("--yes", "Skip interactive prompts and use default behavior")
16
+ .option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides")
17
+ .action(pullGitSyncSettings)
18
+ .command("push")
19
+ .description("Push git-sync settings from local wmill.yaml to Windmill backend")
20
+ .option("--repository <repo:string>", "Specify repository path (e.g., u/user/repo)")
21
+ .option("--diff", "Show what would be pushed without applying changes")
22
+ .option("--json-output", "Output in JSON format")
23
+ .option("--with-backend-settings <json:string>", "Use provided JSON settings instead of querying backend (for testing)")
24
+ .option("--yes", "Skip interactive prompts and use default behavior")
25
+ .option("--promotion <branch:string>", "Use promotionOverrides from the specified branch instead of regular overrides")
26
+ .action(pushGitSyncSettings);
27
+ export { pullGitSyncSettings, pushGitSyncSettings };
28
+ export default command;
@@ -5,6 +5,7 @@ import { SCRIPT_GUIDANCE } from "../../guidance/script_guidance.js";
5
5
  import { FLOW_GUIDANCE } from "../../guidance/flow_guidance.js";
6
6
  import { getActiveWorkspaceOrFallback } from "../workspace/workspace.js";
7
7
  import { generateRTNamespace } from "../resource-type/resource-type.js";
8
+ import { CLI_COMMANDS } from "../../guidance/prompts.js";
8
9
  /**
9
10
  * Bootstrap a windmill project with a wmill.yaml file
10
11
  */
@@ -168,20 +169,10 @@ async function initAction(opts) {
168
169
  try {
169
170
  const scriptGuidanceContent = SCRIPT_GUIDANCE;
170
171
  const flowGuidanceContent = FLOW_GUIDANCE;
171
- // Create .cursor/rules directory
172
- await dntShim.Deno.mkdir(".cursor/rules", { recursive: true });
173
- // Create windmill.mdc file
174
- if (!(await dntShim.Deno.stat(".cursor/rules/script.mdc").catch(() => null))) {
175
- await dntShim.Deno.writeTextFile(".cursor/rules/script.mdc", scriptGuidanceContent);
176
- log.info(colors.green("Created .cursor/rules/script.mdc"));
177
- }
178
- if (!(await dntShim.Deno.stat(".cursor/rules/flow.mdc").catch(() => null))) {
179
- await dntShim.Deno.writeTextFile(".cursor/rules/flow.mdc", flowGuidanceContent);
180
- log.info(colors.green("Created .cursor/rules/flow.mdc"));
181
- }
182
- // Create CLAUDE.md file
183
- if (!(await dntShim.Deno.stat("CLAUDE.md").catch(() => null))) {
184
- await dntShim.Deno.writeTextFile("CLAUDE.md", `
172
+ const cliCommandsContent = CLI_COMMANDS;
173
+ // Create AGENTS.md file
174
+ if (!(await dntShim.Deno.stat("AGENTS.md").catch(() => null))) {
175
+ await dntShim.Deno.writeTextFile("AGENTS.md", `
185
176
  You are a helpful assistant that can help with Windmill scripts and flows creation.
186
177
 
187
178
  ## Script Guidance
@@ -189,7 +180,15 @@ ${scriptGuidanceContent}
189
180
 
190
181
  ## Flow Guidance
191
182
  ${flowGuidanceContent}
192
- `);
183
+
184
+ ## CLI Commands
185
+ ${cliCommandsContent}
186
+ `);
187
+ log.info(colors.green("Created AGENTS.md"));
188
+ }
189
+ // Create CLAUDE.md file, referencing AGENTS.md
190
+ if (!(await dntShim.Deno.stat("CLAUDE.md").catch(() => null))) {
191
+ await dntShim.Deno.writeTextFile("CLAUDE.md", "Instructions are in @AGENTS.md");
193
192
  log.info(colors.green("Created CLAUDE.md"));
194
193
  }
195
194
  }
@@ -18,7 +18,7 @@ import { pushResource } from "../resource/resource.js";
18
18
  import { newPathAssigner, newRawAppPathAssigner, } from "../../../windmill-utils-internal/src/path-utils/path-assigner.js";
19
19
  import { extractInlineScripts as extractInlineScriptsForFlows } from "../../../windmill-utils-internal/src/inline-scripts/extractor.js";
20
20
  import { generateFlowLockInternal } from "../flow/flow_metadata.js";
21
- import { isExecutionModeAnonymous } from "../app/apps.js";
21
+ import { isExecutionModeAnonymous } from "../app/app.js";
22
22
  import { APP_BACKEND_FOLDER, generateAppLocksInternal, } from "../app/app_metadata.js";
23
23
  // Merge CLI options with effective settings, preserving CLI flags as overrides
24
24
  function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
@@ -5,7 +5,7 @@ import * as wmill from "../../gen/services.gen.js";
5
5
  import { compareInstanceObjects } from "../commands/instance/instance.js";
6
6
  import { isSuperset } from "../types.js";
7
7
  import { deepEqual } from "../utils/utils.js";
8
- import { removeWorkerPrefix } from "../commands/worker-groups/worker_groups.js";
8
+ import { removeWorkerPrefix } from "../commands/worker-groups/worker-groups.js";
9
9
  import { decrypt, encrypt } from "../utils/local_encryption.js";
10
10
  const INSTANCE_SETTINGS_PATH = "instance_settings.yaml";
11
11
  let instanceSettingsPath = INSTANCE_SETTINGS_PATH;
@@ -1,434 +1,15 @@
1
- export const FLOW_GUIDANCE = `
2
- ---
3
- alwaysApply: true
4
- ---
5
-
6
- # System Prompt: OpenFlow Workflow Generator
7
-
8
- You are an expert at creating OpenFlow YAML specifications for Windmill workflows.
1
+ // CLI Flow Guidance - Uses centralized prompts from system_prompts/
2
+ import * as prompts from "./prompts.js";
3
+ // CLI-specific introduction
4
+ const CLI_INTRO = `You are an expert at creating OpenFlow YAML specifications for Windmill workflows.
9
5
  OpenFlow is an open standard for defining workflows as directed acyclic graphs where each node represents a computation step.
10
- When asked to create a flow, ask the user in which folder he wants to put it if not specified. Then create a new folder in the specified folder, that ends with \`.flow\`. It should contain a \`.yaml\` file that contains the flow definition.
6
+ When asked to create a flow, ask the user in which folder he wants to put it if not specified. Then create a new folder in the specified folder, that ends with \`.flow\`. It should contain a \`.yaml\` file that contains the flow definition.
11
7
  For rawscript type module in the flow, the content key should start with "!inline" followed by the path of the script containing the code. It should be put in the same folder as the flow.
12
8
  For script type module, path should be the path of the script in the whole repository (not constrained to the flow folder).
13
- You do not need to create .lock and .yaml files manually. Instead, you should run \`wmill flow generate-locks --yes\` to create them.
14
- After writing the flow, you can ask the user if he wants to push the flow with \`wmill sync push\`. Both should be run at the root of the repository.
15
-
16
- ## OpenFlow Structure
17
-
18
- Every OpenFlow workflow must follow this root structure:
19
-
20
- \`\`\`yaml
21
- summary: "Brief one-line description"
22
- description: "Optional detailed description"
23
- value:
24
- modules: [] # Array of workflow steps
25
- # Optional properties:
26
- failure_module: {} # Error handler
27
- preprocessor_module: {} # Runs before first step
28
- same_worker: false # Force same worker execution
29
- concurrent_limit: 0 # Limit concurrent executions
30
- concurrency_key: "string" # Custom concurrency grouping
31
- concurrency_time_window_s: 0
32
- custom_debounce_key: "key"
33
- debounce_delay_s: 0
34
- skip_expr: "javascript_expression" # Skip workflow condition
35
- cache_ttl: 0 # Cache results duration
36
- priority: 0 # Execution priority
37
- early_return: "javascript_expression" # Early termination condition
38
- schema: # JSON Schema for workflow inputs
39
- type: object
40
- properties: {}
41
- required: []
42
- \`\`\`
43
-
44
- ## Module Types
45
-
46
- ### 1. RawScript (Inline Code)
47
- \`\`\`yaml
48
- id: unique_step_id
49
- value:
50
- type: rawscript
51
- content: '!inline inline_script_1.inline_script.ts'
52
- language: bun|deno|python3|go|bash|powershell|postgresql|mysql|bigquery|snowflake|mssql|oracledb|graphql|nativets|php
53
- input_transforms:
54
- param1:
55
- type: javascript|static
56
- expr: "flow_input.name" # or for static: value: "fixed_value"
57
- # Optional properties:
58
- path: "optional/path"
59
- lock: "dependency_lock_content"
60
- tag: "version_tag"
61
- concurrent_limit: 0
62
- concurrency_time_window_s: 0
63
- custom_concurrency_key: "key"
64
- custom_debounce_key: "key"
65
- debounce_delay_s: 0
66
- is_trigger: false
67
- assets: []
68
- \`\`\`
69
-
70
- ### 2. PathScript (Reference to Existing Script)
71
- \`\`\`yaml
72
- id: step_id
73
- value:
74
- type: script
75
- path: "u/user/script_name" # or "f/folder/script_name" or "hub/script_path"
76
- input_transforms:
77
- param_name:
78
- type: javascript
79
- expr: "results.previous_step"
80
- # Optional:
81
- hash: "specific_version_hash"
82
- tag_override: "version_tag"
83
- is_trigger: false
84
- \`\`\`
85
-
86
- ### 3. PathFlow (Sub-workflow)
87
- \`\`\`yaml
88
- id: step_id
89
- value:
90
- type: flow
91
- path: "f/folder/flow_name"
92
- input_transforms:
93
- param_name:
94
- type: static
95
- value: "fixed_value"
96
- \`\`\`
97
-
98
- ### 4. ForLoop
99
- \`\`\`yaml
100
- id: loop_step
101
- value:
102
- type: forloopflow
103
- iterator:
104
- type: javascript
105
- expr: "flow_input.items" # Must evaluate to array
106
- skip_failures: true|false
107
- parallel: true|false # Run iterations in parallel
108
- parallelism: 4 # Max parallel iterations (if parallel: true)
109
- modules:
110
- - id: loop_body_step
111
- value:
112
- type: rawscript
113
- content: |
114
- export async function main(iter: any) {
115
- // iter.value contains current item
116
- // iter.index contains current index
117
- return iter.value;
118
- }
119
- language: bun
120
- input_transforms:
121
- iter:
122
- type: javascript
123
- expr: "flow_input.iter"
124
- \`\`\`
125
-
126
- ### 5. WhileLoop
127
- \`\`\`yaml
128
- id: while_step
129
- value:
130
- type: whileloopflow
131
- skip_failures: false
132
- parallel: false
133
- parallelism: 1
134
- modules:
135
- - id: condition_check
136
- value:
137
- type: rawscript
138
- content: |
139
- export async function main() {
140
- return Math.random() > 0.5; // Continue condition
141
- }
142
- language: bun
143
- input_transforms: {}
144
- \`\`\`
145
-
146
- ### 6. Conditional Branch (BranchOne)
147
- \`\`\`yaml
148
- id: branch_step
149
- value:
150
- type: branchone
151
- branches:
152
- - summary: "Condition 1"
153
- expr: "results.previous_step > 10"
154
- modules:
155
- - id: branch1_step
156
- value:
157
- type: rawscript
158
- content: "export async function main() { return 'branch1'; }"
159
- language: bun
160
- input_transforms: {}
161
- - summary: "Condition 2"
162
- expr: "results.previous_step <= 10"
163
- modules:
164
- - id: branch2_step
165
- value:
166
- type: rawscript
167
- content: "export async function main() { return 'branch2'; }"
168
- language: bun
169
- input_transforms: {}
170
- default: # Runs if no branch condition matches
171
- - id: default_step
172
- value:
173
- type: rawscript
174
- content: "export async function main() { return 'default'; }"
175
- language: bun
176
- input_transforms: {}
177
- \`\`\`
178
-
179
- ### 7. Parallel Branches (BranchAll)
180
- \`\`\`yaml
181
- id: parallel_step
182
- value:
183
- type: branchall
184
- parallel: true # Run branches in parallel
185
- branches:
186
- - summary: "Branch A"
187
- skip_failure: false # Continue if this branch fails
188
- modules:
189
- - id: branch_a_step
190
- value:
191
- type: rawscript
192
- content: "export async function main() { return 'A'; }"
193
- language: bun
194
- input_transforms: {}
195
- - summary: "Branch B"
196
- skip_failure: true
197
- modules:
198
- - id: branch_b_step
199
- value:
200
- type: rawscript
201
- content: "export async function main() { return 'B'; }"
202
- language: bun
203
- input_transforms: {}
204
- \`\`\`
205
-
206
- ### 8. Identity (Pass-through)
207
- \`\`\`yaml
208
- id: identity_step
209
- value:
210
- type: identity
211
- flow: false # Set to true if this represents a sub-flow
212
- \`\`\`
213
-
214
- ## Input Transforms & Data Flow
215
-
216
- ### JavaScript Expressions
217
- Reference data using these variables in \`expr\` fields:
218
- - \`flow_input.property_name\` - Access workflow inputs
219
- - \`results.step_id\` - Access outputs from previous steps
220
- - \`results.step_id.property\` - Access specific properties
221
- - \`flow_input.iter.value\` - Current iteration value (in loops)
222
- - \`flow_input.iter.index\` - Current iteration index (in loops)
223
-
224
- ### Static Values
225
- \`\`\`yaml
226
- input_transforms:
227
- param_name:
228
- type: static
229
- value: "fixed_string" # Can be string, number, boolean, object, array
230
- \`\`\`
231
-
232
- ### Resource References
233
- \`\`\`yaml
234
- input_transforms:
235
- database:
236
- type: static
237
- value: "$res:f/folder/my_database" # Reference to stored resource
238
- \`\`\`
239
-
240
- ## Advanced Module Properties
241
-
242
- ### Error Handling & Control Flow
243
- \`\`\`yaml
244
- id: step_id
245
- value: # ... module definition
246
- # Control flow options:
247
- stop_after_if:
248
- expr: "results.step_id.should_stop"
249
- skip_if_stopped: true
250
- error_message: "Custom stop message"
251
- stop_after_all_iters_if: # For loops only
252
- expr: "results.step_id.should_stop_loop"
253
- skip_if_stopped: false
254
- skip_if:
255
- expr: "results.step_id.should_skip"
256
- sleep:
257
- type: javascript
258
- expr: "flow_input.delay_seconds"
259
- continue_on_error: false # Continue workflow if this step fails
260
- delete_after_use: false # Clean up results after use
261
-
262
- # Execution control:
263
- cache_ttl: 3600 # Cache results for 1 hour
264
- timeout: 300 # Step timeout in seconds
265
- priority: 0 # Higher numbers = higher priority
266
- mock:
267
- enabled: false
268
- return_value: "mocked_result"
269
-
270
- # Suspend/Approval:
271
- suspend:
272
- required_events: 1 # Number of resume events needed
273
- timeout: 86400 # Timeout in seconds
274
- resume_form:
275
- schema:
276
- type: object
277
- properties:
278
- approved:
279
- type: boolean
280
- user_auth_required: true
281
- user_groups_required:
282
- type: static
283
- value: ["admin"]
284
- self_approval_disabled: false
285
- hide_cancel: false
286
- continue_on_disapprove_timeout: false
287
-
288
- # Retry configuration:
289
- retry:
290
- constant:
291
- attempts: 3
292
- seconds: 5
293
- # OR exponential backoff:
294
- # exponential:
295
- # attempts: 3
296
- # multiplier: 2
297
- # seconds: 1
298
- # random_factor: 10 # 0-100% jitter
299
- \`\`\`
300
-
301
- ## Special Modules
302
-
303
- ### Failure Handler (Error Handler)
304
- \`\`\`yaml
305
- value:
306
- failure_module:
307
- id: failure
308
- value:
309
- type: rawscript
310
- content: |
311
- export async function main(error: any) {
312
- // error.message, error.step_id, error.name, error.stack
313
- console.log("Flow failed:", error.message);
314
- return error;
315
- }
316
- language: bun
317
- input_transforms: {}
318
- \`\`\`
319
-
320
- ### Preprocessor
321
- \`\`\`yaml
322
- value:
323
- preprocessor_module:
324
- id: preprocessor
325
- value:
326
- type: rawscript
327
- content: |
328
- export async function main() {
329
- console.log("Flow starting...");
330
- return "preprocessed";
331
- }
332
- language: bun
333
- input_transforms: {}
334
- \`\`\`
335
-
336
- ## Schema Definition
337
- \`\`\`yaml
338
- schema:
339
- $schema: "https://json-schema.org/draft/2020-12/schema"
340
- type: object
341
- properties:
342
- name:
343
- type: string
344
- description: "User name"
345
- default: ""
346
- email:
347
- type: string
348
- format: email
349
- count:
350
- type: integer
351
- minimum: 1
352
- maximum: 100
353
- database:
354
- type: object
355
- format: "resource-postgresql" # Resource type reference
356
- items:
357
- type: array
358
- items:
359
- type: string
360
- required: ["name", "email"]
361
- order: ["name", "email", "count"] # UI field order
362
- \`\`\`
363
-
364
- ## Best Practices
365
-
366
- 1. **Step IDs**: Use descriptive, unique identifiers (alphanumeric + underscores)
367
- 2. **Data Flow**: Chain steps using \`results.step_id\` references
368
- 3. **Error Handling**: Add failure_module for critical workflows
369
- 4. **Languages**: Use \`bun\` for TypeScript (fastest), \`python3\` for Python
370
- 5. **Resources**: Store credentials/configs as resources, reference with \`$res:path\`
371
- 6. **Loops**: Prefer \`parallel: true\` for independent iterations
372
- 7. **Branching**: Use \`branchone\` for if/else logic, \`branchall\` for parallel processing
373
- 8. **Schemas**: Always define input schemas for better UX and validation
374
-
375
- ## Example Complete Workflow
376
- \`\`\`yaml
377
- summary: "Process user data"
378
- description: "Validates user input, processes data, and sends notifications"
379
- value:
380
- modules:
381
- - id: validate_input
382
- value:
383
- type: rawscript
384
- content: '!inline inline_script_0.inline_script.ts'
385
- # script at path inline_script_0.inline_script.ts will contain
386
- # export async function main(email: string, name: string) {
387
- # if (!email.includes('@')) throw new Error('Invalid email');
388
- # return { email, name, valid: true };
389
- # }
390
- language: bun
391
- input_transforms:
392
- email:
393
- type: javascript
394
- expr: "flow_input.email"
395
- name:
396
- type: javascript
397
- expr: "flow_input.name"
398
- - id: process_data
399
- value:
400
- type: script
401
- path: "f/shared/data_processor"
402
- input_transforms:
403
- user_data:
404
- type: javascript
405
- expr: "results.validate_input"
406
- - id: send_notification
407
- value:
408
- type: rawscript
409
- content: '!inline inline_script_1.inline_script.ts'
410
- # script at path inline_script_1.inline_script.ts will contain
411
- # export async function main(processed_data: any) {
412
- # console.log("Sending notification for:", processed_data.name);
413
- # return "notification_sent";
414
- # }
415
- language: bun
416
- input_transforms:
417
- processed_data:
418
- type: javascript
419
- expr: "results.process_data"
420
- schema:
421
- type: object
422
- properties:
423
- email:
424
- type: string
425
- format: email
426
- description: "User email address"
427
- name:
428
- type: string
429
- description: "User full name"
430
- required: ["email", "name"]
431
- \`\`\`
9
+ You do not need to create .lock and .yaml files manually. Instead, you should run \`wmill flow generate-locks --yes\` to create them.`;
10
+ // Assemble complete flow guidance
11
+ export const FLOW_GUIDANCE = `
12
+ ${CLI_INTRO}
432
13
 
433
- When generating OpenFlow YAML, ensure proper indentation, valid YAML syntax, and logical step dependencies. Always include meaningful summaries and proper input transforms to connect workflow steps.
14
+ ${prompts.FLOW_PROMPT}
434
15
  `;