fix-smart-quotes 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -9
- package/docs/plans/2026-01-21-hook-wrapper-fix.md +160 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# fix-smart-quotes
|
|
2
2
|
|
|
3
|
-
Convert straight quotes to proper typographic (
|
|
3
|
+
Convert straight quotes to proper typographic (“smart”) quotes in Markdown files.
|
|
4
4
|
|
|
5
5
|
| Language | Before | After |
|
|
6
6
|
|----------|--------|-------|
|
|
@@ -51,26 +51,39 @@ fix-smart-quotes docs/*.md
|
|
|
51
51
|
|
|
52
52
|
## Claude Code Hook
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Automatically fix quotes after Claude edits Markdown files.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
**1. Create wrapper script** at `~/.claude/hooks/fix-smart-quotes-wrapper.sh`:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
#!/bin/bash
|
|
60
|
+
INPUT=$(cat)
|
|
61
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
62
|
+
[ -z "$FILE_PATH" ] && exit 0
|
|
63
|
+
[[ ! "$FILE_PATH" =~ \.md$ ]] && exit 0
|
|
64
|
+
[ ! -f "$FILE_PATH" ] && exit 0
|
|
65
|
+
npx fix-smart-quotes "$FILE_PATH"
|
|
66
|
+
exit 0
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**2. Make executable:** `chmod +x ~/.claude/hooks/fix-smart-quotes-wrapper.sh`
|
|
70
|
+
|
|
71
|
+
**3. Add to** `~/.claude/settings.json`:
|
|
57
72
|
|
|
58
73
|
```json
|
|
59
74
|
{
|
|
60
75
|
"hooks": {
|
|
61
76
|
"PostToolUse": [{
|
|
62
77
|
"matcher": "Write|Edit",
|
|
63
|
-
"hooks": [{
|
|
64
|
-
"type": "command",
|
|
65
|
-
"command": "npx fix-smart-quotes \"$FILE_PATH\"",
|
|
66
|
-
"timeout": 30
|
|
67
|
-
}]
|
|
78
|
+
"hooks": [{"type": "command", "command": "~/.claude/hooks/fix-smart-quotes-wrapper.sh", "timeout": 30}]
|
|
68
79
|
}]
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
82
|
```
|
|
72
83
|
|
|
73
|
-
|
|
84
|
+
> **Note:** Claude Code passes file paths via stdin JSON, not environment variables. The wrapper script handles this.
|
|
85
|
+
|
|
86
|
+
> **Important:** After changing settings.json, restart Claude Code. Hook configuration is cached at startup.
|
|
74
87
|
|
|
75
88
|
## Features
|
|
76
89
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Hook Wrapper Fix Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Fix the PostToolUse hook to correctly receive file paths via stdin JSON instead of environment variables.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Create a wrapper shell script that parses JSON from stdin, extracts the file path, filters for markdown files only, and calls fix-smart-quotes. Update settings.json to use the wrapper.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Bash, jq, Node.js (fix-smart-quotes)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Task 1: Create Wrapper Script
|
|
14
|
+
|
|
15
|
+
**Files:**
|
|
16
|
+
- Create: `~/.claude/hooks/fix-smart-quotes-wrapper.sh`
|
|
17
|
+
|
|
18
|
+
**Step 1: Create the wrapper script**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
#!/bin/bash
|
|
22
|
+
# fix-smart-quotes-wrapper.sh
|
|
23
|
+
# Wrapper for fix-smart-quotes that parses Claude Code hook stdin JSON
|
|
24
|
+
|
|
25
|
+
# Read JSON from stdin
|
|
26
|
+
INPUT=$(cat)
|
|
27
|
+
|
|
28
|
+
# Extract file_path from JSON using jq
|
|
29
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty')
|
|
30
|
+
|
|
31
|
+
# Exit 0 if no file path found (non-blocking)
|
|
32
|
+
if [ -z "$FILE_PATH" ]; then
|
|
33
|
+
exit 0
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Only process markdown files
|
|
37
|
+
if [[ ! "$FILE_PATH" =~ \.(md|markdown)$ ]]; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Check if file exists
|
|
42
|
+
if [ ! -f "$FILE_PATH" ]; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Run fix-smart-quotes
|
|
47
|
+
npx fix-smart-quotes "$FILE_PATH"
|
|
48
|
+
|
|
49
|
+
# Always exit 0 to not block Claude Code
|
|
50
|
+
exit 0
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Step 2: Make script executable**
|
|
54
|
+
|
|
55
|
+
Run: `chmod +x ~/.claude/hooks/fix-smart-quotes-wrapper.sh`
|
|
56
|
+
|
|
57
|
+
**Step 3: Verify script is executable**
|
|
58
|
+
|
|
59
|
+
Run: `ls -la ~/.claude/hooks/fix-smart-quotes-wrapper.sh`
|
|
60
|
+
Expected: `-rwxr-xr-x` permissions
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Task 2: Test Wrapper Script Manually
|
|
65
|
+
|
|
66
|
+
**Step 1: Test with valid markdown file path**
|
|
67
|
+
|
|
68
|
+
Run:
|
|
69
|
+
```bash
|
|
70
|
+
echo '{"tool_input": {"file_path": "/tmp/test.md"}}' > /tmp/test.md
|
|
71
|
+
echo 'This is a "test" file.' >> /tmp/test.md
|
|
72
|
+
echo '{"tool_input": {"file_path": "/tmp/test.md"}}' | ~/.claude/hooks/fix-smart-quotes-wrapper.sh
|
|
73
|
+
echo "Exit code: $?"
|
|
74
|
+
cat /tmp/test.md
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Expected: Exit code 0, file contains smart quotes
|
|
78
|
+
|
|
79
|
+
**Step 2: Test with non-markdown file**
|
|
80
|
+
|
|
81
|
+
Run:
|
|
82
|
+
```bash
|
|
83
|
+
echo '{"tool_input": {"file_path": "/tmp/test.json"}}' | ~/.claude/hooks/fix-smart-quotes-wrapper.sh
|
|
84
|
+
echo "Exit code: $?"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Expected: Exit code 0 (non-blocking)
|
|
88
|
+
|
|
89
|
+
**Step 3: Test with missing file_path**
|
|
90
|
+
|
|
91
|
+
Run:
|
|
92
|
+
```bash
|
|
93
|
+
echo '{"tool_input": {}}' | ~/.claude/hooks/fix-smart-quotes-wrapper.sh
|
|
94
|
+
echo "Exit code: $?"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Expected: Exit code 0 (non-blocking)
|
|
98
|
+
|
|
99
|
+
**Step 4: Cleanup test files**
|
|
100
|
+
|
|
101
|
+
Run: `rm -f /tmp/test.md /tmp/test.json`
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Task 3: Update settings.json
|
|
106
|
+
|
|
107
|
+
**Files:**
|
|
108
|
+
- Modify: `~/.claude/settings.json`
|
|
109
|
+
|
|
110
|
+
**Step 1: Update hook command**
|
|
111
|
+
|
|
112
|
+
Change from:
|
|
113
|
+
```json
|
|
114
|
+
"command": "npx fix-smart-quotes \"$FILE_PATH\""
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
To:
|
|
118
|
+
```json
|
|
119
|
+
"command": "~/.claude/hooks/fix-smart-quotes-wrapper.sh"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Step 2: Verify settings.json is valid JSON**
|
|
123
|
+
|
|
124
|
+
Run: `jq . ~/.claude/settings.json > /dev/null && echo "Valid JSON"`
|
|
125
|
+
Expected: "Valid JSON"
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Task 4: End-to-End Test
|
|
130
|
+
|
|
131
|
+
**Step 1: Create a test markdown file**
|
|
132
|
+
|
|
133
|
+
Run:
|
|
134
|
+
```bash
|
|
135
|
+
echo 'Test "quotes" here.' > /tmp/hook-test.md
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Step 2: Simulate hook invocation**
|
|
139
|
+
|
|
140
|
+
Run:
|
|
141
|
+
```bash
|
|
142
|
+
echo '{"tool_input": {"file_path": "/tmp/hook-test.md"}}' | ~/.claude/hooks/fix-smart-quotes-wrapper.sh
|
|
143
|
+
cat /tmp/hook-test.md
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Expected: File contains smart quotes (German style since no lang specified)
|
|
147
|
+
|
|
148
|
+
**Step 3: Cleanup**
|
|
149
|
+
|
|
150
|
+
Run: `rm /tmp/hook-test.md`
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Summary
|
|
155
|
+
|
|
156
|
+
After completing all tasks:
|
|
157
|
+
- [x] Wrapper script created at `~/.claude/hooks/fix-smart-quotes-wrapper.sh`
|
|
158
|
+
- [x] Wrapper parses stdin JSON, filters for .md files, exits 0 on non-matches
|
|
159
|
+
- [x] settings.json updated to use wrapper
|
|
160
|
+
- [x] Hook no longer causes errors on non-markdown files
|