One function
extract_files_from_bash in severity1/claude-code-auto-memory
The author described this change as “Fix bash command parsing to stop at shell operators”. It counts as a record because the check below fails on the code as it stood at 2b76c8e93 and passes on 45ff2fb6d, with nothing else changed between the two runs.
Fix saved2025-11-29
Sharing licenceMIT · LICENSE
Change size+14 −2
What the code was meant to do, written into the code itself as a docstring
Extract file paths from Bash commands that modify files. Detects: rm, rm -rf, mv, git rm, git mv, unlink Returns list of file paths that should be tracked.
The change
| 24 | 24 | if command.startswith(skip_prefixes): | |
| 25 | 25 | return [] | |
| 26 | 26 | ||
| 27 | + | # Shell operators that chain commands - stop parsing at these | |
| 28 | + | shell_operators = ("&&", "||", ";", "|", ">", ">>", "<", "2>", "2>&1") | |
| 29 | + | ||
| 27 | 30 | files = [] | |
| 28 | 31 | ||
| 29 | 32 | try: | |
| ⋯ | |||
| 36 | 39 | ||
| 37 | 40 | # Handle: rm, rm -rf, rm -f, etc. | |
| 38 | 41 | if cmd == "rm": | |
| 39 | - | # Skip flags, collect file arguments | |
| 42 | + | # Skip flags, collect file arguments until shell operator | |
| 40 | 43 | for token in tokens[1:]: | |
| 44 | + | if token in shell_operators: | |
| 45 | + | break # Stop at command chaining operator | |
| 41 | 46 | if not token.startswith("-"): | |
| 42 | 47 | files.append(token) | |
| 43 | 48 | ||
| 44 | 49 | # Handle: git rm | |
| 45 | 50 | elif cmd == "git" and len(tokens) > 1 and tokens[1] == "rm": | |
| 46 | 51 | for token in tokens[2:]: | |
| 52 | + | if token in shell_operators: | |
| 53 | + | break | |
| 47 | 54 | if not token.startswith("-"): | |
| 48 | 55 | files.append(token) | |
| 49 | 56 | ||
| ⋯ | |||
| 51 | 58 | elif cmd == "mv" and len(tokens) >= 3: | |
| 52 | 59 | # Skip flags, get first non-flag arg (source) | |
| 53 | 60 | for token in tokens[1:]: | |
| 61 | + | if token in shell_operators: | |
| 62 | + | break | |
| 54 | 63 | if not token.startswith("-"): | |
| 55 | 64 | files.append(token) | |
| 56 | 65 | break # Only track source, not destination | |
| ⋯ | |||
| 58 | 67 | # Handle: git mv (track source file only) | |
| 59 | 68 | elif cmd == "git" and len(tokens) > 2 and tokens[1] == "mv": | |
| 60 | 69 | for token in tokens[2:]: | |
| 70 | + | if token in shell_operators: | |
| 71 | + | break | |
| 61 | 72 | if not token.startswith("-"): | |
| 62 | 73 | files.append(token) | |
| 63 | 74 | break | |
| 64 | 75 | ||
| 65 | 76 | # Handle: unlink | |
| 66 | 77 | elif cmd == "unlink" and len(tokens) > 1: | |
| 67 | - | files.append(tokens[1]) | |
| 78 | + | if tokens[1] not in shell_operators: | |
| 79 | + | files.append(tokens[1]) | |
| 68 | 80 | ||
| 69 | 81 | except ValueError: | |
| 70 | 82 | # shlex.split failed (unbalanced quotes, etc.) - skip | |
The check that tells the two apart
fail→pass·tests/test_hooks.py::TestPostToolUseHook::test_stops_at_shell_operators
Check file tests/test_hooks.py, taken without changes from the fix and copied onto the older code, so the exact same check runs against both versions.
Origin and history
The code before it2b76c8e9306663f3ac1119c1723821d142da7f92
Broken version dated2025-11-29
Modulescripts.post-tool-use
Units changedextract_files_from_bash
Fingerprintc304ae845892b914
Checked2026-08-18 by goldset/0.1
Every field above is generated by our program. None of it is written by hand.