/run-wenlan-app
Build, launch, screenshot, and drive the wenlan-app Tauri desktop app in dev mode on macOS (WKWebView) or Windows (WebView2). Use when asked to run or start the app, verify a UI change in the real running app (not just tests), or take a screenshot of it.
Claude Code
$ npx -y skills add wenlan-app/wenlan --skill run-wenlan-app --agent claude-code
Codex
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a codex -y
Cursor
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a cursor -y
Gemini CLI
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a gemini-cli -y
GitHub Copilot
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a github-copilot -y
OpenCode
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a opencode -y
Windsurf
$ npx skills add wenlan-app/wenlan --skill run-wenlan-app -a windsurf -y
SKILL.md
run-wenlan-app.SKILL.mdname: run-wenlan-app
description: Build, launch, screenshot, and drive the wenlan-app Tauri desktop app in dev mode on macOS (WKWebView) or Windows (WebView2). Use when asked to run or start the app, verify a UI change in the real running app (not just tests), or take a screenshot of it.
Run wenlan-app (dev)
Tauri 2 desktop app (Rust `app/` + React/Vite frontend on :1420). Drive it with `.claude/skills/run-wenlan-app/driver.sh` — all paths below are relative to the unit root (repo or worktree root).
**Prerequisites, both Run sections, Gotchas, and Troubleshooting below are macOS only** (`driver.sh`, vite, ScreenCaptureKit). On Windows the webview is WebView2 and the recipe is different — jump to [Windows (WebView2)](#windows-webview2).
A debug build refuses to start without a complete isolated runtime identity (`validate_debug_runtime_isolation` in `app/src/lib.rs`), so `launch` takes the worktree-scoped config from `scripts/dev-runtime.sh` and starts its **own** daemon on the worktree port. The user's live `wenlan-server` on `:7878` is never the daemon under test and **must never be killed**; `stop` only ends the daemon this worktree recorded.
Prerequisites
- `pnpm install` done in the unit root (worktrees start without `node_modules`).
- No sibling checkout needed: the monorepo checkout is the backend, and
`scripts/resolve-backend-dir.sh` probes the repo root first (an explicit `WENLAN_BACKEND_DIR` overrides it; a sibling checkout is only a legacy fallback). Cargo builds in the main checkout's warm, shared target (`CARGO_TARGET_DIR` defaults to it via `git rev-parse --git-common-dir`). Never launch `target/debug/wenlan-app` from there: it is whichever checkout built last. `build` clones it and its sidecars into this checkout's `target/wenlan-dev-app/` (APFS `cp -c`: shares blocks until the shared target is rebuilt, ~370 MB per worktree at most) and `launch` runs only that clone. Do not give a worktree its own `CARGO_TARGET_DIR`: that costs ~14 GB per worktree.
- Terminal needs macOS Screen Recording permission (for `shot`).
Run (agent path)
.claude/skills/run-wenlan-app/driver.sh build # clean workspace crates, force sidecars, cargo build with this worktree's devUrl/app id baked in
.claude/skills/run-wenlan-app/driver.sh launch # isolated daemon + this worktree's vite + launch target/wenlan-dev-app/wenlan-app directly → "APP UP"
.claude/skills/run-wenlan-app/driver.sh shot /tmp/shot.png # window PNG, works while occluded
.claude/skills/run-wenlan-app/driver.sh stop # kills only this checkout's dev app, vite, and daemon; never :7878 or another session's
Logs land in `$TMPDIR/wenlan-app.log` and `$TMPDIR/wenlan-vite.log`. **Look at the screenshot** after `shot` — a blank frame means the frontend did not load.
Driving UI state
Synthetic events (`CGEvent.postToPid`) are **not handled** by Tauri's WKWebView, and global coordinate clicks are forbidden here (other live agent sessions share this desktop; a stray click once hit the updater's Install button and it consumed `target/debug/wenlan-app`). Instead, drive UI state through **vite HMR**: make a temporary `import.meta.env.DEV`-guarded edit (e.g. force a section expanded, early-return a toast), wait ~3s, `shot`, revert the edit. Mark such edits `// TEMP (do not commit)`.
Run (human path)
`pnpm dev:all` — the supported entry point: an isolated worktree daemon plus `pnpm tauri dev` with a dev bundle identifier and the worktree UI port. Agents use `driver.sh` instead because `tauri dev` dies on cold caches (see Gotchas). Ctrl-C to stop.
Windows (WebView2)
`driver.sh`, vite, and `wincap.swift` are macOS-only. On Windows the app hosts WebView2, is driven over WebDriver, and is captured with `PrintWindow`. There is no committed Windows driver script yet; the recipe below is what a live run on Windows 11 actually required.
1. Build
export CARGO_TARGET_DIR=C:/wl-target # warm cache; keeps target/ off the worktree
export PATH="/c/Strawberry/perl/bin:$PATH" # see gotcha: openssl-sys needs a real perl
cargo build -p wenlan-app --features tauri/custom-protocol
`--features tauri/custom-protocol` is the important part: it flips `tauri-macros`' `dev` flag off, so the binary **embeds `dist/`** instead of loading `devUrl`. That removes vite and :1420 from the picture entirely — a plain `cargo build -p wenlan-app` gives you the macOS-style dev binary that needs a vite server on :1420. Run `pnpm build` first so `dist/` is current.
`wenlan-app` depends on `wenlan-types`, **not** `wenlan-core`, so the app builds even on a host where the daemon crates cannot (see the Vulkan gotcha).
2. Isolated runtime identity
A debug build refuses to start without one (`validate_debug_runtime_isolation`, `app/src/lib.rs`). Take the worktree-scoped values from `bash scripts/dev-runtime.sh print-config` and export `WENLAN_PORT`, `WENLAN_DEV_UI_PORT`, `WENLAN_DEV_REMOTE_PORT_START`, `WENLAN_DEV_APP_ID`, `WENLAN_DEV_STATE_DIR`, `WENLAN_DATA_DIR`, `WENLAN_DEV_TAURI_MCP_SOCKET`, plus `WENLAN_NO_AUTOSTART=1`.
Two things that are easy to miss:
- **The bundle identifier must be overridden at build time**, not runtime.
`tauri_plugin_single_instance` keys on it, so a debug build carrying the production `com.wenlan.desktop` will hand its argv to the user's real running app instead of starting. The only lever without the tauri CLI is `TAURI_CONFIG` (json_patch-merged by both `tauri-build` and `tauri-codegen`):
export TAURI_CONFIG='{"identifier":"com.wenlan.desktop.dev.<worktree-hash>"}'Set it for the build and confirm it landed: `strings` the binary for the id.
- **`knowledge_path` must be written explicitly** into
`$WENLAN_DATA_DIR/config.json`. It defaults to `.wenlan/pages` under the OS user home — *not* under `WENLAN_DATA_DIR` — so without it an "isolated" run writes pages into the developer's real memory.
3.
Read more
name: run-wenlan-app description: Build, launch, screenshot, and drive the wenlan-app Tauri desktop app in dev mode on macOS (WKWebView) or Windows (WebView2). Use when asked to run or start the app, verify a UI change in the real running app (not just tests), or take a screenshot of it.
Run wenlan-app (dev)
Tauri 2 desktop app (Rust `app/` + React/Vite frontend on :1420). Drive it with `.claude/skills/run-wenlan-app/driver.sh` — all paths below are relative to the unit root (repo or worktree root).
**Prerequisites, both Run sections, Gotchas, and Troubleshooting below are macOS only** (`driver.sh`, vite, ScreenCaptureKit). On Windows the webview is WebView2 and the recipe is different — jump to [Windows (WebView2)](#windows-webview2).
A debug build refuses to start without a complete isolated runtime identity (`validate_debug_runtime_isolation` in `app/src/lib.rs`), so `launch` takes the worktree-scoped config from `scripts/dev-runtime.sh` and starts its **own** daemon on the worktree port. The user's live `wenlan-server` on `:7878` is never the daemon under test and **must never be killed**; `stop` only ends the daemon this worktree recorded.
Prerequisites
- `pnpm install` done in the unit root (worktrees start without `node_modules`).
- No sibling checkout needed: the monorepo checkout is the backend, and
`scripts/resolve-backend-dir.sh` probes the repo root first (an explicit `WENLAN_BACKEND_DIR` overrides it; a sibling checkout is only a legacy fallback). Cargo builds in the main checkout's warm, shared target (`CARGO_TARGET_DIR` defaults to it via `git rev-parse --git-common-dir`). Never launch `target/debug/wenlan-app` from there: it is whichever checkout built last. `build` clones it and its sidecars into this checkout's `target/wenlan-dev-app/` (APFS `cp -c`: shares blocks until the shared target is rebuilt, ~370 MB per worktree at most) and `launch` runs only that clone. Do not give a worktree its own `CARGO_TARGET_DIR`: that costs ~14 GB per worktree.
- Terminal needs macOS Screen Recording permission (for `shot`).
Run (agent path)
.claude/skills/run-wenlan-app/driver.sh build # clean workspace crates, force sidecars, cargo build with this worktree's devUrl/app id baked in .claude/skills/run-wenlan-app/driver.sh launch # isolated daemon + this worktree's vite + launch target/wenlan-dev-app/wenlan-app directly → "APP UP" .claude/skills/run-wenlan-app/driver.sh shot /tmp/shot.png # window PNG, works while occluded .claude/skills/run-wenlan-app/driver.sh stop # kills only this checkout's dev app, vite, and daemon; never :7878 or another session's
Logs land in `$TMPDIR/wenlan-app.log` and `$TMPDIR/wenlan-vite.log`. **Look at the screenshot** after `shot` — a blank frame means the frontend did not load.
Driving UI state
Synthetic events (`CGEvent.postToPid`) are **not handled** by Tauri's WKWebView, and global coordinate clicks are forbidden here (other live agent sessions share this desktop; a stray click once hit the updater's Install button and it consumed `target/debug/wenlan-app`). Instead, drive UI state through **vite HMR**: make a temporary `import.meta.env.DEV`-guarded edit (e.g. force a section expanded, early-return a toast), wait ~3s, `shot`, revert the edit. Mark such edits `// TEMP (do not commit)`.
Run (human path)
`pnpm dev:all` — the supported entry point: an isolated worktree daemon plus `pnpm tauri dev` with a dev bundle identifier and the worktree UI port. Agents use `driver.sh` instead because `tauri dev` dies on cold caches (see Gotchas). Ctrl-C to stop.
Windows (WebView2)
`driver.sh`, vite, and `wincap.swift` are macOS-only. On Windows the app hosts WebView2, is driven over WebDriver, and is captured with `PrintWindow`. There is no committed Windows driver script yet; the recipe below is what a live run on Windows 11 actually required.
1. Build
export CARGO_TARGET_DIR=C:/wl-target # warm cache; keeps target/ off the worktree export PATH="/c/Strawberry/perl/bin:$PATH" # see gotcha: openssl-sys needs a real perl cargo build -p wenlan-app --features tauri/custom-protocol
`--features tauri/custom-protocol` is the important part: it flips `tauri-macros`' `dev` flag off, so the binary **embeds `dist/`** instead of loading `devUrl`. That removes vite and :1420 from the picture entirely — a plain `cargo build -p wenlan-app` gives you the macOS-style dev binary that needs a vite server on :1420. Run `pnpm build` first so `dist/` is current.
`wenlan-app` depends on `wenlan-types`, **not** `wenlan-core`, so the app builds even on a host where the daemon crates cannot (see the Vulkan gotcha).
2. Isolated runtime identity
A debug build refuses to start without one (`validate_debug_runtime_isolation`, `app/src/lib.rs`). Take the worktree-scoped values from `bash scripts/dev-runtime.sh print-config` and export `WENLAN_PORT`, `WENLAN_DEV_UI_PORT`, `WENLAN_DEV_REMOTE_PORT_START`, `WENLAN_DEV_APP_ID`, `WENLAN_DEV_STATE_DIR`, `WENLAN_DATA_DIR`, `WENLAN_DEV_TAURI_MCP_SOCKET`, plus `WENLAN_NO_AUTOSTART=1`.
Two things that are easy to miss:
- **The bundle identifier must be overridden at build time**, not runtime.
`tauri_plugin_single_instance` keys on it, so a debug build carrying the production `com.wenlan.desktop` will hand its argv to the user's real running app instead of starting. The only lever without the tauri CLI is `TAURI_CONFIG` (json_patch-merged by both `tauri-build` and `tauri-codegen`):
export TAURI_CONFIG='{"identifier":"com.wenlan.desktop.dev.<worktree-hash>"}'Set it for the build and confirm it landed: `strings` the binary for the id.
- **`knowledge_path` must be written explicitly** into
`$WENLAN_DATA_DIR/config.json`. It defaults to `.wenlan/pages` under the OS user home — *not* under `WENLAN_DATA_DIR` — so without it an "isolated" run writes pages into the developer's real memory.
3.
Open-source Obsidian alternative that works with your existing vault. The knowledge base you don't have to maintain: your AI tools keep it organized and up to date, with no API keys or plugins to set up. For you and your team.
Other skills on wenlan.
More skills from other plugins.
codebase-wiki
How to work in a Codebase Wiki project (the `codebase-wiki` starter pack): an agent-authored, source-grounded wiki of the…
academic-paper-reviewe…
Simulates academic peer review, evaluating papers across Originality, Methodology, Results, and Writing to provide Major/Minor…
Questions about run-wenlan-app.
- Which coding agents can use run-wenlan-app?
- run-wenlan-app installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

