From 8f74dfed5c2ed87c5589301479084eb772ec2f1a Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Fri, 24 Apr 2026 10:04:04 +0200 Subject: [PATCH] feat(cli): wmill init creates root .claude/launch.json for the picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a workspace-root .claude/launch.json so Claude Code can launch `wmill dev` from the project root and land on the file picker (no --path → picker mode). Per-flow and per-raw_app launch.json files are already generated by the existing scans. Skipped (with a gray log) if the file already exists, so the user's customizations are preserved. Co-Authored-By: Claude Opus 4.7 (1M context) --- cli/src/commands/init/init.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/cli/src/commands/init/init.ts b/cli/src/commands/init/init.ts index 26f42d39f6..a8decb7a39 100644 --- a/cli/src/commands/init/init.ts +++ b/cli/src/commands/init/init.ts @@ -1,6 +1,6 @@ import { stat, writeFile, rm, readdir } from "node:fs/promises"; import { join } from "node:path"; -import { writeFileSync, mkdirSync } from "node:fs"; +import { writeFileSync, mkdirSync, existsSync } from "node:fs"; import { colors } from "@cliffy/ansi/colors"; import { Command } from "@cliffy/command"; import { Confirm } from "@cliffy/prompt/confirm"; @@ -274,6 +274,34 @@ async function initAction(opts: InitOptions) { } } + // Generate .claude/launch.json at the workspace root so Claude Code can launch + // `wmill dev` from there and land on the file picker (no --path → picker mode). + try { + const rootClaudeDir = join(".", ".claude"); + const rootLaunchPath = join(rootClaudeDir, "launch.json"); + if (existsSync(rootLaunchPath)) { + log.info(colors.gray(`Skipped ${rootLaunchPath} (already exists)`)); + } else { + const rootLaunchJson = JSON.stringify({ + version: "0.0.1", + configurations: [{ + name: "windmill", + runtimeExecutable: "bash", + runtimeArgs: ["-c", "wmill dev --proxy-port ${PORT:-4000} --no-open"], + port: 4000, + autoPort: true, + }], + }, null, 2) + "\n"; + mkdirSync(rootClaudeDir, { recursive: true }); + writeFileSync(rootLaunchPath, rootLaunchJson, "utf-8"); + log.info(colors.green(`Created ${rootLaunchPath}`)); + } + } catch (error) { + log.warn( + `Could not create root .claude/launch.json: ${error instanceof Error ? error.message : error}` + ); + } + // Generate .claude/launch.json for each flow folder try { const flowSuffix = nonDottedPaths ? "__flow" : ".flow";