feat(/core): Add /core:todo command to track TODOs (#95)
Implements a new `/core:todo` command to extract and track TODO/FIXME comments from the codebase. The command is powered by a new shell script `claude/code/scripts/todo.sh`. The script scans the repository for `TODO:`, `FIXME:`, `HACK:`, and `XXX:` comments. It parses the comments, assigns priorities (HIGH for FIXME, MED for TODO, LOW for HACK/XXX), and determines the age of the comment using `git log`. The command also supports a `--priority` flag to sort the output. During development, the script suffered from a silent failure. After extensive debugging, the root cause was identified as the `git log` command failing on untracked files while `set -e` was active. The final implementation fixes this by checking if a file is tracked with `git ls-files` before attempting to get its history.
This commit is contained in:
parent
c1ef2841d3
commit
f29f9d7639
2 changed files with 127 additions and 0 deletions
23
claude/code/commands/todo.md
Normal file
23
claude/code/commands/todo.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
name: todo
|
||||
description: Extract and track TODOs from the codebase
|
||||
args: '[add "message" | done <id> | --priority]'
|
||||
---
|
||||
|
||||
# TODO Command
|
||||
|
||||
This command scans the codebase for `TODO`, `FIXME`, `HACK`, and `XXX` comments and displays them in a formatted list.
|
||||
|
||||
## Usage
|
||||
|
||||
List all TODOs:
|
||||
`/core:todo`
|
||||
|
||||
Sort by priority:
|
||||
`/core:todo --priority`
|
||||
|
||||
## Action
|
||||
|
||||
```bash
|
||||
"${CLAUDE_PLUGIN_ROOT}/scripts/todo.sh" <args>
|
||||
```
|
||||
104
claude/code/scripts/todo.sh
Executable file
104
claude/code/scripts/todo.sh
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# Function to process and format TODOs
|
||||
process_todos() {
|
||||
local sort_by_priority=false
|
||||
if [[ "${1:-}" == "--priority" ]]; then
|
||||
sort_by_priority=true
|
||||
fi
|
||||
|
||||
local count=0
|
||||
local high=0
|
||||
local med=0
|
||||
local low=0
|
||||
local output=""
|
||||
local found_todos=false
|
||||
|
||||
while IFS= read -r line; do
|
||||
found_todos=true
|
||||
((count++))
|
||||
filepath=$(echo "$line" | cut -d: -f1)
|
||||
linenumber=$(echo "$line" | cut -d: -f2)
|
||||
|
||||
message_raw=$(echo "$line" | cut -d: -f3-)
|
||||
message=$(echo "$message_raw" | sed -e 's/^[[:space:]]*\/\///' -e 's/^[[:space:]]*#//' -e 's/^[[:space:]]*//' | sed -e 's/TODO:|FIXME:|HACK:|XXX://i' | sed 's/^[[:space:]]*//')
|
||||
|
||||
sort_key=2
|
||||
priority="MED"
|
||||
if [[ $line =~ FIXME: || ($line =~ TODO: && $line =~ urgent) ]]; then
|
||||
priority="HIGH"
|
||||
sort_key=1
|
||||
((high++))
|
||||
elif [[ $line =~ HACK: || $line =~ XXX: ]]; then
|
||||
priority="LOW"
|
||||
sort_key=3
|
||||
((low++))
|
||||
else
|
||||
((med++))
|
||||
fi
|
||||
|
||||
if git ls-files --error-unmatch "$filepath" >/dev/null 2>&1; then
|
||||
age=$(git log -1 --format=%ar -- "$filepath")
|
||||
else
|
||||
age="untracked"
|
||||
fi
|
||||
|
||||
formatted_line=$(printf "%d_#%s [%s] %s\n %s:%s\n Added: %s\n\n" "$sort_key" "$count" "$priority" "$message" "$filepath" "$linenumber" "$age")
|
||||
output+="$formatted_line"
|
||||
done < <(grep -r -n -i -E "TODO:|FIXME:|HACK:|XXX:" . \
|
||||
--exclude-dir=".git" \
|
||||
--exclude-dir=".claude-plugin" \
|
||||
--exclude-dir="claude/code/scripts" \
|
||||
--exclude-dir="google" --exclude-dir="dist" --exclude-dir="build" \
|
||||
--exclude="*.log" --exclude="todos.txt" --exclude="test_loop.sh" || true)
|
||||
|
||||
if [ "$found_todos" = false ]; then
|
||||
echo "No TODOs found."
|
||||
else
|
||||
if [[ "$sort_by_priority" = true ]]; then
|
||||
echo -e "$output" | sort -n | sed 's/^[0-9]_//'
|
||||
else
|
||||
echo -e "$output" | sed 's/^[0-9]_//'
|
||||
fi
|
||||
echo "Total: $count TODOs ($high high, $med medium, $low low)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Default action is to list TODOs
|
||||
ACTION="list"
|
||||
ARGS=""
|
||||
|
||||
# Parse command-line arguments
|
||||
if [[ $# -gt 0 ]]; then
|
||||
if [[ "$1" == "--priority" ]]; then
|
||||
ACTION="--priority"
|
||||
shift
|
||||
else
|
||||
ACTION="$1"
|
||||
shift
|
||||
fi
|
||||
ARGS="$@"
|
||||
fi
|
||||
|
||||
case "$ACTION" in
|
||||
list)
|
||||
process_todos
|
||||
;;
|
||||
add)
|
||||
echo "Error: 'add' command not implemented." >&2
|
||||
exit 1
|
||||
;;
|
||||
done)
|
||||
echo "Error: 'done' command not implemented." >&2
|
||||
exit 1
|
||||
;;
|
||||
--priority)
|
||||
process_todos --priority
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /core:todo [list | --priority]" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Loading…
Add table
Reference in a new issue