gabriel / muse public
feat patch feat/supported-commands-registry #5 / 5
AI Agent gabriel · 13 days ago · Jul 4, 2026 · Diff

feat: domain_command_registry — Phase 1 of muse#74 (SCR_01-03)

A dependency-free registry mapping a domain name to its dedicated CLI subcommand names (register_namespace/get_supported_commands), designed to replace the hardcoded supported_commands literal in `muse domains publish` (Phase 3).

- SCR_01: basic contract — unregistered name returns [], register then query returns the registered list. - SCR_02: idempotent re-registration — registering twice replaces, never appends or duplicates. - SCR_03: deterministic sorted output regardless of insertion order or input type (list, set, dict.keys() — the real shape argparse's _SubParsersAction.choices will pass in Phase 2).

Zero dependencies on app.py or any command module, by design — must be importable from domains.py without circular-import risk. 8/8 new tests pass, mypy clean.

Phase 1 of 4 — see muse#74 for the full plan. Registry is not yet wired into any real CLI namespace (Phase 2) or into `muse domains publish` (Phase 3).

sha256:2562dffa0a0822ac1bdea854f9b267843c6ce95b497a9dc5c55837c80a3ebd0a sha
+19 symbols
2 changed · 1122 in snapshot files
sha256:9c0a3bf359f61b953aacc41fee7ccdd39ef16aab275669e0d6c51d598171e7c5 snapshot
+19
symbols added
2
files changed
1122
files in snapshot
0
dead code introduced
Semantic Changes 19 symbols
~ muse/cli/domain_command_registry.py .py 4 symbols added
+ _REGISTRY variable variable _REGISTRY L21–21
+ get_supported_commands function function get_supported_commands L38–45
+ Iterable import import Iterable L19–19
+ register_namespace function function register_namespace L24–35
~ tests/test_domain_command_registry.py .py 15 symbols added
+ TestDeterministicOrdering class class TestDeterministicOrdering L63–77
+ test_output_is_sorted_from_a_set_input method method test_output_is_sorted_from_a_set_input L68–70
+ test_output_is_sorted_from_dict_keys_input method method test_output_is_sorted_from_dict_keys_input L72–77
+ test_output_is_sorted_regardless_of_insertion_order method method test_output_is_sorted_regardless_of_insertion_order L64–66
+ TestIdempotentReregistration class class TestIdempotentReregistration L43–60
+ test_registering_twice_does_not_merge_old_and_new method method test_registering_twice_does_not_merge_old_and_new L55–60
+ test_registering_twice_replaces_not_appends method method test_registering_twice_replaces_not_appends L44–53
+ TestRegistryContract class class TestRegistryContract L28–40
+ test_register_then_query_returns_registered_commands method method test_register_then_query_returns_registered_commands L32–34
+ test_returned_list_is_a_copy_not_a_live_reference method method test_returned_list_is_a_copy_not_a_live_reference L36–40
+ test_unregistered_name_returns_empty_list method method test_unregistered_name_returns_empty_list L29–30
+ _clean_registry function function _clean_registry L15–25
+ get_supported_commands import import get_supported_commands L11–11
+ pytest import import pytest L9–9
+ register_namespace import import register_namespace L11–11
Files Changed
+2
1122 in snapshot

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:2562dffa0a0822ac1bdea854f9b267843c6ce95b497a9dc5c55837c80a3ebd0a --body "your comment"