From eebe24d8b0739a61d308bc53a322a01df984511a Mon Sep 17 00:00:00 2001 From: Guilhem Date: Mon, 27 Apr 2026 22:14:21 +0200 Subject: [PATCH] feat(cli): wmill dev with per-flow proxy and responsive Dev UI (#8529) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(cli): add `wmill flow dev` subcommand with per-flow reverse proxy and launch.json Also generates .claude/launch.json for existing flow folders during `wmill init`. Co-Authored-By: Claude Opus 4.6 (1M context) * feat: responsive dev layout and hide splitter for single-pane views Co-Authored-By: Claude Opus 4.5 * fix: clamp flow graph height between minHeight and maxHeight Co-Authored-By: Claude Opus 4.5 * feat(cli): enhance app new with Claude Desktop integration and better defaults - Add .claude/launch.json to generated app scaffold for Claude Code preview support - Add "Open in Claude Desktop?" prompt that creates a CLI session and opens it in Claude Desktop Code mode via the claude://resume deep link - Improve default CSS template with body background, system fonts, and padding Co-Authored-By: Claude Opus 4.6 (1M context) * fix(cli): handle both .flow and __flow suffixes in wmill dev The flow detection in loadPaths only checked the configured suffix (dotted or non-dotted), so users with nonDottedPaths=true who had .flow folders (or vice versa) would see inline script edits treated as standalone script changes instead of flow changes. Now checks both suffix forms everywhere: type classification, folder path extraction, path stripping, and loadWmPath lookup. Also adds raw_app launch.json generation to init and sync pull. Co-Authored-By: Claude Opus 4.6 (1M context) * docs(cli): update generated skills with dev workflow and preview commands Update cli-commands, write-flow, and raw-app skills to document the new local dev workflow (wmill dev --path, --proxy-port, .claude/launch.json). Add wmill script preview and wmill flow preview to all script/flow skills so agents know how to test without deploying. Co-Authored-By: Claude Opus 4.6 (1M context) * fix(cli): include path in dev URL and use open.default for browser - Append &path= to the printed/opened URL when --path is specified - Use open.default(url) instead of open.openApp for more reliable browser opening Co-Authored-By: Claude Opus 4.6 (1M context) * feat(cli): add Claude CLI/Desktop detection hints in wmill flow new Show contextual instructions for previewing flows based on available tools. Co-Authored-By: Claude Opus 4.6 (1M context) * chore: regenerate auto-generated CLI skills for new dev flags Co-Authored-By: Claude Opus 4.5 * fix(cli): handle mixed flow suffixes in dev file watcher The ignore() function uses isFlowPath() which only checks the configured suffix (__flow or .flow), causing files in the other variant to be silently ignored. Bypass the ignore check for any file inside a flow folder and force flow type detection regardless of suffix configuration. Co-Authored-By: Claude Opus 4.6 (1M context) * feat(cli): drop default proxy in flow folders, open browser, add --no-browser Manual `wmill dev` in a flow folder should not implicitly enable the reverse proxy. Both proxy and legacy modes now open the browser; the new --no-browser flag opts out. Claude Code launch.json templates pass --no-browser so the IDE preview doesn't fight a system browser window. Co-Authored-By: Claude Opus 4.7 (1M context) * feat(cli): gate dev broadcasts by --path and push currentLastEdit on connect When --path (or auto-detected flow path) is set, drop file events for any other path so the dev page stays locked to the requested resource and currentLastEdit can never reflect an unrelated edit. The connection handler proactively pushes currentLastEdit so the page renders without waiting for the first file change. Co-Authored-By: Claude Opus 4.7 (1M context) * fix(frontend): prefer WebSocket for flow round-trip when wmill dev is connected updateFlow used isInIframe priority, which routed Claude Code's iframe preview through postMessage (no listener) and silently dropped flow edits. Flip the priority: when the wmill dev WebSocket is open, use it (covers standalone tabs and Claude Code's preview); fall back to postMessage only when no WS is connected (the VS Code extension's iframe URL has no `local=true`, so it never opens one). Also stop assigning lastSent before a channel actually accepted the message, so a CONNECTING WS doesn't silently swallow the first change. Co-Authored-By: Claude Opus 4.7 (1M context) * feat(dev): url is source of truth for path; add workspace file picker Drops the server-side --path gate added in 3c2d5155e1. The dev page now filters by its URL's ?path= and the CLI is a dumb broadcaster, which lets multiple tabs each watch different paths. When the URL has no ?path=, the page asks the CLI for a list of workspace items (flows, scripts, raw_apps) via a new {type:'listPaths'} WS message and renders a picker. Clicking a flow or script soft-updates the URL via history.pushState and loads it; raw_apps surface a hint to use `wmill app dev` since they don't render here. Co-Authored-By: Claude Opus 4.7 (1M context) * feat(dev): picker uses homepage tree view with summaries Replace the hand-rolled Button-list picker with a TreeView-style layout that mirrors the Windmill homepage: folder/user tree grouping via `groupItems`, item rows rendered through the shared `Row.svelte` (no actions, no favourites, no link — just the visual), a `SearchItems` fuzzy filter with the same search input styling and placeholder as the homepage, and `group-open:` chevron toggling on native
. The CLI's listWorkspacePaths now also reads summaries from each item's metadata (flow.yaml for flows, @@ -712,7 +875,185 @@
- {#if mode == 'script'} + {#snippet itemRow(item: ItemType & { marked?: string }, depth: number)} + {@const wmItem = pickerItems.find((p) => p.path === item.path)} + + {/snippet} + {#snippet treeNode(node: ItemType | FolderItem | UserItem, depth: number)} + {#if 'folderName' in node} +
+ +
0 ? `padding-left: ${depth * 16}px;` : ''} + > +
+ {#if depth === 0} + + {:else} + + {/if} +
+
+ {#if depth === 0}f/{/if}{node.folderName} +
+ ({pluralize(node.items.length, 'item')}) +
+
+
+
+
+
+ {#each node.items as child ('folderName' in child ? `f__${child.folderName}` : 'username' in child ? `u__${child.username}` : `i__${child.type}__${child.path}`)} + {@render treeNode(child, depth + 1)} + {/each} +
+ {:else if 'username' in node} +
+ +
0 ? `padding-left: ${depth * 16}px;` : ''} + > +
+ +
+
+ u/{node.username} +
+ ({pluralize(node.items.length, 'item')}) +
+
+
+
+
+
+ {#each node.items as child ('folderName' in child ? `f__${child.folderName}` : 'username' in child ? `u__${child.username}` : `i__${child.type}__${child.path}`)} + {@render treeNode(child, depth + 1)} + {/each} +
+ {:else} + {@render itemRow(node as ItemType & { marked?: string }, depth)} + {/if} + {/snippet} + + {#if pickerMode} +
+
+ +
+
+ {#if $userStore} + {$userStore?.username} on {$workspaceStore} + {:else} + Unable to login on {$workspaceStore} + {/if} +
+
+

+ {$workspaceStore} + (local) +

+

Click a flow or a script to preview it.

+ + `${item.path} ${item.summary ?? ''}`} + bind:filteredItems={pickerFilteredItems} + /> + + {#if wsState !== 'closed'} +
+ + {#snippet children({ item })} + + + + + {/snippet} + + +
+ + + +
+
+ {/if} + + {#if wsState === 'closed'} + + Start it from your workspace root with + wmill dev + to preview your flows, scripts, and apps. + + {:else if pickerItems.length === 0} +
No flows, scripts, or apps detected in this workspace.
+ {:else if pickerGroups.length === 0} +
No items match the search.
+ {:else} +
+ {#each pickerGroups as group ('folderName' in group ? `f__${group.folderName}` : 'username' in group ? `u__${group.username}` : `i__${group.type}__${group.path}`)} + {@render treeNode(group, 0)} + {/each} +
+ {/if} +
+
+ {:else if mode == 'script'}
@@ -855,7 +1196,11 @@
{:else} -
+
@@ -866,83 +1211,93 @@ {/if}
-
- { - showJobStatus = true - }} - /> -
- + - {#if flowStore.val?.value?.modules} -
- { - delete localModuleStates[id] - delete modulesTestStates.states[id] - }} - {flowHasChanged} - /> - {:else} -
Missing flow modules
- {/if} -
+
+ {#if flowStore.val?.value?.modules} +
+
+ { + showJobStatus = true + }} + /> +
+ { + delete localModuleStates[id] + delete modulesTestStates.states[id] + }} + {flowHasChanged} + controlsPosition="bottom" + /> + {:else} +
Missing flow modules
+ {/if} +
+ - {#key reload} - { - if (ev.detail.kind === 'preprocessor') { - stepsInputArgs.setStepArgs('preprocessor', ev.detail.args ?? {}) - selectionManager.selectId('preprocessor') - } else { - previewArgsStore.val = ev.detail.args ?? {} - flowPreviewButtons?.openPreview() - } - }} - onTestFlow={flowPreviewButtons?.runPreview} - {job} - isOwner={flowPreviewContent?.getIsOwner()} - {suspendStatus} - onOpenDetails={flowPreviewButtons?.openPreview} - previewOpen={flowPreviewButtons?.getPreviewOpen()} - /> - {/key} +
+ {#if selectedModule} +
+ {selectedModule.id} summary + +
+ {/if} + {#key reload} + { + if (ev.detail.kind === 'preprocessor') { + stepsInputArgs.setStepArgs('preprocessor', ev.detail.args ?? {}) + selectionManager.selectId('preprocessor') + } else { + previewArgsStore.val = ev.detail.args ?? {} + flowPreviewButtons?.openPreview() + } + }} + onTestFlow={flowPreviewButtons?.runPreview} + {job} + isOwner={flowPreviewContent?.getIsOwner()} + {suspendStatus} + onOpenDetails={flowPreviewButtons?.openPreview} + previewOpen={flowPreviewButtons?.getPreviewOpen()} + /> + {/key} +
- {#if selectedModule} -
- {selectedModule.id} summary - -
- {/if}
{/if} diff --git a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte index 7789d93f72..422a599d5b 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte @@ -832,109 +832,44 @@ {/if}
- - {#if flowModule.value.type !== 'aiagent'} - - {#if flowModule.value.type === 'rawscript'} - {#if !noEditor} - {#key flowModule.id} -
- {#if assets?.length} - - {/if} - {#if isDebuggableScript && customUi?.editorBar?.debug != false} - - {/if} - {#if showDebugPanel && !showDebugConsole} - - {/if} -
- {#if debugConsoleVisible} - - -
- { - selected = 'test' - if (selectedId == flowModule.id) { - if (flowModule.value.type === 'rawscript' && editor) { - flowModule.value.content = editor.getCode() - } - await reload(flowModule) - modulePreview?.runTestWithStepArgs() - } - }} - on:change={async (event) => { - const content = event.detail - if (flowModule.value.type === 'rawscript') { - if (flowModule.value.content !== content) { - flowModule.value.content = content - } - await reload(flowModule) - if (debugMode && breakpointDecorations.length > 0) { - refreshBreakpointPositions() - } - } - }} - formatAction={() => { - reload(flowModule) - saveDraft() - }} - fixedOverflowWidgets={true} - args={Object.entries(flowModule.value.input_transforms).reduce( - (acc, [key, obj]) => { - acc[key] = obj.type === 'static' ? obj.value : undefined - return acc - }, - {} - )} - key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`} - moduleId={flowModule.id} - preparedAssetsSqlQueries={preparedSqlQueries.current} - customTag={flowModule.value.tag} - /> -
-
- - (showDebugConsole = false)} - workspace={$workspaceStore} - jobId={debugSessionJobId ?? undefined} - /> - -
- {:else} + {#snippet topPaneContent()} + {#if flowModule.value.type === 'rawscript'} + {#if !noEditor} + {#key flowModule.id} +
+ {#if assets?.length} + + {/if} + {#if isDebuggableScript && customUi?.editorBar?.debug != false} + + {/if} + {#if showDebugPanel && !showDebugConsole} + + {/if} +
+ {#if debugConsoleVisible} + +
- {/if} - - {/key} - {/if} - {:else if flowModule.value.type === 'script'} - {#if !noEditor && (customUi?.hubCode != false || !flowModule?.value?.path?.startsWith('hub/'))} -
- {#key forceReload} - + + (showDebugConsole = false)} + workspace={$workspaceStore} + jobId={debugSessionJobId ?? undefined} /> - {/key} + + + {:else} +
+ { + selected = 'test' + if (selectedId == flowModule.id) { + if (flowModule.value.type === 'rawscript' && editor) { + flowModule.value.content = editor.getCode() + } + await reload(flowModule) + modulePreview?.runTestWithStepArgs() + } + }} + on:change={async (event) => { + const content = event.detail + if (flowModule.value.type === 'rawscript') { + if (flowModule.value.content !== content) { + flowModule.value.content = content + } + await reload(flowModule) + if (debugMode && breakpointDecorations.length > 0) { + refreshBreakpointPositions() + } + } + }} + formatAction={() => { + reload(flowModule) + saveDraft() + }} + fixedOverflowWidgets={true} + args={Object.entries(flowModule.value.input_transforms).reduce( + (acc, [key, obj]) => { + acc[key] = obj.type === 'static' ? obj.value : undefined + return acc + }, + {} + )} + key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`} + moduleId={flowModule.id} + preparedAssetsSqlQueries={preparedSqlQueries.current} + customTag={flowModule.value.tag} + />
{/if} - {:else if flowModule.value.type === 'flow'} + + {/key} + {/if} + {:else if flowModule.value.type === 'script'} + {#if !noEditor && (customUi?.hubCode != false || !flowModule?.value?.path?.startsWith('hub/'))} +
{#key forceReload} - + {/key} - {/if} - +
+ {/if} + {:else if flowModule.value.type === 'flow'} + {#key forceReload} + + {/key} {/if} - { - if (flowModule.value.type === 'aiagent') { - return 100 - } - return editorSettingsPanelSize - }, - (v) => { - if (flowModule.value.type !== 'aiagent') { - editorSettingsPanelSize = v - } - } - } - minSize={20} - > - - -
- { - selected = event.detail - }} - wrapperClass="shrink-0" - > - {#if !preprocessorModule} - - {/if} - - {#if canShowChatTab && flowModule.value.type === 'aiagent'} - - {/if} - {#if !preprocessorModule && !isAgentTool} - - {/if} - - {#if visibleSelected === 'inputs' && (flowModule.value.type == 'rawscript' || flowModule.value.type == 'script' || flowModule.value.type == 'flow' || flowModule.value.type == 'aiagent')} -
- + +
+ { + selected = event.detail + }} + wrapperClass="shrink-0" + > + {#if !preprocessorModule} + + {/if} + + {#if canShowChatTab && flowModule.value.type === 'aiagent'} + + {/if} + {#if !preprocessorModule && !isAgentTool} + + {/if} + + {#if visibleSelected === 'inputs' && (flowModule.value.type == 'rawscript' || flowModule.value.type == 'script' || flowModule.value.type == 'flow' || flowModule.value.type == 'aiagent')} +
+ + {#if reloadError} +
+ {/if} + - {#if reloadError} -
- {/if} - { + schema={flowStateStore.val[selectedId]?.schema ?? {}} + previousModuleId={previousModule?.id} + bind:args={ + () => { + // @ts-ignore + return flowModule?.value?.input_transforms + }, + (v) => { + if ( + typeof flowModule?.value === 'object' && + flowModule?.value !== null + ) { // @ts-ignore - return flowModule?.value?.input_transforms - }, - (v) => { - if ( - typeof flowModule?.value === 'object' && - flowModule?.value !== null - ) { - // @ts-ignore - flowModule.value.input_transforms = v - } + flowModule.value.input_transforms = v } } - extraLib={stepPropPicker.extraLib} - {enableAi} - {isAgentTool} - allowedAiTransforms={isAgentTool && flowModule.value.type === 'aiagent' - ? ['user_message'] - : undefined} - helperScript={retrieveDynCodeAndLang(flowModule.value)} - chatInputEnabled={flowStore.val.value?.chat_input_enabled ?? false} - /> -
+ } + extraLib={stepPropPicker.extraLib} + {enableAi} + {isAgentTool} + allowedAiTransforms={isAgentTool && flowModule.value.type === 'aiagent' + ? ['user_message'] + : undefined} + helperScript={retrieveDynCodeAndLang(flowModule.value)} + chatInputEnabled={flowStore.val.value?.chat_input_enabled ?? false} + /> + +
+ {:else if visibleSelected === 'test'} + {#if debugMode && isDebuggableScript} +
+
- {:else if visibleSelected === 'test'} - {#if debugMode && isDebuggableScript} -
- -
- {/if} - + {:else if visibleSelected === 'chat' && canShowChatTab && flowModule.value.type === 'aiagent'} +
+
+ { + setOmitOutputFromConversation(event.detail) + }} + options={{ + right: 'Omit assistant and tool messages from the flow conversation', + rightTooltip: + 'When enabled, this AI agent still runs normally, but its assistant response and tool-use messages are not stored in chat-mode conversation history.' + }} + /> +
+
+ {:else if visibleSelected === 'advanced'} + + - {:else if visibleSelected === 'chat' && canShowChatTab && flowModule.value.type === 'aiagent'} -
-
+ {#if !selectedId.includes('failure')} + + + + + + + + + + {#if flowModule.value['language'] === 'python3' || flowModule.value['language'] === 'deno'} + + {/if} + {/if} + + {#if advancedSelected === 'runtime'} + + + + + + + {/if} +
+ {#if advancedSelected === 'retries'} +
+ {#snippet header()} + + When enabled, the flow will continue to the next step even if this + step fails (after exhausting all retries, if any). This enables to + process the error in a branch one for instance. + + {/snippet} { - setOmitOutputFromConversation(event.detail) - }} + bind:checked={flowModule.continue_on_error} options={{ - right: 'Omit assistant and tool messages from the flow conversation', - rightTooltip: - 'When enabled, this AI agent still runs normally, but its assistant response and tool-use messages are not stored in chat-mode conversation history.' + left: 'Stop on error and propagate error up', + right: "Continue on error with error as step's return" }} />
-
- {:else if visibleSelected === 'advanced'} - - - {#if !selectedId.includes('failure')} - - - - - - - - - - {#if flowModule.value['language'] === 'python3' || flowModule.value['language'] === 'deno'} - - {/if} - {/if} - - {#if advancedSelected === 'runtime'} - - - - - - - {/if} -
- {#if advancedSelected === 'retries'} -
- {#snippet header()} - - When enabled, the flow will continue to the next step even if this - step fails (after exhausting all retries, if any). This enables to - process the error in a branch one for instance. - - {/snippet} - -
-
-
- {#snippet header()} - - If defined, upon error this step will be retried with a delay and a - maximum number of attempts as defined below. - - {/snippet} - -
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'concurrency'} -
- {#snippet header()} - Allowed concurrency within a given timeframe - {/snippet} - {#if flowModule.value.type == 'rawscript'} - - -
+ + - - - Setting priority is only available for enterprise edition and not - available on the cloud. - -
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'lifetime'} -
- -
- {:else if advancedSelected === 'cache'} -
- -
- {:else if advancedSelected === 'early-stop'} - - {:else if advancedSelected === 'skip'} - - {:else if advancedSelected === 'suspend'} -
- -
- {:else if advancedSelected === 'sleep'} -
- -
- {:else if advancedSelected === 'debounce'} -
- -
- {:else if advancedSelected === 'mock'} -
- -
- {:else if advancedSelected === 'same_worker'} -
- - If shared directory is set, will share a folder that will be mounted - on `./shared` for each of them to pass data between each other. - - -
- {:else if advancedSelected === 's3'} -
-

- S3 snippets - - Read/Write object from/to S3 and leverage Polars and DuckDB to run - efficient ETL processes. - -

-
-
-
- - {#snippet children({ item })} - {#if flowModule.value['language'] === 'deno'} - - {:else} - - - - {/if} - {/snippet} - -
- - -
- - {/if} -
- {/if} -
-
- {#if selected === 'test'} - - {#if stepHistoryLoader?.stepStates[flowModule.id]?.initial && !flowModule.mock?.enabled} - - -
{ - stepHistoryLoader?.resetInitial(flowModule.id) - }} - class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 bg-gray-500/40 absolute top-0 left-0 w-full z-50" - > -
Run loaded from history
-
- {/if} - {#if showDebugPanel || hasDebugResult} - - - - - - - - {#if hasDebugResult} -
- -
- {:else} -
+ {#snippet header()} + + Concurrency keys are global, you can have them be workspace + specific using the variable `$workspace`. You can also use an + argument's value using `$args[name_of_arg]` - {#if $debugState.running && !$debugState.stopped} - Running... - {:else if $debugState.stopped} - Paused at breakpoint - {:else} - Waiting for debug session - {/if} -
- {/if} -
-
-
- - + + + {:else} + + The concurrency limit of a workspace script is only settable in the + script metadata itself. For hub scripts, this feature is non available + yet. + + {/if} + + {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'timeout'} +
+ - - - {:else if debugMode && isDebuggableScript} -
- Click "Debug" in the toolbar to start debugging -
- {:else} - { - flowModule.mock = detail - flowModule = flowModule - refreshStateStore(flowStore) - }} - {testJob} - {scriptProgress} - mod={flowModule} - {testIsLoading} - disableMock={preprocessorModule || failureModule} - disableHistory={failureModule} - loadingJob={stepHistoryLoader?.stepStates[flowModule.id]?.loadingJobs} - tagLabel={customUi?.tagLabel} - bind:this={modulePreviewResultViewer} - /> - {/if} - - {/if} - - - +
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'priority'} +
+ + 0} + on:change={() => { + if (flowModule.priority) { + flowModule.priority = undefined + } else { + flowModule.priority = 100 + } + }} + options={{ + right: 'Enabled high priority flow step', + rightTooltip: `Jobs scheduled from this step when the flow is executed are labeled as high priority and take precedence over the other jobs in the jobs queue. ${ + !$enterpriseLicense + ? 'This is a feature only available on enterprise edition.' + : '' + }` + }} + /> + + + + Setting priority is only available for enterprise edition and not + available on the cloud. + +
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'lifetime'} +
+ +
+ {:else if advancedSelected === 'cache'} +
+ +
+ {:else if advancedSelected === 'early-stop'} + + {:else if advancedSelected === 'skip'} + + {:else if advancedSelected === 'suspend'} +
+ +
+ {:else if advancedSelected === 'sleep'} +
+ +
+ {:else if advancedSelected === 'debounce'} +
+ +
+ {:else if advancedSelected === 'mock'} +
+ +
+ {:else if advancedSelected === 'same_worker'} +
+ + If shared directory is set, will share a folder that will be mounted on + `./shared` for each of them to pass data between each other. + + +
+ {:else if advancedSelected === 's3'} +
+

+ S3 snippets + + Read/Write object from/to S3 and leverage Polars and DuckDB to run + efficient ETL processes. + +

+
+
+
+ + {#snippet children({ item })} + {#if flowModule.value['language'] === 'deno'} + + {:else} + + + + {/if} + {/snippet} + +
+ + +
+ + {/if} +
+ {/if} +
+
+ {#if selected === 'test'} + + {#if stepHistoryLoader?.stepStates[flowModule.id]?.initial && !flowModule.mock?.enabled} + + +
{ + stepHistoryLoader?.resetInitial(flowModule.id) + }} + class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 bg-gray-500/40 absolute top-0 left-0 w-full z-50" + > +
Run loaded from history
+
+ {/if} + {#if showDebugPanel || hasDebugResult} + + + + + + + + {#if hasDebugResult} +
+ +
+ {:else} +
+ {#if $debugState.running && !$debugState.stopped} + Running... + {:else if $debugState.stopped} + Paused at breakpoint + {:else} + Waiting for debug session + {/if} +
+ {/if} +
+
+
+ + + +
+ {:else if debugMode && isDebuggableScript} +
+ Click "Debug" in the toolbar to start debugging +
+ {:else} + { + flowModule.mock = detail + flowModule = flowModule + refreshStateStore(flowStore) + }} + {testJob} + {scriptProgress} + mod={flowModule} + {testIsLoading} + disableMock={preprocessorModule || failureModule} + disableHistory={failureModule} + loadingJob={stepHistoryLoader?.stepStates[flowModule.id]?.loadingJobs} + tagLabel={customUi?.tagLabel} + bind:this={modulePreviewResultViewer} + /> + {/if} +
+ {/if} +
+ {/snippet} + + {#if flowModule.value.type === 'aiagent' || (noEditor && flowModule.value.type !== 'flow')} + +
+ {@render bottomPaneContent()} +
+ {:else} + + + {@render topPaneContent()} + + + {@render bottomPaneContent()} + + + {/if}
diff --git a/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte b/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte index e4fd8e58dd..73ba81296f 100644 --- a/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte +++ b/frontend/src/lib/components/flows/map/FlowModuleSchemaMap.svelte @@ -98,6 +98,7 @@ suspendStatus?: StateStore> onDelete?: (id: string) => void flowHasChanged?: boolean + controlsPosition?: 'top' | 'bottom' } let { @@ -127,6 +128,7 @@ showJobStatus = false, suspendStatus = $bindable({ val: {} }), onDelete, + controlsPosition = 'top', flowHasChanged }: Props = $props() @@ -565,7 +567,7 @@ />
-
+
(noteMode = false)} onNotePositionUpdate={(noteId, position) => { // Update note position via NoteEditor context in edit mode diff --git a/frontend/src/lib/components/graph/FlowGraphV2.svelte b/frontend/src/lib/components/graph/FlowGraphV2.svelte index 3c7b0dd771..563a387184 100644 --- a/frontend/src/lib/components/graph/FlowGraphV2.svelte +++ b/frontend/src/lib/components/graph/FlowGraphV2.svelte @@ -198,6 +198,7 @@ diffBeforeFlow?: OpenFlow currentInputSchema?: Record markRemovedAsShadowed?: boolean + controlsPosition?: 'top' | 'bottom' outerDivClass?: string } @@ -271,6 +272,7 @@ onDuplicateMultiple = undefined, onMoveMultiple = undefined, movingIds = undefined, + controlsPosition = 'top', outerDivClass = '' }: Props = $props() @@ -754,12 +756,16 @@ } else { const minY = Math.min(...nodes.map((n) => n.position.y)) const maxBottom = Math.max(...nodes.map((n) => n.position.y + NODE.height + 100)) - height = Math.max(maxBottom - minY, minHeight) + const computed = maxBottom - minY + height = Math.max(Math.min(computed, maxHeight ?? computed), minHeight) } } $effect(() => { + // Track both bounds — updateHeight() reads both, so missing one (as + // maxHeight was) leaves height stale when only that bound changes. minHeight + maxHeight untrack(() => updateHeight()) }) @@ -1180,7 +1186,7 @@
{:else} n.type !== 'note') }} diff --git a/system_prompts/auto-generated/cli/cli-commands.md b/system_prompts/auto-generated/cli/cli-commands.md index a3f790ef01..f8bec5a868 100644 --- a/system_prompts/auto-generated/cli/cli-commands.md +++ b/system_prompts/auto-generated/cli/cli-commands.md @@ -35,6 +35,13 @@ app related commands - `app lint [app_folder:string]` - Lint a raw app folder to validate structure and buildability - `--fix` - Attempt to fix common issues (not implemented yet) - `app new` - create a new raw app from a template + - `--summary ` - App summary (short description). Skips the prompt when provided. Triggers non-interactive mode. + - `--path ` - App path (e.g., f/folder/my_app or u/username/my_app). Skips the prompt when provided. Triggers non-interactive mode. + - `--framework ` - Framework template: react19 | react18 | svelte5 | vue. Skips the prompt when provided. Triggers non-interactive mode. + - `--datatable ` - Datatable to wire up. Without this flag in non-interactive mode, no datatable is configured. + - `--schema ` - Schema to use with --datatable. Created (CREATE SCHEMA IF NOT EXISTS) if it doesn't already exist. + - `--overwrite` - Overwrite the target directory if it already exists, without prompting. + - `--no-open-in-desktop` - Do not prompt to open the new app in Claude Desktop. - `app generate-agents [app_folder:string]` - regenerate AGENTS.md and DATATABLES.md from remote workspace - `app set-permissioned-as ` - Set the on_behalf_of_email for an app (requires admin or wm_deployers group) @@ -71,10 +78,13 @@ workspace dependencies related commands ### dev -Launch a dev server that watches for local file changes and auto-pushes them to the remote workspace. Provides live reload for scripts and flows during development. +Watch local file changes and live-reload the dev page for preview. Does NOT deploy to the remote workspace — use wmill sync push for that. **Options:** -- `--includes ` - Filter paths givena glob pattern or path +- `--includes ` - Filter paths given a glob pattern or path +- `--proxy-port ` - Port for a localhost reverse proxy to the remote Windmill server +- `--path ` - Watch a specific windmill path (e.g., u/admin/my_script or f/my_flow) +- `--no-open` - Do not open the browser automatically ### docs diff --git a/system_prompts/auto-generated/flow.md b/system_prompts/auto-generated/flow.md index 49e2f73970..3b5b07ff76 100644 --- a/system_prompts/auto-generated/flow.md +++ b/system_prompts/auto-generated/flow.md @@ -1,14 +1,76 @@ # Windmill Flow Building Guide -## CLI Commands +## Creating a Flow + +**You — the AI agent — scaffold the flow yourself by running `wmill flow new ` with the right flags. Do NOT hand-create the folder + `flow.yaml`, and do NOT tell the user to "run `wmill flow new` and follow the prompts".** + +`wmill flow new` creates the folder with the correct suffix (`__flow` or `.flow` depending on the workspace's `nonDottedPaths` setting), writes a minimal `flow.yaml` shell, and prints Claude-specific next-step hints. Scaffolding by hand skips all of that and often picks the wrong suffix. + +### Step 1 — Gather path + summary by asking the user + +You need two things: + +1. **path** — the windmill path, e.g. `f/folder/my_flow` or `u/username/my_flow`. +2. **summary** — a short description of the flow. + +If the user's request didn't supply both, ask for both in a single round-trip. Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and provide one or two example values for each (with an "Other" / free-form fallback). Do not guess paths or summaries. + +### Step 2 — Run the command yourself + +```bash +wmill flow new f/folder/my_flow --summary "Short description" +``` + +Add `--description "..."` when the user provided a longer explanation worth preserving separately from the summary. + +### Step 3 — Fill in `flow.yaml` + +Open the generated `flow.yaml` (under the folder the command just created) and replace the empty `value.modules` + `schema` with the real flow definition. -Create a folder ending with `__flow` and add a `flow.yaml` file with the flow definition. For rawscript modules, use `!inline path/to/script.ts` for the content key. Inline script files should NOT include `.inline_script.` in their names (e.g. use `a.ts`, not `a.inline_script.ts`). -After writing, tell the user they can run: -- `wmill generate-metadata` - Generate lock files for the flow you modified -- `wmill sync push` - Deploy to Windmill -Do NOT run these commands yourself. Instead, inform the user that they should run them. +Once the flow has real content, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a `launch.json` entry) and the user should consent. + +### Anti-patterns to avoid + +- ❌ Hand-creating the `__flow` folder + `flow.yaml` instead of running `wmill flow new`. You'll miss the suffix-setting resolution, the default shape, and the Claude hints. +- ❌ Telling the user to "run `wmill flow new `" — you can and should run it yourself. +- ❌ Inventing a path/summary instead of asking the user. + +## CLI Commands — running, previewing, deploying + +After writing, tell the user which command fits what they want to do: + +- `wmill flow preview ` — **default when iterating on a local flow.** Runs the local `flow.yaml` against local inline scripts without deploying. Add `--remote` to use deployed workspace scripts for PathScript steps instead of local files. +- `wmill flow run ` — runs the flow **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — regenerate stale `.lock` and `.script.yaml` files. By default it scans **scripts, flows, and apps** across the workspace; pass `--skip-flows --skip-apps` (or run from a subdirectory) to limit the scope when you only care about the flow you edited. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the flow", "try it", "test it", "does it work" while there are **local edits to a `flow.yaml`**, use `flow preview`. Do NOT push the flow to then `flow run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `flow run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local `flow.yaml` being edited (you're just invoking an existing flow). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to run, don't wait passively + +This is about **programmatic execution** (`wmill flow preview -d ''`), which actually runs the flow and has side effects. Visual preview (the `preview` skill) is offered separately — see "Visual preview" below. + +If the user hasn't already told you to run/test the flow, offer it as a one-sentence next step (e.g. "Want me to run `wmill flow preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the flow in their original request, skip the offer and just execute `wmill flow preview -d ''` directly — pick plausible args from the flow's input schema. + +`wmill flow preview` is safe to run yourself (it does not deploy). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +### Visual preview + +To open the flow visually in the dev page (graph + live reload), use the `preview` skill. Always **offer** it as a one-sentence next step (e.g. "Want me to open the visual preview?") rather than opening it automatically — opening the dev page has side effects (browser window, possibly a `launch.json` entry under MCP-preview branches) the user should consent to. If the user already asked to see/preview/visualize the flow in their original request, skip the offer and just invoke the skill. ## OpenFlow Schema diff --git a/system_prompts/auto-generated/prompts.ts b/system_prompts/auto-generated/prompts.ts index b9fdd48ec8..b9f1875095 100644 --- a/system_prompts/auto-generated/prompts.ts +++ b/system_prompts/auto-generated/prompts.ts @@ -31,15 +31,77 @@ The preprocessor receives a single parameter called \`event\`. export const FLOW_BASE = `# Windmill Flow Building Guide -## CLI Commands +## Creating a Flow + +**You — the AI agent — scaffold the flow yourself by running \`wmill flow new \` with the right flags. Do NOT hand-create the folder + \`flow.yaml\`, and do NOT tell the user to "run \`wmill flow new\` and follow the prompts".** + +\`wmill flow new\` creates the folder with the correct suffix (\`__flow\` or \`.flow\` depending on the workspace's \`nonDottedPaths\` setting), writes a minimal \`flow.yaml\` shell, and prints Claude-specific next-step hints. Scaffolding by hand skips all of that and often picks the wrong suffix. + +### Step 1 — Gather path + summary by asking the user + +You need two things: + +1. **path** — the windmill path, e.g. \`f/folder/my_flow\` or \`u/username/my_flow\`. +2. **summary** — a short description of the flow. + +If the user's request didn't supply both, ask for both in a single round-trip. Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and provide one or two example values for each (with an "Other" / free-form fallback). Do not guess paths or summaries. + +### Step 2 — Run the command yourself + +\`\`\`bash +wmill flow new f/folder/my_flow --summary "Short description" +\`\`\` + +Add \`--description "..."\` when the user provided a longer explanation worth preserving separately from the summary. + +### Step 3 — Fill in \`flow.yaml\` + +Open the generated \`flow.yaml\` (under the folder the command just created) and replace the empty \`value.modules\` + \`schema\` with the real flow definition. -Create a folder ending with \`__flow\` and add a \`flow.yaml\` file with the flow definition. For rawscript modules, use \`!inline path/to/script.ts\` for the content key. Inline script files should NOT include \`.inline_script.\` in their names (e.g. use \`a.ts\`, not \`a.inline_script.ts\`). -After writing, tell the user they can run: -- \`wmill generate-metadata\` - Generate lock files for the flow you modified -- \`wmill sync push\` - Deploy to Windmill -Do NOT run these commands yourself. Instead, inform the user that they should run them. +Once the flow has real content, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a \`launch.json\` entry) and the user should consent. + +### Anti-patterns to avoid + +- ❌ Hand-creating the \`__flow\` folder + \`flow.yaml\` instead of running \`wmill flow new\`. You'll miss the suffix-setting resolution, the default shape, and the Claude hints. +- ❌ Telling the user to "run \`wmill flow new \`" — you can and should run it yourself. +- ❌ Inventing a path/summary instead of asking the user. + +## CLI Commands — running, previewing, deploying + +After writing, tell the user which command fits what they want to do: + +- \`wmill flow preview \` — **default when iterating on a local flow.** Runs the local \`flow.yaml\` against local inline scripts without deploying. Add \`--remote\` to use deployed workspace scripts for PathScript steps instead of local files. +- \`wmill flow run \` — runs the flow **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- \`wmill generate-metadata\` — regenerate stale \`.lock\` and \`.script.yaml\` files. By default it scans **scripts, flows, and apps** across the workspace; pass \`--skip-flows --skip-apps\` (or run from a subdirectory) to limit the scope when you only care about the flow you edited. +- \`wmill sync push\` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the flow", "try it", "test it", "does it work" while there are **local edits to a \`flow.yaml\`**, use \`flow preview\`. Do NOT push the flow to then \`flow run\` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use \`flow run\` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local \`flow.yaml\` being edited (you're just invoking an existing flow). + +Only use \`sync push\` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to run, don't wait passively + +This is about **programmatic execution** (\`wmill flow preview -d ''\`), which actually runs the flow and has side effects. Visual preview (the \`preview\` skill) is offered separately — see "Visual preview" below. + +If the user hasn't already told you to run/test the flow, offer it as a one-sentence next step (e.g. "Want me to run \`wmill flow preview\` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the flow in their original request, skip the offer and just execute \`wmill flow preview -d ''\` directly — pick plausible args from the flow's input schema. + +\`wmill flow preview\` is safe to run yourself (it does not deploy). \`wmill sync push\` and \`wmill generate-metadata\` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +### Visual preview + +To open the flow visually in the dev page (graph + live reload), use the \`preview\` skill. Always **offer** it as a one-sentence next step (e.g. "Want me to open the visual preview?") rather than opening it automatically — opening the dev page has side effects (browser window, possibly a \`launch.json\` entry under MCP-preview branches) the user should consent to. If the user already asked to see/preview/visualize the flow in their original request, skip the offer and just invoke the skill. ## OpenFlow Schema @@ -1794,6 +1856,13 @@ app related commands - \`app lint [app_folder:string]\` - Lint a raw app folder to validate structure and buildability - \`--fix\` - Attempt to fix common issues (not implemented yet) - \`app new\` - create a new raw app from a template + - \`--summary \` - App summary (short description). Skips the prompt when provided. Triggers non-interactive mode. + - \`--path \` - App path (e.g., f/folder/my_app or u/username/my_app). Skips the prompt when provided. Triggers non-interactive mode. + - \`--framework \` - Framework template: react19 | react18 | svelte5 | vue. Skips the prompt when provided. Triggers non-interactive mode. + - \`--datatable \` - Datatable to wire up. Without this flag in non-interactive mode, no datatable is configured. + - \`--schema \` - Schema to use with --datatable. Created (CREATE SCHEMA IF NOT EXISTS) if it doesn't already exist. + - \`--overwrite\` - Overwrite the target directory if it already exists, without prompting. + - \`--no-open-in-desktop\` - Do not prompt to open the new app in Claude Desktop. - \`app generate-agents [app_folder:string]\` - regenerate AGENTS.md and DATATABLES.md from remote workspace - \`app set-permissioned-as \` - Set the on_behalf_of_email for an app (requires admin or wm_deployers group) @@ -1830,10 +1899,13 @@ workspace dependencies related commands ### dev -Launch a dev server that watches for local file changes and auto-pushes them to the remote workspace. Provides live reload for scripts and flows during development. +Watch local file changes and live-reload the dev page for preview. Does NOT deploy to the remote workspace — use wmill sync push for that. **Options:** -- \`--includes \` - Filter paths givena glob pattern or path +- \`--includes \` - Filter paths given a glob pattern or path +- \`--proxy-port \` - Port for a localhost reverse proxy to the remote Windmill server +- \`--path \` - Watch a specific windmill path (e.g., u/admin/my_script or f/my_flow) +- \`--no-open\` - Do not open the browser automatically ### docs diff --git a/system_prompts/auto-generated/skills/cli-commands/SKILL.md b/system_prompts/auto-generated/skills/cli-commands/SKILL.md index 0d4d0f5616..ee59185423 100644 --- a/system_prompts/auto-generated/skills/cli-commands/SKILL.md +++ b/system_prompts/auto-generated/skills/cli-commands/SKILL.md @@ -40,6 +40,13 @@ app related commands - `app lint [app_folder:string]` - Lint a raw app folder to validate structure and buildability - `--fix` - Attempt to fix common issues (not implemented yet) - `app new` - create a new raw app from a template + - `--summary ` - App summary (short description). Skips the prompt when provided. Triggers non-interactive mode. + - `--path ` - App path (e.g., f/folder/my_app or u/username/my_app). Skips the prompt when provided. Triggers non-interactive mode. + - `--framework ` - Framework template: react19 | react18 | svelte5 | vue. Skips the prompt when provided. Triggers non-interactive mode. + - `--datatable ` - Datatable to wire up. Without this flag in non-interactive mode, no datatable is configured. + - `--schema ` - Schema to use with --datatable. Created (CREATE SCHEMA IF NOT EXISTS) if it doesn't already exist. + - `--overwrite` - Overwrite the target directory if it already exists, without prompting. + - `--no-open-in-desktop` - Do not prompt to open the new app in Claude Desktop. - `app generate-agents [app_folder:string]` - regenerate AGENTS.md and DATATABLES.md from remote workspace - `app set-permissioned-as ` - Set the on_behalf_of_email for an app (requires admin or wm_deployers group) @@ -76,10 +83,13 @@ workspace dependencies related commands ### dev -Launch a dev server that watches for local file changes and auto-pushes them to the remote workspace. Provides live reload for scripts and flows during development. +Watch local file changes and live-reload the dev page for preview. Does NOT deploy to the remote workspace — use wmill sync push for that. **Options:** -- `--includes ` - Filter paths givena glob pattern or path +- `--includes ` - Filter paths given a glob pattern or path +- `--proxy-port ` - Port for a localhost reverse proxy to the remote Windmill server +- `--path ` - Watch a specific windmill path (e.g., u/admin/my_script or f/my_flow) +- `--no-open` - Do not open the browser automatically ### docs diff --git a/system_prompts/auto-generated/skills/preview/SKILL.md b/system_prompts/auto-generated/skills/preview/SKILL.md new file mode 100644 index 0000000000..56bd54a201 --- /dev/null +++ b/system_prompts/auto-generated/skills/preview/SKILL.md @@ -0,0 +1,126 @@ +--- +name: preview +description: MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification. +--- + +# Windmill Preview Workflow + +Use this skill any time the user wants to **see**, **open**, **navigate to**, **visualize**, or **preview** a flow, script, or app — and any time you've just finished writing one and want to offer visual verification. + +The Windmill dev page renders the flow graph / script editor, lets the user step through steps, and live-reloads on every save. It runs locally via `wmill dev` and is reached on a localhost port. + +## Two independent decisions + +### 1. Mode: proxy or direct? + +`wmill dev` runs in two modes; pick by asking what kind of URL whatever will display the preview needs. + +- **Proxy** (`--proxy-port `) — exposes the dev page on `http://localhost:/`. Use it when the embedder you'll hand the URL to **only accepts localhost URLs** (most in-IDE / in-chat preview embedders do, because they sandbox cross-origin loads). +- **Direct** (default) — the user's browser loads the dev page from the remote workspace's HTTPS URL; the local `wmill dev` only runs the WebSocket back-channel for live reload. Use it when the URL will be opened in a regular browser tab. + +Default to **direct** unless you have a specific embedder that needs localhost. + +### 2. Who starts the server? + +- **You start it** in the background. Spawn `wmill dev …` (or `wmill app dev …`) yourself, capture the URL it prints, do whatever's next (open a tab, hand the URL to an embedder). +- **The runtime starts it from `.claude/launch.json`.** Some runtimes (currently the Claude Desktop / Claude Code MCP preview integration — tools prefixed with `mcp__Claude_Preview__`) can read a `launch.json` configuration and launch the dev server on demand when you invoke their preview tool. **Only take this path if you actually have such a tool** — otherwise nothing reads the file and `wmill dev` never starts. + +The two decisions compose. The common cases: + +| Embedder | Needs localhost? | launch.json runtime? | What to do | +|---|---|---|---| +| Regular browser tab | No | n/a | Direct mode, you start it, give URL to user | +| IDE / chat preview pane that takes any URL | No | No | Direct mode, you start it, point the embedder at the printed URL | +| IDE / chat preview pane that only accepts localhost | Yes | No | Proxy mode, you start it, point the embedder at `http://localhost:/` | +| Claude Desktop / Code MCP preview | Yes | Yes | Proxy mode, write a `launch.json` entry, invoke the MCP tool | + +Never start the proxy "just in case" — it adds the localhost hop for no benefit when no embedder needs it. + +## Starting the server yourself + +Use this when no `launch.json`-aware runtime is available, regardless of mode. + +For flows / scripts: +```bash +# Direct mode — gives you the remote dev-page URL +wmill dev --path --no-open + +# Proxy mode — gives you a localhost URL that 302s to the remote dev page +wmill dev --proxy-port 4000 --path --no-open +``` + +For apps: +```bash +cd __raw_app && wmill app dev --no-open --port 4000 +``` + +Each command prints the URL on stdout. Line shapes differ: + +- `wmill dev --no-open` (direct) prints `Go to ` with the full remote URL (workspace, token, path baked in). +- `wmill dev --proxy-port` prints `Dev proxy listening on http://localhost:` — the URL to hand to an embedder is `http://localhost:/`. +- `wmill app dev --no-open` prints `🚀 Dev server running at ` — the local app server. + +Capture the URL with a loose match (the first `https?://…` token after startup) and either hand it to your embedder or relay it to the user: *"Preview is running — open `` in your browser."* Don't construct the URL yourself; you don't have the workspace ID or auth token. + +These commands are long-running — start them in the background, don't block waiting. + +## Letting `launch.json` start the server (Claude Desktop / Code MCP only) + +Take this path when **and only when** an `mcp__Claude_Preview__*` MCP tool is exposed in your tool list. Skip it otherwise — without an MCP tool reading the file, `wmill dev` never starts. + +**Each flow / script / app gets its own named entry** in the user's `.claude/launch.json` so multiple previews coexist without colliding — each entry pins a different port + path. Never reuse a generic "windmill" entry for different targets. + +### Step 1 — Reuse or add a per-target entry in `.claude/launch.json` + +Convention: name the entry `windmill: ` (e.g. `windmill: f/test/my_flow`). + +- **Entry already exists** → reuse it; note its `port` for the next step. +- **Not there** → add one. Pick a port not already taken by another entry (start at 4000 and bump). Shape: + +For flows / scripts: +```json +{ + "name": "windmill: f/test/my_flow", + "runtimeExecutable": "bash", + "runtimeArgs": ["-c", "wmill dev --proxy-port ${PORT:-4000} --path f/test/my_flow --no-open"], + "port": 4000, + "autoPort": true +} +``` + +For apps (`*__raw_app/`), `wmill app dev` is the equivalent — runs from the app folder, no `--path`: +```json +{ + "name": "windmill: f/test/my_app", + "runtimeExecutable": "bash", + "runtimeArgs": ["-c", "cd f/test/my_app__raw_app && wmill app dev --no-open --port ${PORT:-4001}"], + "port": 4001, + "autoPort": true +} +``` + +If `.claude/launch.json` doesn't exist yet, create it with the standard shell `{ "version": "0.0.1", "configurations": [...] }`. + +### Step 2 — Invoke the MCP preview tool + +Point it at the entry you just added/found. Use `http://localhost:/` as the URL — the proxy's redirect at `/` is what appends the workspace ID, the auth token, and the path. Do **NOT** construct a `/dev?...` URL yourself. + +The MCP tool launches the configuration on demand, so you don't need to start the `wmill dev` process manually. + +## Non-visual alternative + +If the user wants a programmatic test rather than a visual one: +- Flow: `wmill flow preview -d ''` +- Script: `wmill script preview -d ''` + +Both print the job result, are safe to run yourself, and don't deploy. + +## Anti-patterns to avoid + +- ❌ Writing a `.claude/launch.json` entry when no `mcp__Claude_Preview__*` tool is in your tool list. Nothing will read the file; the server never starts. Spawn `wmill dev` yourself instead. +- ❌ Starting the proxy when no embedder needs a localhost URL. Direct mode is the right choice — the proxy is overhead with no purpose. +- ❌ Reusing a single generic `launch.json` entry for every preview target. Each flow/script/app gets its own named entry on its own port — that's how multiple sessions coexist without one preview clobbering another. +- ❌ Mutating an existing entry's `--path` to retarget it. Add a new entry instead. +- ❌ Constructing `http://localhost:/dev?path=` yourself. The proxy's `/` redirect is what appends the workspace ID and auth token; bypassing it gives a broken page. Always use `http://localhost:/`. +- ❌ Starting `wmill dev` in the foreground (you'll hang). Always background. +- ❌ Listing both "open in IDE pane" and "open in browser" as a menu — pick one based on context. diff --git a/system_prompts/auto-generated/skills/raw-app/SKILL.md b/system_prompts/auto-generated/skills/raw-app/SKILL.md index c835745158..5ac3a69cff 100644 --- a/system_prompts/auto-generated/skills/raw-app/SKILL.md +++ b/system_prompts/auto-generated/skills/raw-app/SKILL.md @@ -9,11 +9,70 @@ Raw apps let you build custom frontends with React, Svelte, or Vue that connect ## Creating a Raw App +**You — the AI agent — create the app yourself by running `wmill app new` with the right flags. Do NOT tell the user to "run `wmill app new` and follow the prompts" or wait for them to do it.** The bare `wmill app new` is an interactive wizard that hangs waiting for stdin in any non-TTY context (which includes you). Always pass flags. + +### Step 1 — Gather the three required values by asking the user + +You need three things to run the command: + +1. **summary** — a short description of the app +2. **path** — the windmill path, e.g. `f/folder/my_app` or `u/username/my_app` +3. **framework** — one of `react19` (recommended), `react18`, `svelte5`, `vue` + +If the user's request did not supply *every* one of these explicitly, ask. Do not guess values, do not invent paths, do not pick a framework on the user's behalf, do not "just use react19 because it's the default". + +Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and group all missing fields into a single round-trip so the user answers them at once: + +- For `framework` — multiple-choice with the four allowed values; mark `react19` as `(Recommended)` and put it first. +- For `summary` and `path` — provide one or two example values as multiple-choice options (the user can pick "Other" to type a free-form answer). + +Only proceed once you have concrete values for all three. If the user replies with something ambiguous, ask again rather than guessing. + +### Step 2 — Run the command yourself + +Once you have summary + path + framework, run it: + +```bash +wmill app new \ + --summary "Customer dashboard" \ + --path f/sales/dashboard \ + --framework react19 +``` + +That's the minimum. The datatable wizard and the "Open in Claude Desktop?" prompt are skipped silently because passing any of `--summary`/`--path`/`--framework` puts the command in non-interactive mode. + +### Optional flags + +Layer these in only when the user asked for them: + +| Flag | When to add it | +|---|---| +| `--datatable ` | The user wants this app wired to a specific Windmill datatable. Without it, the app is created with no datatable. | +| `--schema ` | Together with `--datatable`. Creates the schema with `CREATE SCHEMA IF NOT EXISTS` if it doesn't already exist. | +| `--overwrite` | The target directory already exists and the user said it's OK to replace. Without it, non-interactive mode aborts with an error so you don't clobber existing work. | +| `--no-open-in-desktop` | Already implied in non-interactive mode; only needed if you're somehow running interactively. | + +### Step 3 — Offer the visual preview + +After `wmill app new` and any initial edits to `App.tsx` / `index.tsx`, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a `launch.json` entry when an embedded preview tool is in play) the user should consent to. + +For apps the preview command runs from the app folder (`cd __raw_app && wmill app dev …`); the `preview` skill picks the proxy vs direct branch based on whether the runtime exposes a tool that can embed a localhost URL. If the user already asked to see/preview/visualize the app in their original request, skip the offer and just invoke the skill. + +### Anti-patterns to avoid + +- ❌ Running `wmill app new` with no flags (the prompt will hang). +- ❌ Telling the user to "run `wmill app new` and follow the prompts" — that's a step backwards from what you can do directly. +- ❌ Inventing a path/summary/framework instead of asking the user. +- ❌ Defaulting to `react19` because the user didn't say — even sensible defaults must be confirmed. +- ❌ Passing `--overwrite` automatically when the directory exists — confirm with the user first. + +### Interactive (only when a human is at the terminal) + ```bash wmill app new ``` -This interactive command creates a complete app structure with your choice of frontend framework (React, Svelte, or Vue). +This is the wizard. It only works when run by a human in a real terminal. Don't call it this way from an agent. ## App Structure @@ -237,12 +296,13 @@ data: ## CLI Commands -Tell the user they can run these commands (do NOT run them yourself): +`wmill app new` is the exception: you run it yourself, with flags, per the "Creating a Raw App" section above. + +For everything else, tell the user which command fits their intent and let them run it — these touch the workspace or local lock files, and the user should consent each time: | Command | Description | |---------|-------------| -| `wmill app new` | Create a new raw app interactively | -| `wmill app dev` | Start dev server with live reload | +| `wmill app dev` | Start dev server with live reload (see the `preview` skill for the full open-the-app-in-the-IDE-pane procedure). | | `wmill app generate-agents` | Refresh AGENTS.md and DATATABLES.md | | `wmill generate-metadata` | Generate lock files for backend runnables | | `wmill sync push` | Deploy app to Windmill | diff --git a/system_prompts/auto-generated/skills/write-flow/SKILL.md b/system_prompts/auto-generated/skills/write-flow/SKILL.md index 1d1398f888..65222e0479 100644 --- a/system_prompts/auto-generated/skills/write-flow/SKILL.md +++ b/system_prompts/auto-generated/skills/write-flow/SKILL.md @@ -5,15 +5,77 @@ description: MUST use when creating flows. # Windmill Flow Building Guide -## CLI Commands +## Creating a Flow + +**You — the AI agent — scaffold the flow yourself by running `wmill flow new ` with the right flags. Do NOT hand-create the folder + `flow.yaml`, and do NOT tell the user to "run `wmill flow new` and follow the prompts".** + +`wmill flow new` creates the folder with the correct suffix (`__flow` or `.flow` depending on the workspace's `nonDottedPaths` setting), writes a minimal `flow.yaml` shell, and prints Claude-specific next-step hints. Scaffolding by hand skips all of that and often picks the wrong suffix. + +### Step 1 — Gather path + summary by asking the user + +You need two things: + +1. **path** — the windmill path, e.g. `f/folder/my_flow` or `u/username/my_flow`. +2. **summary** — a short description of the flow. + +If the user's request didn't supply both, ask for both in a single round-trip. Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and provide one or two example values for each (with an "Other" / free-form fallback). Do not guess paths or summaries. + +### Step 2 — Run the command yourself + +```bash +wmill flow new f/folder/my_flow --summary "Short description" +``` + +Add `--description "..."` when the user provided a longer explanation worth preserving separately from the summary. + +### Step 3 — Fill in `flow.yaml` + +Open the generated `flow.yaml` (under the folder the command just created) and replace the empty `value.modules` + `schema` with the real flow definition. -Create a folder ending with `__flow` and add a `flow.yaml` file with the flow definition. For rawscript modules, use `!inline path/to/script.ts` for the content key. Inline script files should NOT include `.inline_script.` in their names (e.g. use `a.ts`, not `a.inline_script.ts`). -After writing, tell the user they can run: -- `wmill generate-metadata` - Generate lock files for the flow you modified -- `wmill sync push` - Deploy to Windmill -Do NOT run these commands yourself. Instead, inform the user that they should run them. +Once the flow has real content, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a `launch.json` entry) and the user should consent. + +### Anti-patterns to avoid + +- ❌ Hand-creating the `__flow` folder + `flow.yaml` instead of running `wmill flow new`. You'll miss the suffix-setting resolution, the default shape, and the Claude hints. +- ❌ Telling the user to "run `wmill flow new `" — you can and should run it yourself. +- ❌ Inventing a path/summary instead of asking the user. + +## CLI Commands — running, previewing, deploying + +After writing, tell the user which command fits what they want to do: + +- `wmill flow preview ` — **default when iterating on a local flow.** Runs the local `flow.yaml` against local inline scripts without deploying. Add `--remote` to use deployed workspace scripts for PathScript steps instead of local files. +- `wmill flow run ` — runs the flow **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — regenerate stale `.lock` and `.script.yaml` files. By default it scans **scripts, flows, and apps** across the workspace; pass `--skip-flows --skip-apps` (or run from a subdirectory) to limit the scope when you only care about the flow you edited. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the flow", "try it", "test it", "does it work" while there are **local edits to a `flow.yaml`**, use `flow preview`. Do NOT push the flow to then `flow run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `flow run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local `flow.yaml` being edited (you're just invoking an existing flow). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to run, don't wait passively + +This is about **programmatic execution** (`wmill flow preview -d ''`), which actually runs the flow and has side effects. Visual preview (the `preview` skill) is offered separately — see "Visual preview" below. + +If the user hasn't already told you to run/test the flow, offer it as a one-sentence next step (e.g. "Want me to run `wmill flow preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the flow in their original request, skip the offer and just execute `wmill flow preview -d ''` directly — pick plausible args from the flow's input schema. + +`wmill flow preview` is safe to run yourself (it does not deploy). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +### Visual preview + +To open the flow visually in the dev page (graph + live reload), use the `preview` skill. Always **offer** it as a one-sentence next step (e.g. "Want me to open the visual preview?") rather than opening it automatically — opening the dev page has side effects (browser window, possibly a `launch.json` entry under MCP-preview branches) the user should consent to. If the user already asked to see/preview/visualize the flow in their original request, skip the offer and just invoke the skill. ## OpenFlow Schema diff --git a/system_prompts/auto-generated/skills/write-script-bash/SKILL.md b/system_prompts/auto-generated/skills/write-script-bash/SKILL.md index 55f71ca172..ba4041c819 100644 --- a/system_prompts/auto-generated/skills/write-script-bash/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bash/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Bash scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-bigquery/SKILL.md b/system_prompts/auto-generated/skills/write-script-bigquery/SKILL.md index 02b1705ee2..e2347163c3 100644 --- a/system_prompts/auto-generated/skills/write-script-bigquery/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bigquery/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing BigQuery queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-bun/SKILL.md b/system_prompts/auto-generated/skills/write-script-bun/SKILL.md index 0e802b6fba..39d66a6433 100644 --- a/system_prompts/auto-generated/skills/write-script-bun/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bun/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Bun/TypeScript scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md b/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md index 3e411d4d81..442a6d4a7b 100644 --- a/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-bunnative/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Bun Native scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-csharp/SKILL.md b/system_prompts/auto-generated/skills/write-script-csharp/SKILL.md index 9d1b481ddf..98f089443e 100644 --- a/system_prompts/auto-generated/skills/write-script-csharp/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-csharp/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing C# scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-deno/SKILL.md b/system_prompts/auto-generated/skills/write-script-deno/SKILL.md index a250d5d60a..08b18f2a40 100644 --- a/system_prompts/auto-generated/skills/write-script-deno/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-deno/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Deno/TypeScript scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-duckdb/SKILL.md b/system_prompts/auto-generated/skills/write-script-duckdb/SKILL.md index 78a349b975..c19544da17 100644 --- a/system_prompts/auto-generated/skills/write-script-duckdb/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-duckdb/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing DuckDB queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-go/SKILL.md b/system_prompts/auto-generated/skills/write-script-go/SKILL.md index 5d04844115..9ff4e581e8 100644 --- a/system_prompts/auto-generated/skills/write-script-go/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-go/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Go scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-graphql/SKILL.md b/system_prompts/auto-generated/skills/write-script-graphql/SKILL.md index 010bfafbf6..727bf5309a 100644 --- a/system_prompts/auto-generated/skills/write-script-graphql/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-graphql/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing GraphQL queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-java/SKILL.md b/system_prompts/auto-generated/skills/write-script-java/SKILL.md index e07600e5a2..132cd603f1 100644 --- a/system_prompts/auto-generated/skills/write-script-java/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-java/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Java scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-mssql/SKILL.md b/system_prompts/auto-generated/skills/write-script-mssql/SKILL.md index a8ce92ff44..7a64a03ea7 100644 --- a/system_prompts/auto-generated/skills/write-script-mssql/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-mssql/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing MS SQL Server queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-mysql/SKILL.md b/system_prompts/auto-generated/skills/write-script-mysql/SKILL.md index 0cfd005dcd..2c9044be23 100644 --- a/system_prompts/auto-generated/skills/write-script-mysql/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-mysql/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing MySQL queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md b/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md index df981a2f90..7c0ea92a17 100644 --- a/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-nativets/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Native TypeScript scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-php/SKILL.md b/system_prompts/auto-generated/skills/write-script-php/SKILL.md index 0667139b12..0f8cb2e4a9 100644 --- a/system_prompts/auto-generated/skills/write-script-php/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-php/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing PHP scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-postgresql/SKILL.md b/system_prompts/auto-generated/skills/write-script-postgresql/SKILL.md index cb12fabf28..e370b7a3f2 100644 --- a/system_prompts/auto-generated/skills/write-script-postgresql/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-postgresql/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing PostgreSQL queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-powershell/SKILL.md b/system_prompts/auto-generated/skills/write-script-powershell/SKILL.md index 2c5787fa98..eadfa56b86 100644 --- a/system_prompts/auto-generated/skills/write-script-powershell/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-powershell/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing PowerShell scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-python3/SKILL.md b/system_prompts/auto-generated/skills/write-script-python3/SKILL.md index 04c87ca9eb..a0f16fb732 100644 --- a/system_prompts/auto-generated/skills/write-script-python3/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-python3/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Python scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-rlang/SKILL.md b/system_prompts/auto-generated/skills/write-script-rlang/SKILL.md index 27c08d5ef8..429bc2600f 100644 --- a/system_prompts/auto-generated/skills/write-script-rlang/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-rlang/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing R scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-rust/SKILL.md b/system_prompts/auto-generated/skills/write-script-rust/SKILL.md index cdbfd93ea6..52b61a0c0a 100644 --- a/system_prompts/auto-generated/skills/write-script-rust/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-rust/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Rust scripts. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/auto-generated/skills/write-script-snowflake/SKILL.md b/system_prompts/auto-generated/skills/write-script-snowflake/SKILL.md index 16e06c082a..68c49ffa6e 100644 --- a/system_prompts/auto-generated/skills/write-script-snowflake/SKILL.md +++ b/system_prompts/auto-generated/skills/write-script-snowflake/SKILL.md @@ -5,11 +5,36 @@ description: MUST use when writing Snowflake queries. ## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types. diff --git a/system_prompts/base/flow-base.md b/system_prompts/base/flow-base.md index 024f7152a9..ad15c37b44 100644 --- a/system_prompts/base/flow-base.md +++ b/system_prompts/base/flow-base.md @@ -1,14 +1,76 @@ # Windmill Flow Building Guide -## CLI Commands +## Creating a Flow + +**You — the AI agent — scaffold the flow yourself by running `wmill flow new ` with the right flags. Do NOT hand-create the folder + `flow.yaml`, and do NOT tell the user to "run `wmill flow new` and follow the prompts".** + +`wmill flow new` creates the folder with the correct suffix (`__flow` or `.flow` depending on the workspace's `nonDottedPaths` setting), writes a minimal `flow.yaml` shell, and prints Claude-specific next-step hints. Scaffolding by hand skips all of that and often picks the wrong suffix. + +### Step 1 — Gather path + summary by asking the user + +You need two things: + +1. **path** — the windmill path, e.g. `f/folder/my_flow` or `u/username/my_flow`. +2. **summary** — a short description of the flow. + +If the user's request didn't supply both, ask for both in a single round-trip. Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and provide one or two example values for each (with an "Other" / free-form fallback). Do not guess paths or summaries. + +### Step 2 — Run the command yourself + +```bash +wmill flow new f/folder/my_flow --summary "Short description" +``` + +Add `--description "..."` when the user provided a longer explanation worth preserving separately from the summary. + +### Step 3 — Fill in `flow.yaml` + +Open the generated `flow.yaml` (under the folder the command just created) and replace the empty `value.modules` + `schema` with the real flow definition. -Create a folder ending with `__flow` and add a `flow.yaml` file with the flow definition. For rawscript modules, use `!inline path/to/script.ts` for the content key. Inline script files should NOT include `.inline_script.` in their names (e.g. use `a.ts`, not `a.inline_script.ts`). -After writing, tell the user they can run: -- `wmill generate-metadata` - Generate lock files for the flow you modified -- `wmill sync push` - Deploy to Windmill -Do NOT run these commands yourself. Instead, inform the user that they should run them. +Once the flow has real content, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a `launch.json` entry) and the user should consent. + +### Anti-patterns to avoid + +- ❌ Hand-creating the `__flow` folder + `flow.yaml` instead of running `wmill flow new`. You'll miss the suffix-setting resolution, the default shape, and the Claude hints. +- ❌ Telling the user to "run `wmill flow new `" — you can and should run it yourself. +- ❌ Inventing a path/summary instead of asking the user. + +## CLI Commands — running, previewing, deploying + +After writing, tell the user which command fits what they want to do: + +- `wmill flow preview ` — **default when iterating on a local flow.** Runs the local `flow.yaml` against local inline scripts without deploying. Add `--remote` to use deployed workspace scripts for PathScript steps instead of local files. +- `wmill flow run ` — runs the flow **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — regenerate stale `.lock` and `.script.yaml` files. By default it scans **scripts, flows, and apps** across the workspace; pass `--skip-flows --skip-apps` (or run from a subdirectory) to limit the scope when you only care about the flow you edited. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the flow", "try it", "test it", "does it work" while there are **local edits to a `flow.yaml`**, use `flow preview`. Do NOT push the flow to then `flow run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `flow run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local `flow.yaml` being edited (you're just invoking an existing flow). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to run, don't wait passively + +This is about **programmatic execution** (`wmill flow preview -d ''`), which actually runs the flow and has side effects. Visual preview (the `preview` skill) is offered separately — see "Visual preview" below. + +If the user hasn't already told you to run/test the flow, offer it as a one-sentence next step (e.g. "Want me to run `wmill flow preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the flow in their original request, skip the offer and just execute `wmill flow preview -d ''` directly — pick plausible args from the flow's input schema. + +`wmill flow preview` is safe to run yourself (it does not deploy). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +### Visual preview + +To open the flow visually in the dev page (graph + live reload), use the `preview` skill. Always **offer** it as a one-sentence next step (e.g. "Want me to open the visual preview?") rather than opening it automatically — opening the dev page has side effects (browser window, possibly a `launch.json` entry under MCP-preview branches) the user should consent to. If the user already asked to see/preview/visualize the flow in their original request, skip the offer and just invoke the skill. ## OpenFlow Schema diff --git a/system_prompts/base/preview.md b/system_prompts/base/preview.md new file mode 100644 index 0000000000..585b1c8f6f --- /dev/null +++ b/system_prompts/base/preview.md @@ -0,0 +1,121 @@ +# Windmill Preview Workflow + +Use this skill any time the user wants to **see**, **open**, **navigate to**, **visualize**, or **preview** a flow, script, or app — and any time you've just finished writing one and want to offer visual verification. + +The Windmill dev page renders the flow graph / script editor, lets the user step through steps, and live-reloads on every save. It runs locally via `wmill dev` and is reached on a localhost port. + +## Two independent decisions + +### 1. Mode: proxy or direct? + +`wmill dev` runs in two modes; pick by asking what kind of URL whatever will display the preview needs. + +- **Proxy** (`--proxy-port `) — exposes the dev page on `http://localhost:/`. Use it when the embedder you'll hand the URL to **only accepts localhost URLs** (most in-IDE / in-chat preview embedders do, because they sandbox cross-origin loads). +- **Direct** (default) — the user's browser loads the dev page from the remote workspace's HTTPS URL; the local `wmill dev` only runs the WebSocket back-channel for live reload. Use it when the URL will be opened in a regular browser tab. + +Default to **direct** unless you have a specific embedder that needs localhost. + +### 2. Who starts the server? + +- **You start it** in the background. Spawn `wmill dev …` (or `wmill app dev …`) yourself, capture the URL it prints, do whatever's next (open a tab, hand the URL to an embedder). +- **The runtime starts it from `.claude/launch.json`.** Some runtimes (currently the Claude Desktop / Claude Code MCP preview integration — tools prefixed with `mcp__Claude_Preview__`) can read a `launch.json` configuration and launch the dev server on demand when you invoke their preview tool. **Only take this path if you actually have such a tool** — otherwise nothing reads the file and `wmill dev` never starts. + +The two decisions compose. The common cases: + +| Embedder | Needs localhost? | launch.json runtime? | What to do | +|---|---|---|---| +| Regular browser tab | No | n/a | Direct mode, you start it, give URL to user | +| IDE / chat preview pane that takes any URL | No | No | Direct mode, you start it, point the embedder at the printed URL | +| IDE / chat preview pane that only accepts localhost | Yes | No | Proxy mode, you start it, point the embedder at `http://localhost:/` | +| Claude Desktop / Code MCP preview | Yes | Yes | Proxy mode, write a `launch.json` entry, invoke the MCP tool | + +Never start the proxy "just in case" — it adds the localhost hop for no benefit when no embedder needs it. + +## Starting the server yourself + +Use this when no `launch.json`-aware runtime is available, regardless of mode. + +For flows / scripts: +```bash +# Direct mode — gives you the remote dev-page URL +wmill dev --path --no-open + +# Proxy mode — gives you a localhost URL that 302s to the remote dev page +wmill dev --proxy-port 4000 --path --no-open +``` + +For apps: +```bash +cd __raw_app && wmill app dev --no-open --port 4000 +``` + +Each command prints the URL on stdout. Line shapes differ: + +- `wmill dev --no-open` (direct) prints `Go to ` with the full remote URL (workspace, token, path baked in). +- `wmill dev --proxy-port` prints `Dev proxy listening on http://localhost:` — the URL to hand to an embedder is `http://localhost:/`. +- `wmill app dev --no-open` prints `🚀 Dev server running at ` — the local app server. + +Capture the URL with a loose match (the first `https?://…` token after startup) and either hand it to your embedder or relay it to the user: *"Preview is running — open `` in your browser."* Don't construct the URL yourself; you don't have the workspace ID or auth token. + +These commands are long-running — start them in the background, don't block waiting. + +## Letting `launch.json` start the server (Claude Desktop / Code MCP only) + +Take this path when **and only when** an `mcp__Claude_Preview__*` MCP tool is exposed in your tool list. Skip it otherwise — without an MCP tool reading the file, `wmill dev` never starts. + +**Each flow / script / app gets its own named entry** in the user's `.claude/launch.json` so multiple previews coexist without colliding — each entry pins a different port + path. Never reuse a generic "windmill" entry for different targets. + +### Step 1 — Reuse or add a per-target entry in `.claude/launch.json` + +Convention: name the entry `windmill: ` (e.g. `windmill: f/test/my_flow`). + +- **Entry already exists** → reuse it; note its `port` for the next step. +- **Not there** → add one. Pick a port not already taken by another entry (start at 4000 and bump). Shape: + +For flows / scripts: +```json +{ + "name": "windmill: f/test/my_flow", + "runtimeExecutable": "bash", + "runtimeArgs": ["-c", "wmill dev --proxy-port ${PORT:-4000} --path f/test/my_flow --no-open"], + "port": 4000, + "autoPort": true +} +``` + +For apps (`*__raw_app/`), `wmill app dev` is the equivalent — runs from the app folder, no `--path`: +```json +{ + "name": "windmill: f/test/my_app", + "runtimeExecutable": "bash", + "runtimeArgs": ["-c", "cd f/test/my_app__raw_app && wmill app dev --no-open --port ${PORT:-4001}"], + "port": 4001, + "autoPort": true +} +``` + +If `.claude/launch.json` doesn't exist yet, create it with the standard shell `{ "version": "0.0.1", "configurations": [...] }`. + +### Step 2 — Invoke the MCP preview tool + +Point it at the entry you just added/found. Use `http://localhost:/` as the URL — the proxy's redirect at `/` is what appends the workspace ID, the auth token, and the path. Do **NOT** construct a `/dev?...` URL yourself. + +The MCP tool launches the configuration on demand, so you don't need to start the `wmill dev` process manually. + +## Non-visual alternative + +If the user wants a programmatic test rather than a visual one: +- Flow: `wmill flow preview -d ''` +- Script: `wmill script preview -d ''` + +Both print the job result, are safe to run yourself, and don't deploy. + +## Anti-patterns to avoid + +- ❌ Writing a `.claude/launch.json` entry when no `mcp__Claude_Preview__*` tool is in your tool list. Nothing will read the file; the server never starts. Spawn `wmill dev` yourself instead. +- ❌ Starting the proxy when no embedder needs a localhost URL. Direct mode is the right choice — the proxy is overhead with no purpose. +- ❌ Reusing a single generic `launch.json` entry for every preview target. Each flow/script/app gets its own named entry on its own port — that's how multiple sessions coexist without one preview clobbering another. +- ❌ Mutating an existing entry's `--path` to retarget it. Add a new entry instead. +- ❌ Constructing `http://localhost:/dev?path=` yourself. The proxy's `/` redirect is what appends the workspace ID and auth token; bypassing it gives a broken page. Always use `http://localhost:/`. +- ❌ Starting `wmill dev` in the foreground (you'll hang). Always background. +- ❌ Listing both "open in IDE pane" and "open in browser" as a menu — pick one based on context. diff --git a/system_prompts/base/raw-app.md b/system_prompts/base/raw-app.md index ac1292a5df..4114c55a60 100644 --- a/system_prompts/base/raw-app.md +++ b/system_prompts/base/raw-app.md @@ -4,11 +4,70 @@ Raw apps let you build custom frontends with React, Svelte, or Vue that connect ## Creating a Raw App +**You — the AI agent — create the app yourself by running `wmill app new` with the right flags. Do NOT tell the user to "run `wmill app new` and follow the prompts" or wait for them to do it.** The bare `wmill app new` is an interactive wizard that hangs waiting for stdin in any non-TTY context (which includes you). Always pass flags. + +### Step 1 — Gather the three required values by asking the user + +You need three things to run the command: + +1. **summary** — a short description of the app +2. **path** — the windmill path, e.g. `f/folder/my_app` or `u/username/my_app` +3. **framework** — one of `react19` (recommended), `react18`, `svelte5`, `vue` + +If the user's request did not supply *every* one of these explicitly, ask. Do not guess values, do not invent paths, do not pick a framework on the user's behalf, do not "just use react19 because it's the default". + +Use whichever interactive question facility your runtime provides — a structured multi-choice tool if available, otherwise plain chat — and group all missing fields into a single round-trip so the user answers them at once: + +- For `framework` — multiple-choice with the four allowed values; mark `react19` as `(Recommended)` and put it first. +- For `summary` and `path` — provide one or two example values as multiple-choice options (the user can pick "Other" to type a free-form answer). + +Only proceed once you have concrete values for all three. If the user replies with something ambiguous, ask again rather than guessing. + +### Step 2 — Run the command yourself + +Once you have summary + path + framework, run it: + +```bash +wmill app new \ + --summary "Customer dashboard" \ + --path f/sales/dashboard \ + --framework react19 +``` + +That's the minimum. The datatable wizard and the "Open in Claude Desktop?" prompt are skipped silently because passing any of `--summary`/`--path`/`--framework` puts the command in non-interactive mode. + +### Optional flags + +Layer these in only when the user asked for them: + +| Flag | When to add it | +|---|---| +| `--datatable ` | The user wants this app wired to a specific Windmill datatable. Without it, the app is created with no datatable. | +| `--schema ` | Together with `--datatable`. Creates the schema with `CREATE SCHEMA IF NOT EXISTS` if it doesn't already exist. | +| `--overwrite` | The target directory already exists and the user said it's OK to replace. Without it, non-interactive mode aborts with an error so you don't clobber existing work. | +| `--no-open-in-desktop` | Already implied in non-interactive mode; only needed if you're somehow running interactively. | + +### Step 3 — Offer the visual preview + +After `wmill app new` and any initial edits to `App.tsx` / `index.tsx`, **offer** to open the visual preview as a one-sentence next step (e.g. "Want me to open the visual preview?"). Don't auto-open — opening the dev page has side effects (browser window, possibly a `launch.json` entry when an embedded preview tool is in play) the user should consent to. + +For apps the preview command runs from the app folder (`cd __raw_app && wmill app dev …`); the `preview` skill picks the proxy vs direct branch based on whether the runtime exposes a tool that can embed a localhost URL. If the user already asked to see/preview/visualize the app in their original request, skip the offer and just invoke the skill. + +### Anti-patterns to avoid + +- ❌ Running `wmill app new` with no flags (the prompt will hang). +- ❌ Telling the user to "run `wmill app new` and follow the prompts" — that's a step backwards from what you can do directly. +- ❌ Inventing a path/summary/framework instead of asking the user. +- ❌ Defaulting to `react19` because the user didn't say — even sensible defaults must be confirmed. +- ❌ Passing `--overwrite` automatically when the directory exists — confirm with the user first. + +### Interactive (only when a human is at the terminal) + ```bash wmill app new ``` -This interactive command creates a complete app structure with your choice of frontend framework (React, Svelte, or Vue). +This is the wizard. It only works when run by a human in a real terminal. Don't call it this way from an agent. ## App Structure @@ -232,12 +291,13 @@ data: ## CLI Commands -Tell the user they can run these commands (do NOT run them yourself): +`wmill app new` is the exception: you run it yourself, with flags, per the "Creating a Raw App" section above. + +For everything else, tell the user which command fits their intent and let them run it — these touch the workspace or local lock files, and the user should consent each time: | Command | Description | |---------|-------------| -| `wmill app new` | Create a new raw app interactively | -| `wmill app dev` | Start dev server with live reload | +| `wmill app dev` | Start dev server with live reload (see the `preview` skill for the full open-the-app-in-the-IDE-pane procedure). | | `wmill app generate-agents` | Refresh AGENTS.md and DATATABLES.md | | `wmill generate-metadata` | Generate lock files for backend runnables | | `wmill sync push` | Deploy app to Windmill | diff --git a/system_prompts/generate.py b/system_prompts/generate.py index aa9cf2b85b..f861c3fd3d 100644 --- a/system_prompts/generate.py +++ b/system_prompts/generate.py @@ -931,6 +931,11 @@ SKILL_DEFINITIONS = [ 'description': 'MUST use when using the CLI, including debugging job failures and inspecting run history via `wmill job`.', 'content_key': 'cli_commands', }, + { + 'name': 'preview', + 'description': 'MUST use when opening the Windmill dev page / visual preview of a flow, script, or app. Triggers on words like preview, open, navigate to, visualize, see the flow/app/script, and after writing a flow/script/app for visual verification.', + 'content_key': 'preview', + }, ] @@ -960,16 +965,42 @@ def generate_skills( 'schedules': read_markdown_file(base_dir / "schedules.md"), 'resources': read_markdown_file(base_dir / "resources.md"), 'cli_commands': cli_commands, + 'preview': read_markdown_file(base_dir / "preview.md"), } # CLI intro for script skills script_cli_intro = """## CLI Commands -Place scripts in a folder. After writing, tell the user they can run: -- `wmill generate-metadata` - Generate .script.yaml and .lock files -- `wmill sync push` - Deploy to Windmill +Place scripts in a folder. -Do NOT run these commands yourself. Instead, inform the user that they should run them. +After writing, tell the user which command fits what they want to do: + +- `wmill script preview ` — **default when iterating on a local script.** Runs the local file without deploying. +- `wmill script run ` — runs the script **already deployed** in the workspace. Use only when the user explicitly wants to test the deployed version, not local edits. +- `wmill generate-metadata` — generate `.script.yaml` and `.lock` files for the script you modified. +- `wmill sync push` — deploy local changes to the workspace. Only suggest/run this when the user explicitly asks to deploy/publish/push — not when they say "run", "try", or "test". + +### Preview vs run — choose by intent, not habit + +If the user says "run the script", "try it", "test it", "does it work" while there are **local edits to the script file**, use `script preview`. Do NOT push the script to then `script run` it — pushing is a deploy, and deploying just to test overwrites the workspace version with untested changes. + +Only use `script run` when: +- The user explicitly says "run the deployed version" / "run what's on the server". +- There is no local script being edited (you're just invoking an existing script). + +Only use `sync push` when: +- The user explicitly asks to deploy, publish, push, or ship. +- The preview has already validated the change and the user wants it in the workspace. + +### After writing — offer to test, don't wait passively + +If the user hasn't already told you to run/test/preview the script, offer it as a one-sentence next step (e.g. "Want me to run `wmill script preview` with sample args?"). Do not present a multi-option menu. + +If the user already asked to test/run/try the script in their original request, skip the offer and just execute `wmill script preview -d ''` directly — pick plausible args from the script's declared parameters. The shape varies by language: `main(...)` for code languages, the SQL dialect's own placeholder syntax (`$1` for PostgreSQL, `?` for MySQL/Snowflake, `@P1` for MSSQL, `@name` for BigQuery, etc.), positional `$1`, `$2`, … for Bash, `param(...)` for PowerShell. + +`wmill script preview` does not deploy, but it still executes script code and may cause side effects; run it yourself when the user asked to test/preview (or after confirming that execution is intended). `wmill sync push` and `wmill generate-metadata` modify workspace state or local files — only run these when the user explicitly asks; otherwise tell them which to run. + +For a **visual** open-the-script-in-the-dev-page preview (rather than `script preview`'s run-and-print-result), use the `preview` skill. Use `wmill resource-type list --schema` to discover available resource types."""