gabriel / muse public
refactor BREAKING task/eliminate-prod-clones #2 / 2
AI Agent gabriel · 159 days ago · Apr 19, 2026 · Diff

refactor: eliminate 9 prod clone groups — extract to canonical homes

Identified via `muse code query "kind=function" --unique-bodies`.

Batch 1 — core/coordination clones (3 functions × 2 files = 6 definitions → 2 imports): _coord_dir, _now_utc, _parse_dt were copy-pasted into dag.py and task_queue.py. Both now import from coordination.py (the canonical source).

Batch 2 — _is_test_file + _TEST_PATTERNS (2 copies → 1 in _query.py): gravity.py and semantic_test_coverage.py both defined identical _TEST_PATTERNS and _is_test_file. Extracted to plugins/code/_query.py as is_test_file() (public). Both callers updated; unused `import re` removed from each.

Batch 3 — _normalise_language + _LANG_CANONICAL (4 copies → 1 in _query.py): compare.py, grep.py, hotspots.py, stable.py each built _LANG_CANONICAL from _SUFFIX_LANG (already in _query.py) and defined identical _normalise_language. Extracted to _query.py as normalise_language() (public). All 4 callers updated; _SUFFIX_LANG import removed from each.

Batch 4 — _use_color (2 copies → muse/core/terminal.py): conflicts.py and merge.py both defined the identical NO_COLOR-aware colour check. New muse/core/terminal.py provides use_color(). Both callers updated; unused os/sys imports removed from conflicts.py.

sha256:e72374ff5644e8edbe8baa0f85fa82d40f7041d4c9acfd747855a5bd105846b7 sha
+23 ~25 −28 symbols
sha256:412c5056eb51843c11992571dc854640454478f1748b63670d64ad2d40d89e7b snapshot
+23
symbols added
~25
symbols modified
−28
symbols removed
0
dead code introduced
Semantic Changes 76 symbols
~ muse/core/terminal.py .py 4 symbols added
+ annotations import import annotations L8–8
+ os import import os L10–10 ← moved from muse/cli/commands/conflicts.py
+ sys import import sys L11–11 ← moved from muse/cli/commands/conflicts.py
+ use_color function function use_color L14–22
~ muse/cli/commands/compare.py .py 1 symbol added, 3 symbols removed, 3 symbols modified
− _LANG_CANONICAL variable variable _LANG_CANONICAL L69–69
− _normalise_language function function _normalise_language L72–73
− _SUFFIX_LANG import import _SUFFIX_LANG L62–62
+ normalise_language import import normalise_language L62–62
~ run
~ muse/cli/commands/conflicts.py .py 1 symbol added, 3 symbols removed, 3 symbols modified
− _use_color function function _use_color L90–98
− os import import os L74–74 → moved to muse/core/terminal.py
− sys import import sys L75–75 → moved to muse/core/terminal.py
+ use_color import import use_color L79–79
~ _bold
~ _dim
~ muse/cli/commands/gravity.py .py 1 symbol added, 3 symbols removed, 3 symbols modified
− _TEST_PATTERNS variable variable _TEST_PATTERNS L159–165
− _is_test_file function function _is_test_file L265–267
− re import import re L122–122
+ is_test_file import import is_test_file L142–142
~ run
~ muse/cli/commands/grep.py .py 1 symbol added, 3 symbols removed, 3 symbols modified
− _LANG_CANONICAL variable variable _LANG_CANONICAL L79–79
− _normalise_language function function _normalise_language L82–83
− _SUFFIX_LANG import import _SUFFIX_LANG L56–56
+ normalise_language import import normalise_language L55–55
~ run
~ muse/cli/commands/hotspots.py .py 1 symbol added, 3 symbols removed, 4 symbols modified
− _LANG_CANONICAL variable variable _LANG_CANONICAL L76–76
− _normalise_language function function _normalise_language L79–80
− _SUFFIX_LANG import import _SUFFIX_LANG L70–70
+ normalise_language import import normalise_language L52–52
~ run
~ muse/cli/commands/merge.py .py 1 symbol added, 1 symbol removed, 1 symbol modified
− _use_color function function _use_color L165–173
+ use_color import import use_color L77–77
~ _c
~ muse/cli/commands/semantic_test_coverage.py .py 1 symbol added, 3 symbols removed, 3 symbols modified
− _TEST_PATTERNS variable variable _TEST_PATTERNS L178–184 → moved to muse/plugins/code/_query.py
− _is_test_file function function _is_test_file L253–255
− re import import re L139–139 → moved to muse/plugins/code/_query.py
+ is_test_file import import is_test_file L153–153
~ run
~ muse/cli/commands/stable.py .py 1 symbol added, 3 symbols removed, 5 symbols modified
− _LANG_CANONICAL variable variable _LANG_CANONICAL L70–70
− _normalise_language function function _normalise_language L79–80
− _SUFFIX_LANG import import _SUFFIX_LANG L49–49
+ normalise_language import import normalise_language L49–49
~ run
~ muse/core/dag.py .py 3 symbols added, 3 symbols removed
− _coord_dir function function _coord_dir L106–108
− _now_utc function function _now_utc L141–142
− _parse_dt function function _parse_dt L145–146
+ _coord_dir import import _coord_dir L77–77
+ _now_utc import import _now_utc L77–77
+ _parse_dt import import _parse_dt L77–77
~ muse/core/task_queue.py .py 3 symbols added, 3 symbols removed
− _coord_dir function function _coord_dir L146–148
− _now_utc function function _now_utc L205–206
− _parse_dt function function _parse_dt L209–210
+ _coord_dir import import _coord_dir L105–105
+ _now_utc import import _now_utc L105–105
+ _parse_dt import import _parse_dt L105–105
~ muse/plugins/code/_query.py .py 5 symbols added
+ _LANG_CANONICAL variable variable _LANG_CANONICAL L86–86
+ _TEST_PATTERNS variable variable _TEST_PATTERNS L102–108 ← moved from muse/cli/commands/semantic_test_coverage.py
+ re import import re L18–18 ← moved from muse/cli/commands/semantic_test_coverage.py
+ is_test_file function function is_test_file L111–113
+ normalise_language function function normalise_language L89–95

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:e72374ff5644e8edbe8baa0f85fa82d40f7041d4c9acfd747855a5bd105846b7 --body "your comment"