gabriel / muse public
feat patch task/apply-command #1 / 1
gabriel · 166 days ago · Apr 14, 2026 · Diff

feat: add muse apply command — apply .patch files to working tree

Implements _parse_patch, _apply_hunk, register, and run. - Parses unified diff (with mail-format header stripping) - Handles --check (validate without writing), --json output - Rejects path traversal and .muse/ internal paths - Supports format-patch → apply round-trip - 16 tests: unit, integration, security, stress — all green

sha256:c54a29a70951ebb33f9f8d65ec9e65101402d48ce03a713cdee4572ff997a579 sha
+65 ~30 symbols
sha256:aa0205711ec0dae67052ccd9e3299289d301f8219cbb16242f3e1c347fbd8e7a snapshot
+65
symbols added
~30
symbols modified
0
dead code introduced
Semantic Changes 95 symbols
~ muse/cli/commands/apply.py .py 23 symbols added
+ _FROM_RE variable variable _FROM_RE L52–52
+ _HUNK_RE variable variable _HUNK_RE L55–55
+ _MAIL_HEADERS variable variable _MAIL_HEADERS L57–57
+ _TO_RE variable variable _TO_RE L53–53
+ _apply_hunk function function _apply_hunk L193–240
+ _parse_patch function function _parse_patch L74–190
+ _strip_mail_headers function function _strip_mail_headers L65–71
+ _validate_path function function _validate_path L243–263
+ ExitCode import import ExitCode L45–45
+ Iterator import import Iterator L43–43
+ _json import import _json L38–38
+ annotations import import annotations L35–35
+ argparse import import argparse L37–37
+ contain_path import import contain_path L47–47
+ logging import import logging L39–39
+ pathlib import import pathlib L40–40
+ re import import re L41–41
+ require_repo import import require_repo L46–46
+ sanitize_display import import sanitize_display L47–47
+ sys import import sys L42–42
+ logger variable variable logger L49–49
+ register function function register L271–302
+ run function function run L310–400
~ tests/test_cmd_apply.py .py 41 symbols added
+ _REPO_ID variable variable _REPO_ID L32–32
+ _commit_files function function _commit_files L60–99
+ _counter variable variable _counter L33–33
+ _env function function _env L56–57
+ _init_repo function function _init_repo L45–53
+ _invoke function function _invoke L102–104
+ _make_simple_patch function function _make_simple_patch L107–116
+ _sha function function _sha L41–42
+ CliRunner import import CliRunner L24–24
+ CommitRecord import import CommitRecord L27–27
+ Manifest import import Manifest L28–28
+ SnapshotRecord import import SnapshotRecord L27–27
+ annotations import import annotations L14–14
+ compute_commit_id import import compute_commit_id L26–26
+ compute_snapshot_id import import compute_snapshot_id L26–26
+ datetime import import datetime L16–16
+ hashlib import import hashlib L17–17
+ json import import json L18–18
+ pathlib import import pathlib L19–19
+ pytest import import pytest L22–22
+ textwrap import import textwrap L20–20
+ write_commit import import write_commit L27–27
+ write_object import import write_object L25–25
+ write_snapshot import import write_snapshot L27–27
+ runner variable variable runner L30–30
+ test_apply_check_does_not_modify_file function function test_apply_check_does_not_modify_file L272–281
+ test_apply_check_exits_nonzero_on_conflict function function test_apply_check_exits_nonzero_on_conflict L284–292
+ test_apply_hunk_basic function function test_apply_hunk_basic L175–188
+ test_apply_hunk_preserves_surrounding_lines function function test_apply_hunk_preserves_surrounding_lines L191–205
+ test_apply_json_output function function test_apply_json_output L235–246
+ test_apply_large_hunk function function test_apply_large_hunk L362–376
+ test_apply_modifies_file_content function function test_apply_modifies_file_content L213–221
+ test_apply_multiple_files function function test_apply_multiple_files L249–264
+ test_apply_new_file_created function function test_apply_new_file_created L224–232
+ test_apply_rejects_muse_internal_paths function function test_apply_rejects_muse_internal_paths L343–354
+ test_apply_rejects_path_traversal_in_patch function function test_apply_rejects_path_traversal_in_patch L328–340
+ test_format_patch_apply_roundtrip function function test_format_patch_apply_roundtrip L300–320
+ test_parse_patch_extracts_file_diffs function function test_parse_patch_extracts_file_diffs L124–129
+ test_parse_patch_multiple_files function function test_parse_patch_multiple_files L147–158
+ test_parse_patch_new_file function function test_parse_patch_new_file L161–167
+ test_parse_patch_skips_mail_headers function function test_parse_patch_skips_mail_headers L132–144
← Older Oldest on task/apply-command
All commits
Newer → Latest on task/apply-command

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