gabriel / muse public
feat patch worktree dev
AI Agent gabriel · 159 days ago · Apr 19, 2026 · Diff

feat(worktree): supercharge JSON output — exit_code, duration_ms, list envelope

All six worktree subcommands now emit exit_code and duration_ms in every --json response. muse worktree list switches from a bare array to a {worktrees, exit_code, duration_ms} envelope (same pattern as workspace).

New TypedDicts: _WorktreeListJson, _WorktreeStatusJson, _WorktreeRepairJson. Updated: _WorktreeAddJson, _WorktreeRemoveJson, _WorktreePruneJson.

All six handler docstrings document the new fields.

tests/test_worktree_supercharge.py: 51 new tests across 6 classes — TestDurationMs, TestExitCode, TestListEnvelope, TestTypedDicts, TestDocstrings, TestPerformance.

tests/test_cmd_worktree_hardening.py: updated 37 tests to handle the envelope shape — _parse_list unwraps worktrees array, j-alias comparisons pop duration_ms before equality, key-set assertions include exit_code and duration_ms, raw list access updated to raw["worktrees"].

sha256:03e1516d1c56d368f245ecaad9cb3a056ff8058c9dabdbacf84d165fba8415b9 sha
+82 ~30 symbols
sha256:7f9fa578ee801c51bc807e329b6ed43a344ffb6d1ec3239e270836e5c9785581 snapshot
+82
symbols added
~30
symbols modified
0
dead code introduced
Semantic Changes 112 symbols
~ tests/test_worktree_supercharge.py .py 78 symbols added
+ TestDocstrings class class TestDocstrings L308–344
+ test_add_docstring_mentions_duration_ms method method test_add_docstring_mentions_duration_ms L313–314
+ test_add_docstring_mentions_exit_code method method test_add_docstring_mentions_exit_code L310–311
+ test_list_docstring_mentions_duration_ms method method test_list_docstring_mentions_duration_ms L319–320
+ test_list_docstring_mentions_exit_code method method test_list_docstring_mentions_exit_code L316–317
+ test_prune_docstring_mentions_duration_ms method method test_prune_docstring_mentions_duration_ms L337–338
+ test_prune_docstring_mentions_exit_code method method test_prune_docstring_mentions_exit_code L334–335
+ test_remove_docstring_mentions_duration_ms method method test_remove_docstring_mentions_duration_ms L331–332
+ test_remove_docstring_mentions_exit_code method method test_remove_docstring_mentions_exit_code L328–329
+ test_repair_docstring_mentions_duration_ms method method test_repair_docstring_mentions_duration_ms L343–344
+ test_repair_docstring_mentions_exit_code method method test_repair_docstring_mentions_exit_code L340–341
+ test_status_docstring_mentions_duration_ms method method test_status_docstring_mentions_duration_ms L325–326
+ test_status_docstring_mentions_exit_code method method test_status_docstring_mentions_exit_code L322–323
+ TestDurationMs class class TestDurationMs L72–121
+ test_add_json_has_duration_ms method method test_add_json_has_duration_ms L74–78
+ test_duration_ms_is_non_negative method method test_duration_ms_is_non_negative L117–121
+ test_duration_ms_is_numeric method method test_duration_ms_is_numeric L111–115
+ test_list_json_has_duration_ms method method test_list_json_has_duration_ms L80–84
+ test_prune_json_has_duration_ms method method test_prune_json_has_duration_ms L99–103
+ test_remove_json_has_duration_ms method method test_remove_json_has_duration_ms L92–97
+ test_repair_json_has_duration_ms method method test_repair_json_has_duration_ms L105–109
+ test_status_json_has_duration_ms method method test_status_json_has_duration_ms L86–90
+ TestExitCode class class TestExitCode L129–193
+ test_add_exit_code_zero_on_success method method test_add_exit_code_zero_on_success L168–171
+ test_add_json_has_exit_code method method test_add_json_has_exit_code L131–135
+ test_exit_code_is_int method method test_exit_code_is_int L183–186
+ test_exit_code_mirrors_process_exit method method test_exit_code_mirrors_process_exit L188–193
+ test_list_exit_code_zero method method test_list_exit_code_zero L173–176
+ test_list_json_has_exit_code method method test_list_json_has_exit_code L137–141
+ test_prune_exit_code_zero_nothing_to_prune method method test_prune_exit_code_zero_nothing_to_prune L178–181
+ test_prune_json_has_exit_code method method test_prune_json_has_exit_code L156–160
+ test_remove_json_has_exit_code method method test_remove_json_has_exit_code L149–154
+ test_repair_json_has_exit_code method method test_repair_json_has_exit_code L162–166
+ test_status_json_has_exit_code method method test_status_json_has_exit_code L143–147
+ TestListEnvelope class class TestListEnvelope L201–249
+ test_list_j_alias_envelope method method test_list_j_alias_envelope L242–249
+ test_list_json_count_after_add method method test_list_json_count_after_add L234–240
+ test_list_json_entry_fields_intact method method test_list_json_entry_fields_intact L227–232
+ test_list_json_has_worktrees_key method method test_list_json_has_worktrees_key L209–213
+ test_list_json_includes_main_in_worktrees method method test_list_json_includes_main_in_worktrees L221–225
+ test_list_json_is_dict_not_array method method test_list_json_is_dict_not_array L203–207
+ test_list_json_worktrees_is_array method method test_list_json_worktrees_is_array L215–219
+ TestPerformance class class TestPerformance L352–370
+ test_add_duration_ms_under_1000 method method test_add_duration_ms_under_1000 L360–364
+ test_list_duration_ms_under_1000 method method test_list_duration_ms_under_1000 L354–358
+ test_prune_duration_ms_under_1000 method method test_prune_duration_ms_under_1000 L366–370
+ TestTypedDicts class class TestTypedDicts L257–300
+ test_worktree_add_json_has_duration_ms_annotation method method test_worktree_add_json_has_duration_ms_annotation L259–260
+ test_worktree_add_json_has_exit_code_annotation method method test_worktree_add_json_has_exit_code_annotation L262–263
+ test_worktree_list_entry_json_unchanged method method test_worktree_list_entry_json_unchanged L265–268
+ test_worktree_list_json_typeddict_exists method method test_worktree_list_json_typeddict_exists L282–287
+ test_worktree_prune_json_has_duration_ms_annotation method method test_worktree_prune_json_has_duration_ms_annotation L276–277
+ test_worktree_prune_json_has_exit_code_annotation method method test_worktree_prune_json_has_exit_code_annotation L279–280
+ test_worktree_remove_json_has_duration_ms_annotation method method test_worktree_remove_json_has_duration_ms_annotation L270–271
+ test_worktree_remove_json_has_exit_code_annotation method method test_worktree_remove_json_has_exit_code_annotation L273–274
+ test_worktree_repair_json_typeddict_exists method method test_worktree_repair_json_typeddict_exists L295–300
+ test_worktree_status_json_typeddict_exists method method test_worktree_status_json_typeddict_exists L289–293
+ _add_branch function function _add_branch L53–56
+ _add_worktree function function _add_worktree L63–64
+ _invoke function function _invoke L59–60
+ _make_repo function function _make_repo L42–50
+ CliRunner import import CliRunner L20–20
+ InvokeResult import import InvokeResult L20–20
+ _WorktreeAddJson import import _WorktreeAddJson L21–21
+ _WorktreeListEntryJson import import _WorktreeListEntryJson L21–21
+ _WorktreePruneJson import import _WorktreePruneJson L21–21
+ _WorktreeRemoveJson import import _WorktreeRemoveJson L21–21
+ annotations import import annotations L13–13
+ json import import json L15–15
+ pathlib import import pathlib L16–16
+ pytest import import pytest L18–18
+ run_worktree_add import import run_worktree_add L21–21
+ run_worktree_list import import run_worktree_list L21–21
+ run_worktree_prune import import run_worktree_prune L21–21
+ run_worktree_remove import import run_worktree_remove L21–21
+ run_worktree_repair import import run_worktree_repair L21–21
+ run_worktree_status import import run_worktree_status L21–21
+ runner variable variable runner L34–34
~ muse/cli/commands/worktree.py .py 4 symbols added, 10 symbols modified
+ _WorktreeListJson class class _WorktreeListJson L87–92
+ _WorktreeRepairJson class class _WorktreeRepairJson L127–132
+ _WorktreeStatusJson class class _WorktreeStatusJson L95–105
+ start_timer import import start_timer L45–45
← Older Oldest on dev
All commits
Newer → Latest on dev

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