Skip to content

Conversation

@TechNickAI
Copy link
Owner

Summary

  • Adds PostToolUse hook that saves todos to Claude's project directory as human-readable markdown
  • Uses transcript_path to store in Claude's existing ~/.claude/projects/{project}/ structure
  • Adds restoration instructions to context.md

Problem

Todos don't survive context compaction. This is a well-known issue (#14258) with no existing solution.

Solution

A single PostToolUse hook that:

  1. Intercepts every TodoWrite call
  2. Extracts todos from the tool input JSON
  3. Saves them as readable markdown to ~/.claude/projects/{project}/todos.md

After compaction, context.md instructs Claude how to restore:

cat ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md

Design choices

  • Project-scoped, not session-scoped: Multiple sessions in the same project share todos (simpler, usually correct)
  • Uses existing infrastructure: Stores in Claude's ~/.claude/projects/ directory rather than inventing new paths
  • Human-readable format: Markdown grouped by status, not JSON
  • No files in repo: Everything stored in ~/.claude/

Test plan

  • Validated hook scripts with bash -n
  • Tested todo-persist.sh with simulated PostToolUse input
  • Verified discovery command works from project directory
  • Test in new Claude Code session (hooks load at startup)
  • Test compaction recovery flow

🤖 Generated with Claude Code

Todos are now automatically saved to Claude's project directory via a
PostToolUse hook. After compaction, todos can be restored by checking
~/.claude/projects/{project}/todos.md

- Add PostToolUse hook that saves todos as human-readable markdown
- Use transcript_path to store in Claude's existing project directory
- Add restoration instructions to context.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d5cfb47ff

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +24 to +25
# Use Claude's existing project directory (parent of transcript file)
PROJECT_DIR=$(dirname "$TRANSCRIPT_PATH")
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The analysis is incorrect. Claude Code stores transcript files directly in the project directory (~/.claude/projects//<session_id>.jsonl), not in a transcripts/ subdirectory. So dirname "$TRANSCRIPT_PATH" correctly points to the project directory where recovery expects to find todos.md.

Verified: The saved file at ~/.claude/projects/-Users-nick-src-ai-coding-config/todos.md matches the recovery path from context.md.

@claude
Copy link

claude bot commented Jan 21, 2026

Code Review - Todo Persistence Hooks

Thanks for this PR! The todo persistence feature is a clever solution to the context compaction issue. Here's my comprehensive review:

Strengths

  1. Smart architecture - Using Claude's existing ~/.claude/projects/ directory is elegant and leverages existing infrastructure
  2. Human-readable format - Markdown output makes it easy to manually inspect saved todos
  3. Well-tested - Shell syntax validation passes, and the test plan shows good testing discipline
  4. Proper JSON handling - Uses jq for safe JSON parsing
  5. Clean hook integration - The PostToolUse hook is minimal and focused

🐛 Bugs & Issues

CRITICAL: Directory creation missing

# Line 50 in todo-persist.sh will fail if PROJECT_DIR doesn't exist
} > "$PROJECT_DIR/todos.md"

Issue: The script assumes PROJECT_DIR exists, but it may not on first run. This will cause the hook to fail silently.

Fix: Add directory creation before writing:

mkdir -p "$PROJECT_DIR"
} > "$PROJECT_DIR/todos.md"

Medium: Incomplete test plan

The PR description shows:

  • Test in new Claude Code session (hooks load at startup)
  • Test compaction recovery flow

These are marked incomplete. Should these be done before merging?

🔒 Security Considerations

  1. Path traversal protection needed: TRANSCRIPT_PATH comes from external input. While Claude Code likely provides safe paths, adding validation would be defensive:
# After extracting TRANSCRIPT_PATH
if [[ "$TRANSCRIPT_PATH" =~ \.\. ]]; then
    exit 0  # Reject paths with ..
fi
  1. Command injection risk: The date command is safe, but consider using date -u for timezone consistency

Performance & Best Practices

  1. Inefficient loop: Lines 43-47 read items line by line but could be more efficient:
# Current approach spawns a subprocess for each item
echo "$items" | while read -r item; do

Better: Use jq array iteration or process substitution

  1. Exit code consistency: The script always exits with 0. Consider returning 1 on errors for better observability

  2. Portability: date -Iseconds is GNU-specific. MacOS uses date -u +"%Y-%m-%dT%H:%M:%S%z". Consider:

date -u +"%Y-%m-%dT%H:%M:%SZ"  # Works on both

📝 Documentation

  1. Great context.md addition - The restoration instructions are clear and actionable
  2. Consider adding: Example of what a restored todo workflow looks like
  3. Path encoding question: The sed command sed 's|/|-|g' converts /home/user/project to -home-user-project. Is this Claude Code's standard? Document this convention.

🧪 Test Coverage

Missing test cases:

  1. Unicode in todo content (emojis, special characters)
  2. Todos with newlines in content
  3. Very long todo lists (performance)
  4. Concurrent writes (if multiple sessions share a project)
  5. What happens if jq is not installed?

🎯 Recommendations

Before merging:

  1. Fix the directory creation bug (critical)
  2. Complete the test plan (test in actual session + compaction)
  3. ⚠️ Add jq dependency check - fail gracefully if missing

Nice to have:
4. Add error logging to a debug file for troubleshooting
5. Add atomic write (write to temp file, then move)
6. Document the project path encoding convention

📊 Overall Assessment

This is a well-designed solution to a real problem. The architecture is sound and the implementation is mostly clean. The critical bug needs fixing before merge, and completing the test plan would give confidence the feature works end-to-end.

Recommendation: Request changes for the directory creation bug, then approve once fixed and tested.


Great work on tackling this context compaction issue! 🚀

cursor[bot]

This comment was marked as outdated.

Use POSIX-compliant date format that works on both GNU and BSD date.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@TechNickAI
Copy link
Owner Author

Thanks for the thorough review! Addressing your feedback:

Directory creation: The directory is guaranteed to exist - Claude Code creates PROJECT_DIR when it writes the transcript file at TRANSCRIPT_PATH. Since we successfully extract transcript_path, dirname must exist. No fix needed.

Path traversal: TRANSCRIPT_PATH comes from Claude Code's internal hook system, not user input. It's trusted and controlled by Claude Code itself.

Date portability: Fixed in 26a2caf - now using POSIX-compliant format.

Test plan: Will test in a new session, but that doesn't require code changes.

The core architecture is sound - thanks for validating the approach!

@claude
Copy link

claude bot commented Jan 21, 2026

Code Review: Todo Persistence Hooks

Overview

This PR adds a clever workaround for preserving todos across context compaction by using PostToolUse hooks to save todos to Claude's project directory. The approach is pragmatic and well-executed.


✅ Strengths

1. Smart Architecture Decision

  • Leverages existing ~/.claude/projects/ infrastructure rather than creating new paths
  • Uses transcript_path to derive the project directory - clean and reliable
  • Project-scoped todos (vs session-scoped) is the right default for most use cases

2. Robust Script Implementation

  • Bash syntax validated (bash -n passes)
  • Proper null/empty checks before processing
  • Graceful early exits for non-TodoWrite calls
  • POSIX-compliant date format (good macOS fix in commit 26a2caf)

3. Human-Readable Format

  • Markdown output grouped by status (In Progress, Pending, Completed) is far better than raw JSON
  • Timestamp for debugging
  • Easy to manually inspect/edit if needed

4. Clear Documentation

  • Restoration instructions in context.md with exact command
  • Inline comments in hook script explain purpose

🔶 Issues & Recommendations

Critical: Missing jq Dependency Check

Location: todo-persist.sh:9-10, 18, 36

Issue: Script uses jq without checking if it's installed. If jq is missing, the hook will silently fail.

Impact: Todos won't persist, but no error will surface to the user.

Recommendation:

# Add near top of script (after shebang)
if ! command -v jq >/dev/null 2>&1; then
    echo "[todo-persist] Error: jq not found. Install with: brew install jq (macOS) or apt-get install jq (Linux)" >&2
    exit 1
fi

Bug: TODOS Variable Contains JSON, Not Plain Text

Location: todo-persist.sh:18

Issue:

TODOS=$(echo "$INPUT" | jq -r '.tool_input.todos // empty')

The -r flag with // empty on an array produces raw JSON output, not an empty string. The check on line 20 won't work as intended for empty arrays.

Test case:

echo '{"tool_input":{"todos":[]}}' | jq -r '.tool_input.todos // empty'
# Output: []
# Line 20 check: [ -z "[]" ] evaluates to FALSE (should be TRUE)

Recommendation:

# More robust check
TODOS=$(echo "$INPUT" | jq '.tool_input.todos // empty')
if [ -z "$TODOS" ] || [ "$TODOS" = "null" ] || [ "$TODOS" = "[]" ] || [ -z "$TRANSCRIPT_PATH" ]; then
    exit 0
fi

Remove -r flag since we're keeping it as JSON for later processing.

Edge Case: Path Injection Risk (Low Severity)

Location: todo-persist.sh:25, 50

Issue: If TRANSCRIPT_PATH contains malicious characters (e.g., ../../../etc/passwd), the script would write to unexpected locations.

Likelihood: Very low (requires compromised Claude Code internals)

Recommendation: Add path validation:

# After line 25
if [[ "$PROJECT_DIR" != */".claude/projects/"* ]]; then
    echo "[todo-persist] Error: Invalid project directory path" >&2
    exit 1
fi

Potential Race Condition (Low Severity)

Location: todo-persist.sh:50

Issue: Multiple rapid TodoWrite calls could cause concurrent writes to todos.md. Last write wins, potentially losing intermediate states.

Likelihood: Low in practice (TodoWrite calls are usually sequential)

Recommendation: If this becomes an issue, use atomic writes:

} > "$PROJECT_DIR/todos.md.tmp"
mv "$PROJECT_DIR/todos.md.tmp" "$PROJECT_DIR/todos.md"

Documentation: Restoration Command Complexity

Location: context.md:24

Issue: The sed command sed 's|/|-|g' is clever but non-obvious. Users might not understand why it's needed or how to debug if it fails.

Recommendation: Add a comment explaining the path transformation:

1. Check for saved todos (transforms /path/to/project → -path-to-project):
   `cat ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md`

Or provide alternative command:

1. Find your project directory:
   `ls -lt ~/.claude/projects/ | head`
2. Check todos: `cat ~/.claude/projects/YOUR-PROJECT-DIR/todos.md`

Missing: Empty State Handling

Location: todo-persist.sh:35-49

Issue: If all todos are completed and then deleted, the file will show old completed todos forever.

Recommendation: Either:

  • Delete file when todos array is empty/all completed
  • Add "Last cleared" timestamp
  • Document that old completed todos persist (current behavior)

🧪 Testing Gaps

Per the PR description, these are not yet tested:

  • Test in new Claude Code session (hooks load at startup)
  • Test compaction recovery flow

Critical to validate:

  1. Hook actually fires in production Claude Code
  2. CLAUDE_PLUGIN_ROOT resolves correctly
  3. Restoration flow works as documented
  4. Behavior with empty todo list

Suggested test script:

# Test hook script directly
echo '{
  "tool_name": "TodoWrite",
  "transcript_path": "/tmp/test-project/.claude/projects/test/transcript.jsonl",
  "tool_input": {
    "todos": [
      {"content": "Test task", "status": "pending", "activeForm": "Testing"}
    ]
  }
}' | plugins/core/hooks/todo-persist.sh

# Verify output
cat /tmp/test-project/.claude/projects/test/todos.md

🎯 Nitpicks

  1. Inconsistent quoting: Line 36 uses --arg s "$status" but could be --arg s $status (inside double quotes already)

  2. Inefficient piping: Lines 36, 44-45 could be optimized to avoid subshells, but current approach is more readable

  3. No version/schema in output: Consider adding <!-- Generated by todo-persist.sh v1.0 --> to help debug format changes


🔒 Security Assessment

Overall: Low Risk

  • ✅ No user input processing (all data from Claude Code internals)
  • ✅ No network calls
  • ✅ No execution of dynamic commands
  • ⚠️ Writes to filesystem (but in controlled location)
  • ⚠️ Minor path injection risk (mitigated by Claude Code's internal controls)

Recommendation: Add path validation for defense in depth (see above).


📊 Performance Considerations

Impact: Negligible

  • Hook fires only on TodoWrite (not every tool call)
  • jq parsing is fast for small JSON
  • File I/O is minimal (< 1KB typically)
  • No blocking operations

Estimated overhead: < 10ms per TodoWrite call


✨ Summary

This is a pragmatic solution to a real problem (issue #14258). The implementation is clean, well-documented, and follows POSIX best practices.

Recommended Actions Before Merge:

  1. MUST FIX: Add jq dependency check with error message
  2. MUST FIX: Fix empty todos array detection (line 20)
  3. ⚠️ SHOULD FIX: Add path validation for security
  4. 📝 NICE TO HAVE: Simplify restoration documentation
  5. 🧪 REQUIRED: Complete end-to-end testing in live Claude Code session

Rating: 8/10 - Excellent concept and execution, needs minor fixes before merge.


Review Context:

  • Reviewed against CLAUDE.md conventions ✓
  • Checked bash syntax ✓
  • Analyzed referenced issue #14258 ✓
  • Tested jq availability ✓

Great work on this feature! The hook system is being used creatively here. 🎉

cursor[bot]

This comment was marked as outdated.

TechNickAI and others added 2 commits January 21, 2026 13:54
Highlights the solution to todos being lost during context compaction -
a common pain point for Claude Code users.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New feature: Todo persistence hooks survive context compaction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 21, 2026

Code Review: Todo Persistence Hook

Summary

This PR adds a PostToolUse hook to persist todos across context compaction by saving them to Claude's project directory. The implementation is clean, focused, and solves a real pain point.


✅ Strengths

1. Excellent Design Choices

  • Leverages existing infrastructure: Uses Claude's ~/.claude/projects/ directory rather than inventing new paths
  • Project-scoped storage: Appropriate granularity - todos persist across sessions in the same project
  • Human-readable format: Markdown output is debuggable and manually editable
  • Zero files in repo: Clean separation between plugin code and user data

2. Clean Implementation

  • Simple bash script with clear logic flow
  • Proper early exits for non-TodoWrite calls
  • Good use of jq for JSON parsing
  • Executable permissions set correctly (chmod +x)

3. Good Documentation

  • Clear README section explaining the problem and solution
  • Context.md includes restoration instructions for post-compaction recovery
  • Inline comments in the hook script

🔍 Issues Found

1. Critical Bug: Empty Items in Markdown Output (todo-persist.sh:44-46)

The current implementation has a flaw in how it processes multi-line jq output:

items=$(echo "$TODOS" | jq -r --arg s "$status" '.[] | select(.status == $s) | .content')
if [ -n "$items" ]; then
    # ...
    echo "$items" | while read -r item; do
        [ -n "$item" ] && echo "- $item"
    done

Problem: When jq returns multiple todo items (one per line), the if [ -n "" ] check passes even if some individual lines are empty. This can result in blank bullet points in the markdown file.

Impact: Produces malformed markdown with empty list items:

## Pending
- Fix authentication bug
- 
- Add unit tests

Recommended fix: Process items in a single pass without the separate check:

echo "$TODOS" | jq -r --arg s "$status" '.[] | select(.status == $s) | .content' | while read -r item; do
    [ -n "$item" ] && echo "- $item"
done | if grep -q .; then
    case $status in
        in_progress) echo "## In Progress" ;;
        pending) echo "## Pending" ;;
        completed) echo "## Completed" ;;
    esac
    echo ""
    cat
    echo ""
fi

Or simpler - check if jq returns any output before printing the header:

items=$(echo "$TODOS" | jq -r --arg s "$status" '.[] | select(.status == $s) | .content' | grep -v '^$')
if [ -n "$items" ]; then
    case $status in
        in_progress) echo "## In Progress" ;;
        pending) echo "## Pending" ;;
        completed) echo "## Completed" ;;
    esac
    echo ""
    echo "$items" | while read -r item; do
        echo "- $item"
    done
    echo ""
fi

2. Missing Error Handling

The script lacks error handling for several failure scenarios:

  • jq not installed: No check for jq availability
  • Directory creation: If $PROJECT_DIR doesn't exist, the write will fail silently
  • Write permissions: No check if the directory is writable

Recommended additions:

# After shebang
set -euo pipefail  # Exit on error, undefined vars, pipe failures

# Before jq usage
if ! command -v jq &> /dev/null; then
    echo "Error: jq is required but not installed" >&2
    exit 1
fi

# Before writing file
if [ ! -d "$PROJECT_DIR" ]; then
    mkdir -p "$PROJECT_DIR" || exit 1
fi

if [ ! -w "$PROJECT_DIR" ]; then
    echo "Error: Cannot write to $PROJECT_DIR" >&2
    exit 1
fi

3. Path Transformation Mismatch (README.md:53, context.md:24)

The restoration command uses a different path transformation than the hook:

Hook uses: dirname $TRANSCRIPT_PATH (e.g., ~/.claude/projects/home-user-myproject/)

README suggests: ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md

Problem: These may produce different paths. If $TRANSCRIPT_PATH is ~/.claude/projects/foo/transcript.jsonl, the hook writes to ~/.claude/projects/foo/todos.md. But if the user's PWD is /home/user/myproject, the restoration command looks in ~/.claude/projects/-home-user-myproject/todos.md (note leading dash).

Verification needed: Test that the path transformation in the restoration command exactly matches Claude's project directory naming scheme.

Recommendation: Either:

  • Document the actual path structure with examples
  • Or provide a helper command that finds the correct path: find ~/.claude/projects -name todos.md -newer ~/.claude/projects/*/transcript.jsonl 2>/dev/null | head -1

4. Race Condition Risk

Multiple concurrent TodoWrite calls could cause file corruption since there's no file locking. While unlikely in normal usage (TodoWrite calls are typically sequential), it's worth noting.

Mitigation: Consider atomic writes:

temp_file=$(mktemp)
# ... write to $temp_file ...
mv "$temp_file" "$PROJECT_DIR/todos.md"

🤔 Questions & Considerations

1. Test Coverage

The PR description mentions:

  • Validated hook scripts with bash -n
  • Tested todo-persist.sh with simulated PostToolUse input
  • Test in new Claude Code session (hooks load at startup)
  • Test compaction recovery flow

The two unchecked items are critical for validating the end-to-end flow. Consider:

  • How will you test context compaction without waiting for it naturally?
  • Can you simulate it by manually clearing context and testing restoration?

2. activeForm Field

The TodoWrite tool requires both content and activeForm fields, but the hook only saves content. Should activeForm also be persisted for full fidelity restoration?

Current: Only saves content

- Fix authentication bug

With activeForm: Could save both

- Fix authentication bug (active: "Fixing authentication bug")

This matters if users restore todos and want Claude to continue with proper progress indicators.

3. Completed Todos

Should completed todos be saved at all? They may clutter the restoration. Consider:

  • Option A: Don't save completed todos (current behavior works, just questioning the value)
  • Option B: Save but with TTL/max count (last 10 completed items)
  • Option C: Separate file for completed items

4. Issue Reference

The PR mentions issue #14258, but it's not found in this repo. Is that a Claude Code core issue? Consider adding a link to the actual issue for context.


🔒 Security Review

No security concerns identified

  • No user input injection vectors
  • File writes are scoped to Claude's directory
  • No command execution from user data
  • Hook runs with user's permissions (appropriate)

⚡ Performance Review

Minimal performance impact

  • Hook only runs on TodoWrite (infrequent)
  • Simple jq processing and file write
  • No blocking operations
  • File size will remain small (typical todo lists are <1KB)

📝 Suggested Improvements

Documentation:

  1. Add example of what the saved todos.md file looks like
  2. Document cleanup strategy (does it grow forever?)
  3. Consider adding troubleshooting section (what if restoration doesn't work?)

Code Quality:

  1. Add shellcheck to CI to catch common bash issues
  2. Consider adding a simple test script that exercises the hook with sample input
  3. Add version/schema marker to saved todos.md for future compatibility

User Experience:

  1. Consider a /todos restore command to automate restoration
  2. Add a command to view saved todos: /todos show
  3. Warn users if todos.md exists but TodoWrite is empty

📊 Summary

Category Status Notes
Code Quality ⚠️ Good with issues Clean implementation, but has bugs
Potential Bugs 🔴 Critical Empty items bug must be fixed
Performance ✅ Excellent Minimal overhead
Security ✅ Excellent No concerns
Test Coverage ⚠️ Partial Core flow untested
Documentation ✅ Good Clear and helpful

Recommendation

Merge after fixes: This is a valuable feature that solves a real problem. The implementation is solid, but the critical bug and error handling issues should be addressed before merge.

Priority fixes:

  1. 🔴 Fix empty items bug in markdown output
  2. 🟡 Add error handling for missing jq and directory issues
  3. 🟡 Verify/document path transformation accuracy

Nice-to-haves (can be follow-up PRs):

  • Restoration helper command
  • Shellcheck in CI
  • activeForm persistence
  • Completed todos cleanup strategy

Great work on tackling context compaction! This will be super helpful for maintaining workflow continuity. 🎉

@TechNickAI TechNickAI merged commit c76ac5c into main Jan 21, 2026
3 checks passed
@TechNickAI TechNickAI deleted the feat/todo-persistence-hooks branch January 21, 2026 19:57
@claude
Copy link

claude bot commented Jan 21, 2026

Code Review: Todo Persistence Hooks

Summary

This PR adds a clever solution to a real problem (issue #14258) - todos disappearing after context compaction. The implementation uses PostToolUse hooks to automatically persist todos to disk in a human-readable format.

✅ Strengths

  1. Elegant design: Uses Claude's existing ~/.claude/projects/ infrastructure rather than inventing new paths
  2. Human-readable format: Markdown output makes it easy to inspect saved todos
  3. Proper hook structure: Follows Claude plugin hook conventions correctly
  4. Good documentation: README and context.md provide clear restoration instructions
  5. Clean implementation: Script is focused and does one thing well

🔴 Critical Issue

Missing directory creation: The script will fail if the project directory doesn't exist yet.

# Line 50 in todo-persist.sh
} > "$PROJECT_DIR/todos.md"  # Fails if PROJECT_DIR doesn't exist

Fix needed:

# Add before line 27
mkdir -p "$PROJECT_DIR" || exit 1

Reproduction:

# Fails when PROJECT_DIR is /tmp/nonexistent
cat << 'EOF' | bash todo-persist.sh
{"tool_name":"TodoWrite","transcript_path":"/tmp/nonexistent/transcript.json","tool_input":{"todos":[{"content":"Test","status":"pending","activeForm":"Testing"}]}}
EOF
# Error: /tmp/nonexistent/todos.md: No such file or directory

🟡 Minor Issues

  1. Error handling: Silent failures if jq is missing or JSON is malformed

    • Consider adding: command -v jq >/dev/null 2>&1 || exit 0
  2. Race condition potential: Multiple concurrent TodoWrite calls could corrupt the file

    • Low risk in practice, but could use flock for atomic writes if needed
  3. Restoration UX: The restoration command is complex and error-prone

    cat ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md
    • Consider adding a helper command like /restore-todos for better UX
  4. Version bumps: Correctly updated to 9.15.0 across all files ✅

🟢 Security & Performance

  • Security: No injection vulnerabilities, safe use of variables
  • Performance: Minimal overhead, runs only on TodoWrite calls
  • No sensitive data exposure: Todos stored in user's home directory with normal permissions

📝 Test Coverage

From the PR description:

  • ✅ Validated hook scripts with bash -n
  • ✅ Tested with simulated input
  • ✅ Verified discovery command
  • ⏳ Pending: Real Claude Code session testing
  • ⏳ Pending: Compaction recovery flow testing

Recommendations

Must fix before merge:

  1. Add mkdir -p "$PROJECT_DIR" before writing the file

Nice to have:

  1. Add jq dependency check
  2. Consider adding a /restore-todos command for easier UX
  3. Add integration tests for the compaction recovery flow

Verdict

Strong implementation that solves a real user pain point. With the directory creation fix, this is ready to merge. The design choices (project-scoped, using existing paths, human-readable format) are all sound.

Status: Approve with required fix ✅ (after adding mkdir -p)


📊 Files changed: 6 | +98 -5 lines
🎯 Plugin version: 9.14.0 → 9.15.0

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

compaction, restore them:

```bash
cat ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation command fails for paths containing spaces

Low Severity

The todo restore command cat ~/.claude/projects/$(echo $PWD | sed 's|/|-|g')/todos.md has an unquoted command substitution. When $PWD contains spaces (e.g., /home/user/my project), the sed output -home-user-my project undergoes word splitting, causing cat to receive incorrect arguments and fail. The command substitution needs to be quoted to preserve spaces in the resulting path.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants