Skip to content

fix: invoke Python scripts with uv run, drop the Python browser opener - #30

Merged
bmadcode merged 1 commit into
mainfrom
uv-run-conversion
Aug 9, 2026
Merged

fix: invoke Python scripts with uv run, drop the Python browser opener#30
bmadcode merged 1 commit into
mainfrom
uv-run-conversion

Conversation

@bmadcode

@bmadcode bmadcode commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Two ways this module needed a system Python it should not have needed.

1. The customization resolver — 61 invocations

Every agent and workflow shelled out to a bare python3 to run _bmad/scripts/resolve_customization.py. That script declares requires-python = ">=3.11" and hard-exits below it, because tomllib is a 3.11 stdlib addition. On macOS without Homebrew or Ubuntu 22.04 — where python3 is 3.10 — activation fell through to the "if the script fails" path and hand-merged the TOML in-context, with no error surfaced.

uv run reads the script's own requires-python and provisions a matching interpreter instead.

Also gds-gdd/references/validation-render.mdrender-validation-html.py.

2. Browser openers — 4 sites

These spawned a Python interpreter purely to open an HTML file:

python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('PATH').resolve().as_uri())"

Replaced with the platform opener the rest of BMad already uses — open (macOS), xdg-open (Linux), start "" (Windows), path double-quoted.

These were the last place the module assumed a system Python at all, and they failed silently on a machine that has none — which is now a supported configuration, since uv provisions its own interpreter. Each site also gained an explicit failure instruction: hand the user the path rather than cycling through the other two openers.

Also

README badge corrected from >=3.10 to >=3.11 — it advertised a floor that cannot run the module.

Verification

npm test passes (lint, markdownlint, prettier). No bare python3 or python invocation remains anywhere in src/.

Part of an ecosystem-wide pass — the same fix is going into bmad-method, bmad-builder, creative-intelligence-suite, and test-architecture-enterprise.

Summary by CodeRabbit

  • Compatibility

    • Updated the documented minimum Python version to 3.11.
  • Improvements

    • Standardized workflow and agent command execution through the project’s environment runner for more consistent behavior.
    • Improved HTML report and preview opening across macOS, Linux, and Windows.
    • Added clearer fallback messaging with the generated report path when automatic opening fails.
    • Preserved headless-mode behavior and existing workflow fallbacks.

Two ways this module needed a system Python it should not have needed.

61 invocations shelled out to a bare `python3` to run
_bmad/scripts/resolve_customization.py, which declares
requires-python = ">=3.11" and hard-exits below it (tomllib is a 3.11
stdlib addition). On macOS without Homebrew or Ubuntu 22.04, python3 is
3.10. `uv run` reads the script's own metadata and provisions a matching
interpreter instead.

Four more spawned a Python interpreter purely to open an HTML file:

  python3 -c "import webbrowser, pathlib; webbrowser.open(...)"

Replaced with the platform opener the rest of BMad already uses — open /
xdg-open / start. These were the last place the module assumed a system
Python at all, and they failed silently on a machine that has none.

Also corrects the README badge, which advertised >=3.10 — a floor that
cannot run the module.
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The change updates the documented Python minimum to 3.11, changes resolver commands from python3 to uv run, and replaces Python browser launches with platform-specific opener commands.

Changes

Runtime command migration

Layer / File(s) Summary
Python requirement and resolver commands
README.md, src/agents/*, src/workflows/*
The README now requires Python 3.11 or newer. Resolver commands across agents and workflows now use uv run with the same scripts, arguments, and fallback behavior.
Platform-specific report opening
src/workflows/2-design/gds-prd/references/validate.md, src/workflows/2-design/gds-ux/{assets,references}/*
HTML reports now use open, xdg-open, or start with quoted paths. Failed opens report the file path, and headless behavior remains unchanged.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: sjennings

Poem

A rabbit sees uv take flight,
Resolvers hop through paths just right.
Reports open wide on every screen,
With quoted paths kept safe and clean.
Python three-eleven leads the way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: using uv run for Python scripts and replacing the Python browser opener.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch uv-run-conversion

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 5: Add project metadata enforcing Python >=3.11 and declaring the
required uv dependency, and update CI installation to install that dependency
alongside Node dependencies. Anchor the changes to the project’s top-level
package/configuration metadata and CI setup; alternatively remove the Python/uv
prerequisite badge if enforcement cannot be added.

In `@src/agents/gds-agent-tech-writer/SKILL.md`:
- Line 23: The resolver invocation must use a supported, isolated Python runtime
with declared metadata. Update _bmad/scripts/resolve_customization.py to provide
PEP 723 requires-python and dependency metadata, or document the required
uv/Python installation and prerequisites if inline metadata is not used; then
ensure each referenced command remains consistent in
src/agents/gds-agent-tech-writer/SKILL.md:23,
src/workflows/1-preproduction/gds-brainstorm-game/SKILL.md:25,
src/workflows/1-preproduction/gds-brainstorm-game/steps/step-04-complete.md:280,
src/workflows/1-preproduction/gds-create-game-brief/SKILL.md:18,
src/workflows/1-preproduction/research/gds-domain-research/SKILL.md:23,
src/workflows/4-production/gds-code-review/steps/step-04-present.md:130,
src/workflows/4-production/gds-correct-course/SKILL.md:23 and :312,
src/workflows/4-production/gds-create-story/SKILL.md:55 and :453,
src/workflows/4-production/gds-dev-story/SKILL.md:42 and :516,
src/workflows/4-production/gds-investigate/SKILL.md:55,
src/workflows/4-production/gds-retrospective/SKILL.md:66 and :1502, and
src/workflows/4-production/gds-sprint-planning/SKILL.md:46 and :258.

In `@src/workflows/2-design/gds-prd/references/validate.md`:
- Around line 43-49: Make all platform-specific commands complete and
unambiguous: in src/workflows/2-design/gds-prd/references/validate.md lines
43-49, show the macOS, Linux, and Windows open commands with the quoted
validation-report.html path; in
src/workflows/2-design/gds-ux/assets/color-themes.md line 9 and
src/workflows/2-design/gds-ux/references/creative-tools.md line 19, add the
quoted "PATH" argument to the Linux and Windows examples.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 133a46dd-3bdb-4b10-8db3-5b25a17050f7

📥 Commits

Reviewing files that changed from the base of the PR and between f51d400 and 9d75bb6.

📒 Files selected for processing (51)
  • README.md
  • src/agents/gds-agent-game-architect/SKILL.md
  • src/agents/gds-agent-game-designer/SKILL.md
  • src/agents/gds-agent-game-dev/SKILL.md
  • src/agents/gds-agent-game-solo-dev/SKILL.md
  • src/agents/gds-agent-tech-writer/SKILL.md
  • src/workflows/1-preproduction/gds-brainstorm-game/SKILL.md
  • src/workflows/1-preproduction/gds-brainstorm-game/steps/step-04-complete.md
  • src/workflows/1-preproduction/gds-create-game-brief/SKILL.md
  • src/workflows/1-preproduction/research/gds-domain-research/SKILL.md
  • src/workflows/1-preproduction/research/gds-domain-research/domain-steps/step-06-research-synthesis.md
  • src/workflows/2-design/gds-create-narrative/SKILL.md
  • src/workflows/2-design/gds-create-narrative/steps/step-11-complete.md
  • src/workflows/2-design/gds-gdd/SKILL.md
  • src/workflows/2-design/gds-gdd/references/validation-render.md
  • src/workflows/2-design/gds-prd/SKILL.md
  • src/workflows/2-design/gds-prd/references/validate.md
  • src/workflows/2-design/gds-ux/SKILL.md
  • src/workflows/2-design/gds-ux/assets/color-themes.md
  • src/workflows/2-design/gds-ux/references/creative-tools.md
  • src/workflows/2-design/gds-ux/references/validate.md
  • src/workflows/3-technical/gds-check-implementation-readiness/SKILL.md
  • src/workflows/3-technical/gds-check-implementation-readiness/steps/step-06-final-assessment.md
  • src/workflows/3-technical/gds-create-epics-and-stories/SKILL.md
  • src/workflows/3-technical/gds-create-epics-and-stories/steps/step-04-final-validation.md
  • src/workflows/3-technical/gds-game-architecture/SKILL.md
  • src/workflows/3-technical/gds-game-architecture/steps/step-09-complete.md
  • src/workflows/3-technical/gds-generate-project-context/SKILL.md
  • src/workflows/3-technical/gds-generate-project-context/steps/step-03-complete.md
  • src/workflows/4-production/gds-code-review/SKILL.md
  • src/workflows/4-production/gds-code-review/steps/step-04-present.md
  • src/workflows/4-production/gds-correct-course/SKILL.md
  • src/workflows/4-production/gds-create-story/SKILL.md
  • src/workflows/4-production/gds-dev-story/SKILL.md
  • src/workflows/4-production/gds-investigate/SKILL.md
  • src/workflows/4-production/gds-retrospective/SKILL.md
  • src/workflows/4-production/gds-sprint-planning/SKILL.md
  • src/workflows/4-production/gds-sprint-status/SKILL.md
  • src/workflows/gametest/gds-e2e-scaffold/SKILL.md
  • src/workflows/gametest/gds-performance-test/SKILL.md
  • src/workflows/gametest/gds-playtest-plan/SKILL.md
  • src/workflows/gametest/gds-test-automate/SKILL.md
  • src/workflows/gametest/gds-test-design/SKILL.md
  • src/workflows/gametest/gds-test-framework/SKILL.md
  • src/workflows/gametest/gds-test-review/SKILL.md
  • src/workflows/gds-document-project/SKILL.md
  • src/workflows/gds-document-project/instructions.md
  • src/workflows/gds-document-project/workflows/deep-dive-instructions.md
  • src/workflows/gds-document-project/workflows/full-scan-instructions.md
  • src/workflows/gds-quick-flow/gds-quick-dev/SKILL.md
  • src/workflows/gds-quick-flow/gds-quick-dev/step-05-present.md

Comment thread README.md
[![Version](https://img.shields.io/npm/v/bmad-game-dev-studio?color=blue&label=version)](https://www.npmjs.com/package/bmad-game-dev-studio)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python Version](https://img.shields.io/badge/python-%3E%3D3.10-blue?logo=python&logoColor=white)](https://www.python.org)
[![Python Version](https://img.shields.io/badge/python-%3E%3D3.11-blue?logo=python&logoColor=white)](https://www.python.org)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n --hidden \
  -g '!node_modules' -g '!dist' -g '!build' \
  -e 'requires-python|python_requires|3\.10|3\.11|uv run|install.*uv|uv.*install' .

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 12782


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'Tracked top-level files:\n'
git ls-files | sed 's#/.##' | sort | sed -n '1,200p'

printf '\nFiles named pyproject, setup, uv-related:\n'
git ls-files | rg '(^|/)(pyproject\.toml|setup\.py|setup\.cfg|uv\.lock|requirements|noxfile|tox|\.pre-commit|README\.md|Dockerfile|ci|\.github/.*)$|^uv\.lock$|^\./pyproject\.toml$|^\./setup\.py$' || true

printf '\nRelevant declaration/install command scans:\n'
rg -n --hidden \
  -g '!node_modules' -g '!dist' -g '!build' \
  -e 'python_requires|requires-python|python =|python version|python_version|requires|dev-dependencies|dependencies|pyodide|uv|uvx|python -m pip|pip install|install|Python Version' \
  pyproject.toml setup.py setup.cfg uv.lock .github README.md 2>/dev/null || true

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 12380


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'README top 90 lines:\n'
sed -n '1,90p' README.md | nl -ba

printf '\nQualiy workflow Python/uv/package.json sections:\n'
sed -n '1,120p' .github/workflows/quality.yaml | nl -ba

printf '\nDocs workflow setup/Python/uv sections:\n'
sed -n '1,120p' .github/workflows/docs.yaml | nl -ba

printf '\nRelease workflow setup/uv sections:\n'
sed -n '1,130p' .github/workflows/release.yaml | nl -ba

printf '\npackage.json Python/uv references:\n'
rg -n '"python"|"uv"|uv|python' package.json .github README.md docs src -g '*.json' -g '*.md' -g '*.js' -g '*.mjs' -g '*.py' || true

printf '\nREADME install/setup section around BMad install:\n'
rg -n -C 4 'BMad|Bmad|bmad-method|setup|install|Prerequisites|requirements|Python|uv' README.md docs/how-to -g '*.md' || true

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 240


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
for p in ["README.md", ".github/workflows/quality.yaml", ".github/workflows/docs.yaml", ".github/workflows/release.yaml", "package.json"]:
    path = Path(p)
    print(f"\n=== {p} ({path.expanduser().resolve()}) exists={path.exists()} ===")
    if not path.exists():
        continue
    lines = path.read_text().splitlines()
    for start, end in [(1, 130) if "workflow" in str(p) or "README" in str(p) else (1, 90)]:
        if start > len(lines):
            break
        for i in range(max(1, start), min(len(lines), end)+1):
            line = lines[i-1]
            if any(ss in line for ss in ["setenv", "node-version", "npm install", "uv", "uv_run", "pip", "python", "Python", "package.json"]):
                s = "L{:>4}: {}".format(i, line)
                if s not in printed:
                    print(s)

print("\n=== package.json relevant keys ===")
p = Path("package.json")
if p.exists():
    import json
    data = json.loads(p.read_text())
    for k in ["scripts", "devDependencies", "dependencies", "packageManager", "engines", "node"] or []:
        print(f"{k}: ", data.get(k))
PY

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 356


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'README.md lines 1-110:\n'
python3 - <<'PY'
from pathlib import Path
for i, line in enumerate(Path('README.md').read_text().splitlines()[:110], 1):
    if any(s in line for s in ['![Python Version', '![uv', 'BMGD is installed', 'npx bmad-method', 'Prerequisites', 'requirements', 'installation', 'install', 'uv']) or i <= 10:
        print(f"{i}: {line}")
PY

printf '\n.github workflow relevant lines:\n'
for f in .github/workflows/*.yaml; do
  printf '\n--- %s ---\n' "$f"
  python3 - "$f" "$@" <<'PY' "$1"
import sys
from pathlib import Path
p = Path(sys.argv[1])
for i, line in enumerate(p.read_text().splitlines(), 1):
    if any(s in line for s in ['setup-node', 'node-version', 'npm install', 'npx', 'uv', 'uv_run', 'python', 'Python', 'setenv', 'package.json']):
        print(f"{i}: {line}")
PY
done

printf '\npackage.json relevant sections:\n'
python3 - <<'PY'
import json
from pathlib import Path
data=json.loads(Path('package.json').read_text())
for k in sorted(data):
    if k in {'scripts','devDependencies','dependencies','packageManager','engines','contributors'}:
        print(f"\n[{k}]")
        v=data[k]
        if isinstance(v, dict):
            for kk,vv in v.items():
                if any(x in str(vv).lower() for x in ('python','uv','bmad','install')):
                    print(kk, ':', vv)
        else:
            print(v)
PY

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 1487


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'README.md lines 1-110:\n'
python3 - <<'PY'
from pathlib import Path
for i, line in enumerate(Path('README.md').read_text().splitlines()[:110], 1):
    if i <= 10 or any(s in line for s in ['![Python Version', '![uv', 'BMGD is installed', 'npx bmad-method', 'Prerequisites', 'requirements', 'installation', 'install', 'uv', 'Python']):
        print(f"{i}: {line}")
PY

printf '\nGitHub workflow relevant lines:\n'
for f in .github/workflows/*.yaml; do
  printf '\n--- %s ---\n' "$f"
  python3 - "$f" <<'PY'
import sys
from pathlib import Path
p = Path(sys.argv[1])
for i, line in enumerate(p.read_text().splitlines(),1):
    if any(s in line for s in ['setup-node', 'node-version', 'npm install', 'npx@', 'uv', 'python', 'Python', 'setenv', 'package.json', 'node_modules']):
        print(f"{i}: {line}")
PY
done

printf '\npackage.json relevant sections:\n'
python3 - <<'PY'
import json
from pathlib import Path
data = json.loads(Path('package.json').read_text())
for k, v in data.items():
    if k in {'scripts', 'devDependencies', 'dependencies', 'packageManager', 'engines'}:
        print(f"\n[{k}]")
        if isinstance(v, dict):
            for kk, vv in v.items():
                print(f"{kk}: {vv}")
        else:
            print({k: v})
PY

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 3592


Add Python/uv enforcement metadata to match the README prerequisites.

README now documents Python >=3.11 and uv, but there is no top-level requires-python / package metadata and the CI installs only Node dependencies. Add an install/dependency declaration for uv and Python guard metadata, or remove one prerequisite badge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 5, Add project metadata enforcing Python >=3.11 and
declaring the required uv dependency, and update CI installation to install that
dependency alongside Node dependencies. Anchor the changes to the project’s
top-level package/configuration metadata and CI setup; alternatively remove the
Python/uv prerequisite badge if enforcement cannot be added.

### Step 1: Resolve the Agent Block

Run: `python3 {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`
Run: `uv run {project-root}/_bmad/scripts/resolve_customization.py --skill {skill-root} --key agent`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

command -v uv
uv --version

resolver="_bmad/scripts/resolve_customization.py"
test -f "$resolver"

sed -n '1,100p' "$resolver"
rg -n -i '\buv\b|python 3\.11|python >=?3\.11' README.md
rg -n -P '\buv run\b.*resolve_customization\.py' src

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 179


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'Repository files around resolver:\n'
git ls-files | rg '(^|/)((README\.md|pyproject\.toml|uv\.lock|_bmad/scripts/resolve_customization\.py)|SKILL\.md$|steps/)$.|(^|/)SKILL\.md$|(^|/)steps/.*\.md$|(^|/)README\.md$|(^|/)pyproject\.toml$|(^|/)uv\.lock$' || true

printf '\nIf resolver exists, first 120 lines:\n'
if [ -f _bmad/scripts/resolve_customization.py ]; then
  sed -n '1,120p' _bmad/scripts/resolve_customization.py
fi

printf '\nuv documentation mentions in repo:\n'
rg -n -i '\buv\b|python 3\.11|python >=?3\.11' README.md pyproject.toml 2>/dev/null || true

printf '\nTarget command occurrences:\n'
rg -n -P 'uv run \{project-root\}/_bmad/scripts/resolve_customization\.py --skill \{skill-root\} --key (agent|workflow(\.on_complete)?)' src || true

Repository: bmad-code-org/bmad-module-game-dev-studio

Length of output: 17604


🌐 Web query:

uv documentation inline script metadata project script environment uv run script with no pyproject.toml

💡 Result:

Use uv run with PEP 723 inline script metadata (or --no-project if you’re in a uv project); you do not need a pyproject.toml. 1) Script with inline metadata (recommended) - Put a PEP 723 # /// script block in the.py file, declaring dependencies and optionally requires-python [1]. - Then run: uv run path/to/script.py - uv run will detect the inline metadata and install dependencies into an isolated, ephemeral environment for that script [2][3]. Example (PEP 723 inline metadata): # /// script # dependencies = ["rich"] # requires-python = ">=3.12" # /// from rich import print print("hello") Run: uv run script.py 2) If there is no inline metadata and you’re inside a directory with a pyproject.toml - By default, if uv run is used in a project (a directory containing pyproject.toml), uv installs the current project before running the script [4][5]. - To avoid that when your script does not depend on the project, use --no-project before the script name: uv run --no-project script.py 3) Notes about environment/behavior - When inline metadata is present, uv runs the script with an environment isolated from the project and uses only the dependencies declared in the script’s metadata [4][5][3]. - uv creates dedicated virtual environments for scripts with inline metadata in its cache [6]. If you tell me whether your script includes PEP 723 inline metadata (and show the header), I can give the exact minimal command for your case.

Citations:


🌐 Web query:

resolving uv requirement using existing python environment does not install virtual environment

💡 Result:

By design, uv requires a virtual environment for operations that mutate the environment, such as uv pip install or uv pip sync, to avoid modifying the base Python installation [1][2]. If you attempt these commands without a virtual environment, uv will prompt you to create one [1][2]. To install packages into an existing, non-virtual environment, you have two primary options: 1. Use the --system flag: This instructs uv to target the system-level Python interpreter [3][4][5]. uv pip install --system <package_name> Note: This should be used with caution, as it will modify the global Python installation [3][4][6]. On many modern Linux distributions that follow PEP 668 (externally managed environments), this command may fail with an error indicating that the interpreter is externally managed, as uv will refuse to modify those system-protected environments [7][4][8]. 2. Use the --python flag: This allows you to target any specific Python interpreter path, regardless of whether it is a virtual environment or a base Python installation [1][2][5]. uv pip install --python /path/to/python <package_name> If your goal is to have a globally available command-line tool without modifying the system Python, it is recommended to use uv tool install <package_name> instead [4]. This manages the package in an isolated, user-level environment [4].

Citations:


🌐 Web query:

site:docs.astral.sh/uv/reference/cli uv run --no-project inline script pyproject.toml

💡 Result:

The combination of arguments uv run --no-project, inline script execution, and pyproject.toml is not a standard usage pattern because these features serve different purposes within the uv toolchain. 1. Inline Script Execution: uv supports running Python scripts that contain inline dependency metadata (specified in a PEP 723 format) [1][2]. When you run a script, uv automatically manages an isolated, ephemeral environment for those dependencies [1][2]. 2. --no-project: The --no-project flag tells uv to ignore any project configuration (like a pyproject.toml) found in the current directory or parent directories [1][2]. This is used when you want to ensure that uv does not attempt to resolve or use an existing project environment [1][2]. 3. pyproject.toml: This file is typically used to define a project's dependencies and configuration [1][2]. When using --no-project, uv explicitly disables the use of these files [2]. If you are trying to use an inline script, you do not need to provide a pyproject.toml file, as the dependencies are defined inside the Python file itself [1][2]. If you use the --no-project flag, uv will prevent the discovery and use of any pyproject.toml file in your environment [1][2]. Therefore, providing a pyproject.toml file while simultaneously using --no-project is contradictory or simply ignored depending on the specific command context. To run a script with inline metadata, you simply use: uv run your_script.py If you wish to force isolation from any existing project in the directory, you can use: uv run --no-project your_script.py

Citations:


🌐 Web query:

docs.astral.sh uv scripts PEP 723 uv run inline script pyproject dependencies

💡 Result:

uv provides full support for PEP 723 inline script metadata, enabling the creation of self-contained, reproducible Python scripts that manage their own dependencies [1][2][3]. Key features and workflows include: Declaring Dependencies: Scripts can define dependencies and Python version requirements within a TOML block delimited by # /// script and # /// at the top of the file [4][5]. Example: # /// script # requires-python = ">=3.11" # dependencies = ["requests"] # /// Managing Metadata: - Initialize scripts: Use uv init --script to create a new script with template metadata [1][3]. - Manage dependencies: Use uv add --script <script.py> to automatically add dependencies to the script's inline metadata [1][2]. Execution: - Running scripts: Use uv run <script.py>. uv detects the PEP 723 metadata, creates an ephemeral, isolated virtual environment, installs the specified dependencies, and executes the script [1][3][5]. - Isolation: When using inline script metadata, uv runs the script in an isolated environment, ignoring any project-level dependencies (such as those in a local pyproject.toml), even if the script is executed within a project directory [1][6][7]. - Locking: uv supports locking PEP 723 scripts using a uv.lock file [1][7]. Scripts must be explicitly locked using uv lock, after which subsequent runs and tool usage will respect the locked dependencies [1][7]. - Shebang support: For direct execution (e.g.,./script.py), you can add the following shebang to the first line of your script [3]: #!/usr/bin/env -S uv run --script For further details, refer to the official uv documentation on running scripts [1].

Citations:


🌐 Web query:

site:docs.astral.sh/uv/references/python uv run script metadata requires-python missing Python installation

💡 Result:

uv run script.py can run a standalone script with PEP 723 inline metadata:

# /// script
# requires-python = ">=3.12"
# dependencies = ["requests"]
# ///

Then:

uv run script.py

uv reads requires-python, selects a compatible interpreter, creates/manages the script environment, and installs dependencies. If no compatible Python is installed, uv can download one automatically; alternatively install it explicitly:

uv python install 3.12
uv run --python 3.12 script.py

If the metadata is missing, uv generally uses its default Python selection rather than a script-specific requirement. Use uv add --script script.py package to add PEP 723 metadata automatically. (docs.astral.sh)

Citations:


🌐 Web query:

uv run script.py --no-project inline script pyproject.toml exists project environment

💡 Result:

When you run a script using uv, the presence of a pyproject.toml file and the use of the --no-project flag significantly alter how uv manages the execution environment [1][2][3][4]. If you are running a script with PEP 723 inline script metadata, uv automatically treats it as a standalone script [3][4]. In this case, uv ignores the project context entirely, even if a pyproject.toml file exists in the directory [1][2][4]. The script is executed in an isolated environment built specifically for the dependencies declared in its metadata, and you do not need to provide the --no-project flag [1][2][4]. If you are running a standard script (without inline metadata) within a directory that contains a pyproject.toml file, the following behaviors apply: 1. Standard Behavior: By default, uv detects the pyproject.toml, treats the directory as a project, and installs the project and its dependencies before running the script [1][2][3]. The script has access to those project dependencies [1][2]. 2. Using --no-project: The --no-project flag explicitly tells uv to skip project discovery and project environment management [1][2]. In this mode, uv will not install the project, and the project's dependencies will not be automatically included [1][2]. However, note that --no-project only disables project discovery; it does not disable general Python environment discovery (such as an existing.venv folder in the directory) [5]. If you require a truly clean, isolated environment, consider using the --isolated flag alongside --no-project [6][5]. If your pyproject.toml file is incomplete (e.g., missing a [project] table), uv may throw an error unless you use --no-project or use the --script flag to force inline-metadata mode [7][6][8].

Citations:


Ensure the resolver script has the supported runtime metadata.

These commands expose every workflow agent to uv plus the resolver script’s Python and dependency metadata. If _bmad/scripts/resolve_customization.py uses PEP 723 inline metadata, document uv / Python installation options in the prerequisites or add the required requires-python / dependencies. If it does not use inline metadata, uv run in the presence of this repo’s uv.lock may resolve against project-environment behavior instead of an isolated resolver environment.

📍 Affects 12 files
  • src/agents/gds-agent-tech-writer/SKILL.md#L23-L23 (this comment)
  • src/workflows/1-preproduction/gds-brainstorm-game/SKILL.md#L25-L25
  • src/workflows/1-preproduction/gds-brainstorm-game/steps/step-04-complete.md#L280-L280
  • src/workflows/1-preproduction/gds-create-game-brief/SKILL.md#L18-L18
  • src/workflows/1-preproduction/research/gds-domain-research/SKILL.md#L23-L23
  • src/workflows/4-production/gds-code-review/steps/step-04-present.md#L130-L130
  • src/workflows/4-production/gds-correct-course/SKILL.md#L23-L23
  • src/workflows/4-production/gds-correct-course/SKILL.md#L312-L312
  • src/workflows/4-production/gds-create-story/SKILL.md#L55-L55
  • src/workflows/4-production/gds-create-story/SKILL.md#L453-L453
  • src/workflows/4-production/gds-dev-story/SKILL.md#L42-L42
  • src/workflows/4-production/gds-dev-story/SKILL.md#L516-L516
  • src/workflows/4-production/gds-investigate/SKILL.md#L55-L55
  • src/workflows/4-production/gds-retrospective/SKILL.md#L66-L66
  • src/workflows/4-production/gds-retrospective/SKILL.md#L1502-L1502
  • src/workflows/4-production/gds-sprint-planning/SKILL.md#L46-L46
  • src/workflows/4-production/gds-sprint-planning/SKILL.md#L258-L258
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/agents/gds-agent-tech-writer/SKILL.md` at line 23, The resolver
invocation must use a supported, isolated Python runtime with declared metadata.
Update _bmad/scripts/resolve_customization.py to provide PEP 723 requires-python
and dependency metadata, or document the required uv/Python installation and
prerequisites if inline metadata is not used; then ensure each referenced
command remains consistent in src/agents/gds-agent-tech-writer/SKILL.md:23,
src/workflows/1-preproduction/gds-brainstorm-game/SKILL.md:25,
src/workflows/1-preproduction/gds-brainstorm-game/steps/step-04-complete.md:280,
src/workflows/1-preproduction/gds-create-game-brief/SKILL.md:18,
src/workflows/1-preproduction/research/gds-domain-research/SKILL.md:23,
src/workflows/4-production/gds-code-review/steps/step-04-present.md:130,
src/workflows/4-production/gds-correct-course/SKILL.md:23 and :312,
src/workflows/4-production/gds-create-story/SKILL.md:55 and :453,
src/workflows/4-production/gds-dev-story/SKILL.md:42 and :516,
src/workflows/4-production/gds-investigate/SKILL.md:55,
src/workflows/4-production/gds-retrospective/SKILL.md:66 and :1502, and
src/workflows/4-production/gds-sprint-planning/SKILL.md:46 and :258.

Comment on lines +43 to +49
For interactive runs, open the HTML with the platform opener — `open` on macOS, `xdg-open` on Linux, `start ""` on Windows — double-quoting the path:

```bash
python3 -c "import webbrowser, pathlib; webbrowser.open(pathlib.Path('{doc_workspace}/validation-report.html').resolve().as_uri())"
open "{doc_workspace}/validation-report.html"
```

Skip the open step in headless mode (see `references/headless.md`). Re-running validation overwrites the report in place.
If the command fails, don't retry with another opener: tell the user the file path and move on. Skip the open step in headless mode (see `references/headless.md`). Re-running validation overwrites the report in place.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make every platform command complete and unambiguous.

These instructions list platform-specific openers but do not provide a complete command for every platform.

  • src/workflows/2-design/gds-prd/references/validate.md#L43-L49: show open "{doc_workspace}/validation-report.html", xdg-open "{doc_workspace}/validation-report.html", and start "" "{doc_workspace}/validation-report.html".
  • src/workflows/2-design/gds-ux/assets/color-themes.md#L9-L9: add "PATH" to the Linux and Windows examples.
  • src/workflows/2-design/gds-ux/references/creative-tools.md#L19-L19: add "PATH" to the Linux and Windows examples.
📍 Affects 3 files
  • src/workflows/2-design/gds-prd/references/validate.md#L43-L49 (this comment)
  • src/workflows/2-design/gds-ux/assets/color-themes.md#L9-L9
  • src/workflows/2-design/gds-ux/references/creative-tools.md#L19-L19
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workflows/2-design/gds-prd/references/validate.md` around lines 43 - 49,
Make all platform-specific commands complete and unambiguous: in
src/workflows/2-design/gds-prd/references/validate.md lines 43-49, show the
macOS, Linux, and Windows open commands with the quoted validation-report.html
path; in src/workflows/2-design/gds-ux/assets/color-themes.md line 9 and
src/workflows/2-design/gds-ux/references/creative-tools.md line 19, add the
quoted "PATH" argument to the Linux and Windows examples.

@bmadcode
bmadcode merged commit ac99cb8 into main Aug 9, 2026
52 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant