diff --git a/README.md b/README.md
index ff10ed6..cee5bed 100644
--- a/README.md
+++ b/README.md
@@ -4,22 +4,22 @@ Minimal SDL3 + Vulkan spinning cube demo.
 ## Cheat sheet
 
 ### Dependencies
-- python scripts/dev_commands.py dependencies installs the Conan graph in uild.
+- `python scripts/dev_commands.py dependencies` installs the Conan graph in `build`.
 
 ### Configure & build
-- python scripts/dev_commands.py configure defaults to Ninja+MSVC on Windows or Ninja on other platforms, writing into the matching uild-ninja-msvc/uild-ninja folder with the Release type; override the generator or build dir with --generator / --build-dir if needed.
-- python scripts/dev_commands.py build runs cmake --build in the same folder (change --build-dir to match a different configure directory).
-- python scripts/dev_commands.py msvc-quick (Windows only) runs the VC vars + Ninja build alias; pass --bat-path to target a different Visual Studio installation.
-- python scripts/dev_commands.py run launches spinning_cube from the configured Ninja output.
-- Prefix any subcommand with --dry-run to print the alias-driven shell command instead of executing it.
+- `python scripts/dev_commands.py configure` defaults to Ninja+MSVC on Windows or plain Ninja on Linux/macOS, writing into the matching `build-ninja-msvc`/`build-ninja` folder with the `Release` build type; override the generator or build directory with `--generator` / `--build-dir` if you need something else.
+- `python scripts/dev_commands.py build` runs `cmake --build` in the same folder (change `--build-dir` to match a different configure directory).
+- `python scripts/dev_commands.py msvc-quick` (Windows only) runs the VC vars + Ninja build alias; pass `--bat-path` to target a different Visual Studio installation.
+- `python scripts/dev_commands.py run` launches `sdl3_app` (use `--target` to run another executable and `--args` to forward CLI arguments).
+- Prefix any subcommand with `--dry-run` to print the alias-driven shell command without executing it.
 
 ### Run
-- python scripts/dev_commands.py run [--build-dir ...] (source uild/conanrun.sh / uild\\conanrun.bat first if Conan exports env vars).
+- `python scripts/dev_commands.py run [--build-dir ...]` (source `build/conanrun.sh` / `build\conanrun.bat` first if the Conan runtime exports env vars).
 
 ## Runtime configuration
-1. sdl3_app --json-file-in <path> loads JSON configs (script path, window size, lua_debug, etc.).
-2. sdl3_app --create-seed-json config/seed_runtime.json writes a starter file assuming scripts/cube_logic.lua sits beside the binary.
-3. sdl3_app --set-default-json [path] stores or overrides the runtime JSON; Windows writes %APPDATA%/sdl3cpp, other OSes use $XDG_CONFIG_HOME/sdl3cpp/default_runtime.json (fallback ~/.config/sdl3cpp).
+1. `sdl3_app --json-file-in <path>` loads JSON configs (script path, window size, `lua_debug`, etc.).
+2. `sdl3_app --create-seed-json config/seed_runtime.json` writes a starter file assuming `scripts/cube_logic.lua` sits beside the binary.
+3. `sdl3_app --set-default-json [path]` stores or overrides the runtime JSON; Windows writes `%APPDATA%/sdl3cpp`, other OSes use `$XDG_CONFIG_HOME/sdl3cpp/default_runtime.json` (fallback `~/.config/sdl3cpp`).
 
 ### GUI Demo
-scripts/gui_demo.lua paints the Lua GUI framework on top of the Vulkan scene. Launch it as ./build/sdl3_app --json-file-in config/gui_runtime.json or register that config via sdl3_app --set-default-json.
+`scripts/gui_demo.lua` paints the Lua GUI framework on top of the Vulkan scene. Launch it as `./build/sdl3_app --json-file-in config/gui_runtime.json` or register that config via `sdl3_app --set-default-json`.
diff --git a/scripts/dev_commands.py b/scripts/dev_commands.py
index fe9c695..8873e01 100644
--- a/scripts/dev_commands.py
+++ b/scripts/dev_commands.py
@@ -5,6 +5,7 @@ from __future__ import annotations
 import argparse
 import os
 import platform
+import shlex
 import subprocess
 
 
@@ -85,13 +86,16 @@ def msvc_quick(args: argparse.Namespace) -> None:
 
 def run_demo(args: argparse.Namespace) -> None:
     build_dir = args.build_dir or DEFAULT_BUILD_DIR
-    binary = os.path.join(
-        build_dir, "spinning_cube.exe" if IS_WINDOWS else "spinning_cube"
-    )
+    exe_name = args.target or ("sdl3_app.exe" if IS_WINDOWS else "sdl3_app")
+    binary = os.path.join(build_dir, exe_name)
+    cmd = binary
+    if args.args:
+        extra = " ".join(shlex.quote(arg) for arg in args.args)
+        cmd = f"{cmd} {extra}"
     if args.dry_run:
-        print("\n> " + binary)
+        print("\n> " + cmd)
     else:
-        subprocess.run(binary, shell=True, check=True)
+        subprocess.run(cmd, shell=True, check=True)
 
 
 def main() -> int:
@@ -155,6 +159,15 @@ def main() -> int:
         "--build-dir",
         help="where the binary lives (defaults to the Ninja folder from configure)",
     )
+    run_parser.add_argument(
+        "--target",
+        help="executable name to run (defaults to `sdl3_app`)",
+    )
+    run_parser.add_argument(
+        "--args",
+        nargs=argparse.REMAINDER,
+        help="arguments to forward to the executable (prefix with '--' before positional args when needed)",
+    )
     run_parser.set_defaults(func=run_demo)
 
     args = parser.parse_args()
