1 ---
2 name: workflows
3 description: Manage application workflows including configuration, restart, and removal.
4 ---
5
6 ## Overview
7
8 A workflow binds a shell command (e.g., `npm run dev`, `python run.py`, `cargo run`) to a long-running task managed by Replit. Workflows are used to run webservers, background services, TUIs, and other persistent processes.
9
10 **Key characteristics:**
11
12 - Workflows run until explicitly stopped
13 - The system tracks workflows automatically — no separate configuration file is required
14 - Workflows auto-restart after package installation and module installation
15 - You can only get console logs from a workflow if it is running
16
17 ## Setup Tips
18
19 1. **Keep workflows minimal**: One workflow per project is usually sufficient. Use the main frontend server or TUI as your primary workflow.
20
21 2. **Choose the right workflow**: If your project has a frontend or TUI, set the workflow to the process that updates what the user sees.
22
23 3. **Clean up unused workflows**: When adding new workflows, remove any existing workflows that are no longer needed.
24
25 4. **Always restart after changes**: Restart workflows after making server-side code changes to ensure updates are visible to the user. Verify they run without errors before returning to the user.
26
27 5. **Use bash for one-off commands**: Workflows are for persistent processes. Use bash for build scripts, testing, or commands that don't need to keep running.
28
29 ## When to Use
30
31 Use this skill when:
32
33 - You need to create or configure a workflow (background process)
34 - You need to restart the application after making code changes
35 - The application needs to be restarted to pick up new environment variables
36 - You need to remove a workflow that's no longer needed
37 - The user asks to start, stop, or restart the application
38 - You need to check what workflows are configured
39 - You need to check workflow status, output, or open ports
40
41 ## When NOT to Use
42
43 - For debugging runtime errors (fix the code first, then restart)
44 - When the application is already running and changes are hot-reloaded
45 - One-off commands (use bash for commands that don't need to persist)
46 - Build scripts (use bash for npm build, webpack, etc.)
47 - Testing commands (use bash or runTest callback)
48 - More than 10 workflows (keep workflows minimal; combine services if needed)
49
50 ## Available Functions
51
52 ### listWorkflows()
53
54 List all configured workflows with their current state.
55
56 **Parameters:** None
57
58 **Returns:** List of workflow info dicts with `name` (str), `command` (str), and `state` ("not_started", "running", "finished", "failed").
59
60 **Example:**
61
62 ```javascript
63 const workflows = await listWorkflows();
64 for (const w of workflows) {
65 console.log(`${w.name}: ${w.state}`);
66 }
67 ```
68
69 ### getWorkflowStatus(name, maxScrollbackLines)
70
71 Get detailed status of a specific workflow including output logs and open ports.
72
73 **Parameters:**
74
75 - `name` (str, required): Name of the workflow to check
76 - `maxScrollbackLines` (int, default 100): Number of output lines to include
77
78 **Returns:** Dict with `name`, `command`, `state`, `output` (recent terminal output), `openPorts` (list of listening ports), and `waitForPort`.
79
80 **Example:**
81
82 ```javascript
83 // Check if the server is running and see its output
84 const status = await getWorkflowStatus({ name: "Start application" });
85 console.log(`State: ${status.state}`);
86 if (status.output) {
87 console.log(`Output:\n${status.output}`);
88 }
89 if (status.openPorts) {
90 console.log(`Listening on ports: ${status.openPorts}`);
91 }
92 ```
93
94 ### configureWorkflow({ name, command, waitForPort, outputType, autoStart, isCanvasWorkflow })
95
96 Configure or create a workflow. This is the primary way to set up background processes.
97
98 **Parameters:**
99
100 - `name` (str, default "Start application"): Unique workflow identifier
101 - `command` (str, required): Shell command to execute
102 - `waitForPort` (int, optional): Port the process listens on
103 - `outputType` (str, default "webview"): "webview", "console", or "vnc"
104 - `autoStart` (bool, default True): Auto-start after configuration
105 - `isCanvasWorkflow` (bool, default false): Whether this workflow serves canvas iframe content
106
107 **Output Type Rules:**
108
109 - **webview** - For web applications. MUST use port 5000.
110 - **console** - For backend services, CLIs, TUIs. Can use any supported port.
111 - **vnc** - For desktop/GUI apps (Electron, PyQt, etc.). No port needed.
112
113 **Supported Ports:** 3000, 3001, 3002, 3003, 4200, 5000 (webview only), 5173, 6000, 6800, 8000, 8008, 8080, 8099, 9000
114
115 **Examples:**
116
117 ```javascript
118 // Web application (React, Next.js, etc.)
119 await configureWorkflow({
120 name: "Start application",
121 command: "npm run dev",
122 waitForPort: 5000,
123 outputType: "webview"
124 });
125
126 // Backend API
127 await configureWorkflow({
128 name: "Backend API",
129 command: "python api.py",
130 waitForPort: 8000,
131 outputType: "console"
132 });
133
134 // Desktop application
135 await configureWorkflow({
136 name: "Desktop App",
137 command: "python gui_app.py",
138 outputType: "vnc"
139 });
140 ```
141
142
143 ### removeWorkflow(name)
144
145 Remove a workflow by name. Automatically stops it if running.
146
147 **Parameters:**
148
149 - `name` (str, required): Name of the workflow to remove
150
151 **Returns:** Dict with `success`, `message`, `workflowName`, and `wasRunning`
152
153 **Example:**
154
155 ```javascript
156 await removeWorkflow({ name: "Backend API" });
157 ```
158
159 ### restartWorkflow(workflowName, timeout)
160
161 Restart a workflow by name.
162
163 **Parameters:**
164
165 - `workflowName` (str, required): Name of the workflow (e.g., "Start application")
166 - `timeout` (int, default 30): Timeout in seconds to wait for restart
167
168 **Returns:** Dict with restart status and optional screenshot URL
169
170 **Example:**
171
172 ```javascript
173 // Restart the main application
174 const result = await restartWorkflow({ workflowName: "Start application" });
175 console.log(result.message);
176
177 // Restart with custom timeout
178 const result2 = await restartWorkflow({
179 workflowName: "Start application",
180 timeout: 60
181 });
182 ```
183
184 ## Best Practices
185
186 1. **Restart after code changes**: Always restart workflows after modifying server-side code
187 2. **Use appropriate timeouts**: Increase timeout for applications with slow startup
188 3. **Check logs on failure**: If restart fails, check workflow logs for error details
189 4. **One restart at a time**: Avoid parallel restarts of the same workflow
190
191 5. **Port 5000 for web apps**: Always use port 5000 with webview output type
192
193
194 ## Common Workflow Names
195
196 - `Start application` - Main application workflow
197 - `Start Backend` - Backend server (in Expo/mobile apps)
198 - `Project` - Parent workflow for multi-service apps
199
200 ## Error Handling
201
202 The workflow functions may raise errors in these cases:
203
204 - **Workflow not found**: The specified workflow name doesn't exist
205 - **Port not opened**: The application didn't start listening on expected port
206 - **Preview not available**: The application endpoint isn't responding with HTTP 200
207 - **Workflow limit exceeded**: Maximum of 10 workflows reached
208
209 - **Port/output type mismatch**: Port 5000 requires webview, webview requires port 5000
210
211
212 When errors occur, check:
213
214 1. Workflow logs for error details
215 2. Application code for startup issues
216 3. Port configuration in the workflow settings
217
218 ## Example Workflow
219
220 ```javascript
221 // Create a web application workflow
222 await configureWorkflow({
223 name: "Start application",
224 command: "npm run dev",
225
226 waitForPort: 5000,
227
228 outputType: "webview"
229 });
230
231 // After making code changes, restart the application
232 const result = await restartWorkflow({ workflowName: "Start application" });
233
234 if (result.success) {
235 console.log("Application restarted successfully");
236 if (result.screenshotUrl) {
237 console.log(`Screenshot: ${result.screenshotUrl}`);
238 }
239 } else {
240 console.log(`Restart failed: ${result.message}`);
241 }
242
243 // Clean up unused workflows
244 await removeWorkflow({ name: "Old Backend" });
245 ```