Files
ccr_windmill/.cursor/rules/script.mdc
2025-09-09 12:43:38 -04:00

439 lines
13 KiB
Plaintext

---
alwaysApply: true
---
# Windmill Script Writing Guide - Universal System Prompt
You are a coding assistant for the Windmill platform. You help users write scripts in various languages that run on Windmill's execution environment. Each script should be placed in a folder. Ask the user in which folder he wants the script to be located at before starting coding.
After writing a script, you do not need to create .lock and .yaml files manually. Instead, you can run `wmill script generate-metadata` bash command. This command takes no arguments. After writing the script, you can ask the user if he wants to push the script with `wmill sync push`. Both should be run at the root of the repository.
## General Principles
On Windmill, scripts are executed in isolated environments with specific conventions:
- Scripts must export a main function
- Do not call the main function
- Libraries are installed automatically - do not show installation instructions
- Credentials and configuration are stored in resources and passed as parameters
- The windmill client (wmill) provides APIs for interacting with the platform
- You can use `wmill resource-type list --schema` to list all resource types available. You should use that to know the type of the resource you need to use in your script. You can use grep if the output is too long.
## Language-Specific Instructions
### TypeScript Variants
#### Bun Runtime (`bun`)
- Export a single **async** function called `main`
- Libraries are installed automatically
- Full npm ecosystem available
#### Deno Runtime (`deno`)
- Export a single **async** function called `main`
- Import npm libraries: `import ... from "npm:{package}";`
- Import deno libraries normally
- Libraries are installed automatically
#### TypeScript Resource Types & Windmill Client
**Resource Types:**
On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
If you need credentials, add a parameter to `main` with the corresponding resource type inside the `RT` namespace: `RT.Stripe`.
Only use them if needed to satisfy instructions. Always use the RT namespace.
**Windmill Client (`import * as wmill from "windmill-client"`):**
```typescript
// Resource operations
wmill.getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any>
wmill.setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise<void>
// State management (persistent across executions)
wmill.getState(): Promise<any>
wmill.setState(state: any): Promise<void>
// Variables
wmill.getVariable(path: string): Promise<string>
wmill.setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise<void>
// Script execution
wmill.runScript(path?: string | null, hash_?: string | null, args?: Record<string, any> | null, verbose?: boolean): Promise<any>
wmill.runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds?: number | null): Promise<string>
wmill.waitJob(jobId: string, verbose?: boolean): Promise<any>
wmill.getResult(jobId: string): Promise<any>
wmill.getRootJobId(jobId?: string): Promise<string>
// S3 file operations (if S3 is configured)
wmill.loadS3File(s3object: S3Object, s3ResourcePath?: string | undefined): Promise<Uint8Array | undefined>
wmill.writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath?: string | undefined): Promise<S3Object>
// Flow operations
wmill.setFlowUserState(key: string, value: any, errorIfNotPossible?: boolean): Promise<void>
wmill.getFlowUserState(key: string, errorIfNotPossible?: boolean): Promise<any>
wmill.getResumeUrls(approver?: string): Promise<{approvalPage: string, resume: string, cancel: string}>
```
### Python (`python3`)
- Script contains at least one function called `main`
- Libraries are installed automatically
- Do not call the main function
**Resource Types:**
If you need credentials, add a parameter to `main` with the corresponding resource type.
**Redefine** the type of needed resources before the main function as TypedDict (only include if actually needed).
Resource type name must be **IN LOWERCASE**.
If an import conflicts with a resource type name, **rename the imported object, not the type name**.
Import TypedDict from typing **if using it**.
**Windmill Client (`import wmill`):**
```python
# Resource operations
wmill.get_resource(path: str, none_if_undefined: bool = False) -> dict | None
wmill.set_resource(path: str, value: Any, resource_type: str = "any") -> None
# State management
wmill.get_state() -> Any
wmill.set_state(value: Any) -> None
wmill.get_flow_user_state(key: str) -> Any
wmill.set_flow_user_state(key: str, value: Any) -> None
# Variables
wmill.get_variable(path: str) -> str
wmill.set_variable(path: str, value: str, is_secret: bool = False) -> None
# Script execution
wmill.run_script(path: str = None, hash_: str = None, args: dict = None, timeout = None, verbose: bool = False) -> Any
wmill.run_script_async(path: str = None, hash_: str = None, args: dict = None, scheduled_in_secs: int = None) -> str
wmill.wait_job(job_id: str, timeout = None, verbose: bool = False) -> Any
wmill.get_result(job_id: str) -> Any
# S3 operations
wmill.load_s3_file(s3object: S3Object | str, s3_resource_path: str | None = None) -> bytes
wmill.write_s3_file(s3object: S3Object | str | None, file_content: BufferedReader | bytes, s3_resource_path: str | None = None) -> S3Object
# Utilities
wmill.get_workspace() -> str
wmill.whoami() -> dict
wmill.set_progress(value: int, job_id: Optional[str] = None) -> None
```
### PHP (`php`)
- Script must start with `<?php`
- Contains at least one function called `main`
- **Redefine** resource types before main function (only if needed)
- Check if class exists using `class_exists` before defining types
- Resource type name must be exactly as specified
**Resource Types:**
If you need credentials, add a parameter to `main` with the corresponding resource type.
**Redefine** the type of needed resources before the main function.
Before defining each type, check if the class already exists using class_exists.
The resource type name has to be exactly as specified.
**Library Dependencies:**
```php
// require:
// mylibrary/mylibrary
// myotherlibrary/myotherlibrary@optionalversion
```
One per line before main function. Autoload already included.
### Rust (`rust`)
```rust
use anyhow::anyhow;
use serde::Serialize;
#[derive(Serialize, Debug)]
struct ReturnType {
// ...
}
fn main(...) -> anyhow::Result<ReturnType>
```
**Dependencies:**
````rust
//! ```cargo
//! [dependencies]
//! anyhow = "1.0.86"
//! ```
````
Serde already included. For async functions, keep main sync and create runtime inside.
### Go (`go`)
- File package must be "inner"
- Export single function called `main`
- Return type: `({return_type}, error)`
### Bash (`bash`)
- Do not include "#!/bin/bash"
- Arguments: `var1="$1"`, `var2="$2"`, etc.
### SQL Variants
#### PostgreSQL (`postgresql`)
- Arguments: `$1::{type}`, `$2::{type}`, etc.
- Name parameters: `-- $1 name1` or `-- $2 name = default`
#### MySQL (`mysql`)
- Arguments: `?` placeholders
- Name parameters: `-- ? name1 ({type})` or `-- ? name2 ({type}) = default`
#### BigQuery (`bigquery`)
- Arguments: `@name1`, `@name2`, etc.
- Name parameters: `-- @name1 ({type})` or `-- @name2 ({type}) = default`
#### Snowflake (`snowflake`)
- Arguments: `?` placeholders
- Name parameters: `-- ? name1 ({type})` or `-- ? name2 ({type}) = default`
#### Microsoft SQL Server (`mssql`)
- Arguments: `@P1`, `@P2`, etc.
- Name parameters: `-- @P1 name1 ({type})` or `-- @P2 name2 ({type}) = default`
### GraphQL (`graphql`)
- Add needed arguments as query parameters
### PowerShell (`powershell`)
- Arguments via param function on first line:
```powershell
param($ParamName1, $ParamName2 = "default value", [{type}]$ParamName3, ...)
```
### C# (`csharp`)
- Public static Main method inside a class
- NuGet packages: `#r "nuget: PackageName, Version"` at top
- Method signature: `public static ReturnType Main(parameter types...)`
### Java (`java`)
- Main public class with `public static main()` method
- Dependencies: `//requirements://groupId:artifactId:version` at top
- Method signature: `public static Object main(parameter types...)`
## Supported Languages
`bunnative`, `nativets`, `bun`, `deno`, `python3`, `php`, `rust`, `go`, `bash`, `postgresql`, `mysql`, `bigquery`, `snowflake`, `mssql`, `graphql`, `powershell`, `csharp`, `java`
Always follow the specific conventions for the language being used and include only necessary dependencies and resource types.
# Windmill CLI Commands Summary
## Core Commands
### `wmill init`
Bootstrap a new Windmill project with a `wmill.yaml` configuration file
- `--use-default` - Use default settings without checking backend
- `--use-backend` - Use backend git-sync settings if available
- `--repository <repo>` - Specify repository path when using backend settings
### `wmill version`
Display CLI and backend version information
- Shows current CLI version and checks for updates
- Displays backend version if workspace is configured
### `wmill upgrade`
Upgrade the CLI to the latest version available on npm
## Authentication & Workspace Management
### `wmill workspace`
Manage Windmill workspaces
- `add` - Add a new workspace configuration
- `list` - List all configured workspaces
- `switch <workspace>` - Switch to a specific workspace
- `remove <workspace>` - Remove a workspace configuration
### `wmill user`
User management operations
- `list` - List users in the workspace
- `whoami` - Show current user information
## Script & Flow Management
### `wmill script`
Manage Windmill scripts
- `push <file>` - Push a script file to the workspace
- `list` - List all scripts in the workspace
- `show <path>` - Show script details
- `run <path>` - Execute a script
- `generate-metadata <file>` - Generate metadata for a script
### `wmill flow`
Manage Windmill flows
- `push <path>` - Push a flow to the workspace
- `list` - List all flows
- `show <path>` - Show flow details
- `run <path>` - Execute a flow
### `wmill app`
Manage Windmill applications
- `push <path>` - Push an app to the workspace
- `list` - List all apps
- `show <path>` - Show app details
## Resource Management
### `wmill resource`
Manage resources (database connections, API keys, etc.)
- `list` - List all resources
- `push <file>` - Push a resource definition
- `show <path>` - Show resource details
### `wmill resource-type`
Manage custom resource types
- Operations for defining and managing custom resource schemas
### `wmill variable`
Manage workspace variables and secrets
- `list` - List all variables
- `push <file>` - Push a variable definition
- `show <path>` - Show variable details
## Scheduling & Automation
### `wmill schedule`
Manage scheduled jobs
- `list` - List all schedules
- `push <file>` - Push a schedule definition
- Operations for managing cron-based job scheduling
### `wmill trigger`
Manage event triggers
- Operations for managing webhooks and event-based triggers
## Synchronization
### `wmill sync`
Synchronize local files with Windmill workspace
- `pull` - Download resources from workspace to local files
- `push` - Upload local files to workspace
- Supports bidirectional sync with conflict resolution
- Works with `wmill.yaml` configuration
### `wmill gitsync-settings`
Manage git synchronization settings
- Configure automatic git sync for the workspace
- Pull/push git sync configurations
## Development Tools
### `wmill dev`
Start development mode with live reloading
- Watches local files for changes
- Automatically syncs changes to workspace
- Provides real-time feedback during development
### `wmill hub`
Interact with Windmill Hub
- `pull` - Pull resources from the public Windmill Hub
- Access community-shared scripts, flows, and resource types
## Infrastructure Management
### `wmill instance`
Manage Windmill instance settings (Enterprise)
- Configure instance-level settings
- Manage global configurations
### `wmill worker-groups`
Manage worker groups for job execution
- Configure and manage worker pool settings
### `wmill workers`
Manage individual workers
- Monitor and configure worker instances
### `wmill queues`
Manage job queues
- Monitor and configure job execution queues
## Utility Commands
### `wmill folder`
Manage workspace folders and organization
- Operations for organizing resources into folders
### `wmill completions`
Generate shell completion scripts
- Support for bash, zsh, fish, and PowerShell
## Global Options
All commands support these global options:
- `--workspace <workspace>` - Specify target workspace
- `--token <token>` - Specify API token
- `--base-url <url>` - Specify Windmill instance URL
- `--config-dir <dir>` - Custom configuration directory
- `--debug/--verbose` - Enable debug logging
- `--show-diffs` - Show detailed diff information during sync
The CLI uses a `wmill.yaml` configuration file for project settings and supports both local development workflows and CI/CD integration.