Vendor blank, coding, and cua presets into the hud wheel - #515
Conversation
hud init copies these starters from files packaged with the SDK instead of downloading GitHub tarballs, so the scaffold always matches the installed version and works offline. The trees stay authored under environments/; the wheel force-includes them at hud/cli/starters/, and a source checkout falls back to environments/ directly. The blank preset becomes a real template directory like its siblings, replacing the inline string scaffold in hud/cli/templates.py; the scaffold no longer substitutes the target name into env.py/pyproject. Remaining presets keep the tarball path.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3062e00c67
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "hud/**", | ||
| "/environments/blank/**", | ||
| "/environments/coding/**", | ||
| "/environments/cua/**", |
There was a problem hiding this comment.
Include starter lockfiles in the published wheel
When the package is released through .github/workflows/release.yml's uv build, the wheel is built from the sdist; reproducing that command reports “Building source distribution...” followed by “Building wheel from source distribution...”. Although this glob retains the CUA tree, both starter uv.lock files are absent from the resulting sdist and wheel. Consequently, hud init --preset cua from PyPI produces a tree whose Dockerfile.hud requires COPY ./pyproject.toml ./uv.lock ./env.py ./tasks.py /mcp_server/, so every documented Docker/deploy build fails immediately because uv.lock does not exist. Ensure the lockfiles are explicitly retained in the sdist and resulting wheel.
Useful? React with 👍 / 👎.
| from hud.environment import Environment | ||
|
|
||
| env = Environment(name="{env_name}") | ||
| env = Environment(name="blank") |
There was a problem hiding this comment.
Preserve the requested name in blank scaffolds
When hud init my-env or hud init my-env --preset blank copies this template, it now writes the literal blank instead of deriving the environment name from the requested target as the previous scaffold did. hud deploy treats the declared Environment name as the platform identity and uses get-or-rebuild semantics, so independently named blank projects all deploy as blank and later deployments can rebuild the same registry rather than create the intended environments. Restore target-name substitution for the blank scaffold and its project metadata.
AGENTS.md reference: AGENTS.md:L76-L78
Useful? React with 👍 / 👎.
Stacked on #512.
hud initnow copies the blank, coding, and cua starters from files packaged with the SDK instead of downloading GitHub tarballs — the scaffold a user gets always matches the SDK version they installed, and init works offline for these presets. The remaining presets keep the tarball path.How
environments/<id>/. The wheel force-includes them athud/cli/starters/<id>;presets.pyresolves the packaged path first and falls back to the repo-relativeenvironments/<id>souv run hud initworks from a source checkout. Missing both raisesFileNotFoundErrorloudly.environments/in site-packages, executable bits survive (run_script.shstays 755), gitignored junk stays out; the source-checkout copy path additionally skips.venv/__pycache__/cache dirs.hud/cli/templates.pystring constants) is replaced by a realenvironments/blank/template;templates.pyis deleted andinit.pyhas a single materialization path.Behavior notes
hud init NAME --preset blankno longer substitutesNAMEintoenv.py/pyproject.toml— the scaffold is a verbatim copy (Environment(name="blank"), packageblank-env), consistent with every other preset.--preset codingoutput is byte-identical toenvironments/coding; blank and cua scaffold cleanly.Checks
pytest749 passed (full suite), cli suite 160 passed including new preset materialization tests (vendored copy, exec bits, junk-dir skip, loud missing-tree failure, tarball path + path-traversal guard). ruff format/check clean. pyright: 4 pre-existing errors in untouched test files, none introduced.HUD-2276
Note
Low Risk
Changes are confined to CLI scaffolding, packaging, and docs; no auth, runtime eval, or grading paths. The blank preset naming change is a minor UX shift for users who relied on directory-name substitution.
Overview
hud initnow copiesblank,coding, andcuafrom starter trees shipped inside the installedhudpackage instead of generating inline strings or downloading GitHub tarballs for those presets. Other presets still use the tarball path. Starters are authored atenvironments/<id>/, force-included into the wheel ashud/cli/starters/<id>, with a repo-checkout fallback toenvironments/souv run hud initworks without a build.The inline blank scaffold (
hud/cli/templates.py) is removed;initalways goes throughmaterialize_preset, which copies vendored trees (skipping.venv/__pycache__, preserving executable bits) or downloads remote archives as before.Behavior change:
hud init NAME --preset blankno longer substitutesNAMEintoenv.py/pyproject.toml—the scaffold is a verbatim copy (Environment(name="blank"), packageblank-env), like other presets.Docs and
.gitignoreare updated to describe bundled vs downloaded presets and to trackenvironments/blank/in git.Reviewed by Cursor Bugbot for commit 3062e00. Bugbot is set up for automated code reviews on this repo. Configure here.