feat: layered profile/bundle model and profile-first init UX#490
Closed
HarryCampion wants to merge 25 commits into
Closed
feat: layered profile/bundle model and profile-first init UX#490HarryCampion wants to merge 25 commits into
HarryCampion wants to merge 25 commits into
Conversation
Implements the rhiza-cli side of the bundle/profile two-layer model introduced in rhiza#1028 (feat/bundle-profiles). Changes: - models/bundle.py: add ProfileDefinition dataclass; add profiles field to RhizaBundles with full from_config/config round-trip support - models/template.py: add profiles: list[str] field to RhizaTemplate (backward compatible — old files without profiles: load unchanged) - models/_profile_resolver.py: new resolve_bundles() function that expands profile names to bundle lists, merges explicit templates:, deduplicates preserving order, and raises ValueError for unknowns - models/__init__.py: export ProfileDefinition and resolve_bundles - commands/sync.py: thread resolve_bundles through _clone_template so profiles: in template.yml drive sparse checkout; lock records resolved effective bundle list; accepts profiles: as a valid config mode - commands/validate.py: accept profiles: as valid configuration mode; add _validate_profiles(); update error messages - commands/init.py: profile-first UX — fetch upstream profiles at init time, present numbered menu, write profiles: to template.yml; falls back to legacy templates: list when offline or no profiles in upstream - tests/test_models/test_profile_resolver.py: 26 new unit tests - tests/test_models/test_template_model.py: update for 4-tuple return from _clone_template and updated error message strings Tied to: Jebel-Quant/rhiza#1028
…, and profile init integration
… for advanced bundle picking)
…prompts - Add _RHIZA_STYLE (cyan #00BCD4) to all questionary calls in init.py - Replace typer.echo + typer.prompt repo selection with questionary.select - Replace raw input() in uninstall.py with questionary.confirm + _RHIZA_STYLE - Update uninstall tests to mock questionary.confirm instead of builtins.input - Remove now-unused typer import from init.py
…nce, shorter checkbox prompt
…description at 50 chars
Move the green colour to the 'checkbox' token so only the ●/○ marker is green. Reset 'selected' to dim grey so checked row text matches unchecked text. Set 'highlighted' to bold-only to prevent the terminal reverse-video block on hover.
Remove all row text styling — both checked and unchecked items use the same dim grey. The filled/hollow shape of the cyan ●/○ marker is the sole selection indicator. Pointer moves without any row highlighting.
…text highlighting - Set 'selected' to cyan so ● is filled+cyan when checked - Set 'highlighted' to noreverse to suppress terminal reverse-video on hover - Pass title as raw styled tuple list so questionary bypasses class:selected and class:highlighted for text entirely — row text is always dim grey regardless of checked or hover state - Pointer movement is the only positional indicator
Patch questionary list layouts so the terminal cursor is hidden for interactive list windows. This removes the square block drawn around the active bundle bullet, leaving the cyan pointer and filled vs hollow bullet markers as the only selection cues. Adds a regression test covering the patched list window behavior.
Questionary was emitting a SetCursorPosition token for the active row, which caused some terminals to draw a square cursor on the bundle bullet. Strip that token from list rows so the only changing controls are the cyan pointer and the hollow/filled bullet markers. Adds a regression test for the patched choice tokens and keeps the prompt-profile tests green.
tschm
approved these changes
May 3, 2026
Collaborator
Author
I'll come back to this |
Member
|
@HarryCampion let's discuss this. I think the functionality you are aiming for is now included. Maybe a candidate for closure? |
Collaborator
Author
Looks like it, I'll give it a go and close this. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the rhiza-cli side of the two-layer bundle/profile model. Depends on Jebel-Quant/rhiza#1028 being merged.
ProfileDefinition+RhizaBundles.profiles— parse and round-trip theprofiles:section oftemplate-bundles.ymlRhizaTemplate.profiles— newprofiles: list[str]field; oldtemplate.ymlfiles without it load unchangedresolve_bundles()— expands profile names → bundle lists, merges explicittemplates:, deduplicates in order, raisesValueErrorfor unknownssync— threadsresolve_bundlesthrough_clone_template; lock records resolved effective bundle list; acceptsprofiles:as valid configvalidate— acceptsprofiles:as a valid configuration mode; new_validate_profiles()checkinit— profile-first UX: fetches upstream profiles at init time, presents numbered menu, writesprofiles:totemplate.yml; falls back to legacytemplates:list when offlineTests
26 new unit tests in
tests/test_models/test_profile_resolver.pycovering:ProfileDefinitionandRhizaBundles.profilesparsing/round-trip/errorsRhizaTemplate.profilesfield serialisationresolve_bundles— expansion, deduplication, multi-profile, all error paths179 existing tests pass unchanged (4 updated for the
_clone_template4-tuple return and new error message wording).Tied to
Jebel-Quant/rhiza#1028 — bundle/profile schema in upstream
template-bundles.yml