safeword 0.1.0 → 0.2.0

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.
Files changed (57) hide show
  1. package/dist/{check-J6DFVBCE.js → check-FHNTC46G.js} +2 -2
  2. package/dist/check-FHNTC46G.js.map +1 -0
  3. package/dist/chunk-2XWIUEQK.js +190 -0
  4. package/dist/chunk-2XWIUEQK.js.map +1 -0
  5. package/dist/{chunk-UQMQ64CB.js → chunk-GZRQL3SX.js} +41 -2
  6. package/dist/chunk-GZRQL3SX.js.map +1 -0
  7. package/dist/cli.js +5 -5
  8. package/dist/{diff-U4IELWRL.js → diff-SPJ7BJBG.js} +31 -28
  9. package/dist/diff-SPJ7BJBG.js.map +1 -0
  10. package/dist/{reset-XETOHTCK.js → reset-3ACTIYYE.js} +44 -27
  11. package/dist/reset-3ACTIYYE.js.map +1 -0
  12. package/dist/{setup-CLDCHROZ.js → setup-ANC3NUOC.js} +76 -47
  13. package/dist/setup-ANC3NUOC.js.map +1 -0
  14. package/dist/{upgrade-DOKWRK7J.js → upgrade-3KVLLNDF.js} +37 -49
  15. package/dist/upgrade-3KVLLNDF.js.map +1 -0
  16. package/package.json +1 -1
  17. package/templates/SAFEWORD.md +776 -0
  18. package/templates/commands/arch-review.md +24 -0
  19. package/templates/commands/lint.md +11 -0
  20. package/templates/commands/quality-review.md +23 -0
  21. package/templates/doc-templates/architecture-template.md +136 -0
  22. package/templates/doc-templates/design-doc-template.md +134 -0
  23. package/templates/doc-templates/test-definitions-feature.md +131 -0
  24. package/templates/doc-templates/user-stories-template.md +92 -0
  25. package/templates/guides/architecture-guide.md +423 -0
  26. package/templates/guides/code-philosophy.md +195 -0
  27. package/templates/guides/context-files-guide.md +457 -0
  28. package/templates/guides/data-architecture-guide.md +200 -0
  29. package/templates/guides/design-doc-guide.md +171 -0
  30. package/templates/guides/learning-extraction.md +552 -0
  31. package/templates/guides/llm-instruction-design.md +248 -0
  32. package/templates/guides/llm-prompting.md +102 -0
  33. package/templates/guides/tdd-best-practices.md +615 -0
  34. package/templates/guides/test-definitions-guide.md +334 -0
  35. package/templates/guides/testing-methodology.md +618 -0
  36. package/templates/guides/user-story-guide.md +256 -0
  37. package/templates/guides/zombie-process-cleanup.md +219 -0
  38. package/templates/hooks/agents-md-check.sh +27 -0
  39. package/templates/hooks/inject-timestamp.sh +2 -3
  40. package/templates/hooks/post-tool.sh +4 -0
  41. package/templates/hooks/pre-commit.sh +10 -0
  42. package/templates/lib/common.sh +26 -0
  43. package/templates/lib/jq-fallback.sh +20 -0
  44. package/templates/markdownlint.jsonc +25 -0
  45. package/templates/prompts/arch-review.md +43 -0
  46. package/templates/prompts/quality-review.md +10 -0
  47. package/templates/skills/safeword-quality-reviewer/SKILL.md +207 -0
  48. package/dist/check-J6DFVBCE.js.map +0 -1
  49. package/dist/chunk-24OB57NJ.js +0 -78
  50. package/dist/chunk-24OB57NJ.js.map +0 -1
  51. package/dist/chunk-DB4CMUFD.js +0 -157
  52. package/dist/chunk-DB4CMUFD.js.map +0 -1
  53. package/dist/chunk-UQMQ64CB.js.map +0 -1
  54. package/dist/diff-U4IELWRL.js.map +0 -1
  55. package/dist/reset-XETOHTCK.js.map +0 -1
  56. package/dist/setup-CLDCHROZ.js.map +0 -1
  57. package/dist/upgrade-DOKWRK7J.js.map +0 -1
@@ -0,0 +1,256 @@
1
+ # User Story Guide for Claude Code
2
+
3
+ ## How to Fill Out Feature User Stories
4
+
5
+ **Template:** `@.safeword/templates/user-stories-template.md`
6
+
7
+ **When user asks:** "Create user stories for issue #N" or "Create user stories for [feature]"
8
+
9
+ **What you do:**
10
+
11
+ 1. Read `@.safeword/templates/user-stories-template.md`
12
+ 2. Fill in feature name, issue number, status
13
+ 3. Create numbered stories (Story 1, Story 2, etc.)
14
+ 4. Add acceptance criteria with ✅/❌ checkboxes for tracking
15
+ 5. Include test file references
16
+ 6. Add summary with completion % and phases
17
+ 7. Save to project location (e.g., `planning/user-stories/45-feature-name.md`)
18
+
19
+ **DO include:**
20
+
21
+ - Status tracking (✅/❌ per story and AC)
22
+ - Test file references
23
+ - Implementation status
24
+ - Completion percentage
25
+ - Phase tracking
26
+ - Next steps
27
+
28
+ ---
29
+
30
+ ## INVEST Validation (Do This Before Saving)
31
+
32
+ After filling out story, mentally check:
33
+
34
+ ✅ **Independent** - Can be done without other stories?
35
+ ✅ **Negotiable** - Are details left for conversation?
36
+ ✅ **Valuable** - Does "So that" clearly state value?
37
+ ✅ **Estimable** - Can team estimate this (1-5 days)?
38
+ ✅ **Small** - Completable in one sprint?
39
+ ✅ **Testable** - Are acceptance criteria specific?
40
+
41
+ **If ANY check fails → Refine or split the story**
42
+
43
+ ---
44
+
45
+ ## Writing Good Acceptance Criteria
46
+
47
+ **✅ GOOD - Specific, user-facing, testable:**
48
+
49
+ - User can switch campaigns without page reload
50
+ - Response time is under 200ms
51
+ - Current campaign is visually highlighted
52
+ - Error message explains what went wrong
53
+
54
+ **❌ BAD - Vague, technical, or implementation:**
55
+
56
+ - Campaign switching works ← Too vague
57
+ - Use Zustand for state ← Implementation detail
58
+ - Database is fast ← Not user-facing
59
+ - Code is clean ← Not testable
60
+
61
+ ---
62
+
63
+ ## Size Guidelines
64
+
65
+ | Indicator | Too Big | Just Right | Too Small |
66
+ | ------------------- | ------- | ---------- | --------- |
67
+ | Acceptance Criteria | 6+ | 1-5 | 0 |
68
+ | Personas/Screens | 3+ | 1-2 | N/A |
69
+ | Duration | 6+ days | 1-5 days | <1 hour |
70
+ | **Action** | Split | ✅ Ship | Combine |
71
+
72
+ **Decision rule:** When borderline (e.g., 5 AC but 2 personas), err on the side of splitting. Smaller stories are easier to estimate and complete.
73
+
74
+ ---
75
+
76
+ ## Examples
77
+
78
+ ### ✅ GOOD Story
79
+
80
+ **As a** player with multiple campaigns
81
+ **I want** to switch between campaigns from the sidebar
82
+ **So that** I can quickly resume different games
83
+
84
+ **Acceptance Criteria:**
85
+
86
+ - [ ] Sidebar shows all campaigns with last-played date
87
+ - [ ] Clicking campaign loads it within 200ms
88
+ - [ ] Current campaign is highlighted
89
+
90
+ ### ❌ BAD Story (Too Big)
91
+
92
+ **As a** user
93
+ **I want** a complete campaign management system
94
+ **So that** I can organize my games
95
+
96
+ **Acceptance Criteria:**
97
+
98
+ - [ ] Create, edit, delete campaigns
99
+ - [ ] Share campaigns with other players
100
+ - [ ] Export/import campaign data
101
+ - [ ] Search and filter campaigns
102
+ - [ ] Tag campaigns by theme
103
+
104
+ **Problem:** This is 5+ separate stories. Split it.
105
+
106
+ ### ❌ BAD Story (No Value)
107
+
108
+ **As a** developer
109
+ **I want** to refactor the GameStore
110
+ **So that** code is cleaner
111
+
112
+ **Problem:**
113
+
114
+ - Developer is not a user
115
+ - "Cleaner code" is not user-facing value
116
+ - This is a technical task, not a user story
117
+
118
+ ### ✅ BETTER (Technical Story)
119
+
120
+ **Technical Task:** Refactor GameStore to use Immer
121
+
122
+ **Why:** Prevent state mutation bugs (3 bugs in last sprint)
123
+ **Effort:** 2-3 hours
124
+ **Test:** All existing tests pass, no new mutations
125
+
126
+ ---
127
+
128
+ ## Conversation Starter, Not Contract
129
+
130
+ **Remember:** User story is a placeholder for conversation.
131
+
132
+ **During planning, discuss:**
133
+
134
+ - Edge cases not in acceptance criteria
135
+ - Technical approach (but don't document it in story)
136
+ - Open questions or dependencies
137
+ - How to split if too big
138
+
139
+ **The story should NOT contain:**
140
+
141
+ - Technical implementation details
142
+ - Test strategies
143
+ - UI mockups (link to them instead)
144
+ - Definition of done (that's team-wide)
145
+
146
+ ---
147
+
148
+ ## Technical Constraints Section
149
+
150
+ **Purpose:** Capture non-functional requirements that inform test definitions. These are NOT user stories but constrain how stories are implemented.
151
+
152
+ **When to use:** Fill in constraints BEFORE writing test definitions. Delete sections that don't apply—keep it lean.
153
+
154
+ ### Categories
155
+
156
+ | Category | What It Captures | Examples |
157
+ | -------------- | -------------------------------- | ----------------------------------------------- |
158
+ | Performance | Speed, throughput, capacity | Response time < 200ms, 1000 concurrent users |
159
+ | Security | Auth, validation, rate limiting | Sanitized inputs, session required, 100 req/min |
160
+ | Compatibility | Browsers, devices, accessibility | Chrome 100+, iOS 14+, WCAG 2.1 AA |
161
+ | Data | Privacy, retention, compliance | GDPR delete in 72h, 90-day log retention |
162
+ | Dependencies | Existing systems, restrictions | Use AuthService, no new packages |
163
+ | Infrastructure | Resources, offline, deployment | < 512MB memory, offline-capable |
164
+
165
+ ### ✅ GOOD Constraints (Specific, Testable)
166
+
167
+ ```markdown
168
+ ### Performance
169
+
170
+ - [ ] API response < 200ms at P95 under 100 concurrent users
171
+ - [ ] Initial page load < 3s on simulated 3G
172
+
173
+ ### Security
174
+
175
+ - [ ] All user inputs sanitized via DOMPurify
176
+ - [ ] Rate limited: 100 requests/min per IP
177
+ ```
178
+
179
+ ### ❌ BAD Constraints (Vague, Untestable)
180
+
181
+ ```markdown
182
+ ### Performance
183
+
184
+ - [ ] Should be fast ← How fast? Under what conditions?
185
+ - [ ] Good performance ← Not measurable
186
+
187
+ ### Security
188
+
189
+ - [ ] Secure ← What does this mean?
190
+ - [ ] Protected from hackers ← Not specific
191
+ ```
192
+
193
+ ### Decision Rule
194
+
195
+ **Include a constraint if:**
196
+
197
+ - It affects how you write tests (performance tests, security tests)
198
+ - It limits implementation choices (must use X, can't use Y)
199
+ - Violating it would fail an audit or break SLAs
200
+
201
+ **Skip if:**
202
+
203
+ - It's a project-wide standard already in ARCHITECTURE.md
204
+ - It's obvious (don't document "code must compile")
205
+
206
+ ### Tie-Breaking
207
+
208
+ **If constraint fits multiple categories:** Choose the most specific one.
209
+
210
+ | Constraint | Could Fit | Best Category | Why |
211
+ | -------------------------- | ----------------------------- | -------------- | ------------------------------- |
212
+ | API rate limit 100 req/min | Security, Performance | Security | Rate limiting is access control |
213
+ | Page load < 3s on 3G | Performance, Compatibility | Performance | Speed is primary concern |
214
+ | Must work offline | Infrastructure, Compatibility | Infrastructure | Offline is deployment concern |
215
+
216
+ **Edge case:** If truly cross-cutting (e.g., "GDPR compliance" spans Data + Security), pick one and add a note: "See also: Security constraints"
217
+
218
+ ---
219
+
220
+ ## LLM Optimization Tips
221
+
222
+ **Core principle:** User stories are instructions that LLMs read and follow. Apply LLM instruction design best practices.
223
+
224
+ **See:** `@.safeword/guides/llm-instruction-design.md` for comprehensive framework on writing LLM-consumable documentation.
225
+
226
+ **When filling templates:**
227
+
228
+ - Use specific, concrete language (not vague)
229
+ - Avoid generic phrases ("improve UX", "make better")
230
+ - Include numbers where relevant (200ms, 3 items, under 5 clicks)
231
+ - Use concrete examples over abstract rules
232
+ - Define all terms explicitly
233
+ - Write for humans, not robots
234
+
235
+ **Token efficiency:**
236
+
237
+ - Template is 9 lines (minimal prompt caching cost)
238
+ - No nested sections (flat structure)
239
+ - No validation metadata in file
240
+
241
+ ---
242
+
243
+ ## File Naming Convention
244
+
245
+ Save stories as: `.safeword/planning/user-stories/[slug].md`
246
+
247
+ **Good filenames:**
248
+
249
+ - `campaign-switching.md`
250
+ - `export-character-pdf.md`
251
+ - `stress-tracking.md`
252
+
253
+ **Bad filenames:**
254
+
255
+ - `user-story-1.md` ← Not descriptive
256
+ - `STORY_CAMPAIGN_SWITCHING_FINAL_v2.md` ← Bloated
@@ -0,0 +1,219 @@
1
+ # Zombie Process Cleanup (Multi-Project Environments)
2
+
3
+ **When to use:** Working on multiple projects simultaneously, especially when they share tech stacks (Next.js, Playwright, etc.)
4
+
5
+ ---
6
+
7
+ ## The Problem
8
+
9
+ When running dev servers and E2E tests across multiple projects, zombie processes accumulate:
10
+
11
+ - Dev servers holding ports
12
+ - Playwright browser instances
13
+ - Test runners stuck in background
14
+ - Build processes from previous sessions
15
+
16
+ **CRITICAL:** NEVER use `killall node` or `pkill -9 node` when working on multiple projects - this kills processes from ALL projects.
17
+
18
+ ---
19
+
20
+ ## Port-Based Cleanup (Safest for Multi-Project)
21
+
22
+ **Prerequisite:** Each project must use a different port (e.g., Project A: 3000, Project B: 3001)
23
+
24
+ **Port convention:** Dev and test instances use different ports within the same project:
25
+
26
+ - **Dev port**: Project's configured port (e.g., 3000, 5173, 8080) - manual testing
27
+ - **Test port**: Dev port + 1000 (e.g., 4000, 6173, 9080) - Playwright managed
28
+
29
+ See `testing-methodology.md` → "E2E Testing with Persistent Dev Servers" for full port isolation strategy.
30
+
31
+ **Decision rule:** If unsure which cleanup method to use → port-based first (safest), then project script, then tmux.
32
+
33
+ **Recommended cleanup pattern** (replace ports with your project's ports):
34
+
35
+ ```bash
36
+ # Kill both dev server AND test server ports
37
+ # Example: Next.js (3000/4000), Vite (5173/6173), or your project's ports
38
+ lsof -ti:3000 -ti:4000 | xargs kill -9 2>/dev/null
39
+
40
+ # Kill Playwright processes launched from THIS directory
41
+ pkill -f "playwright.*$(pwd)" 2>/dev/null
42
+
43
+ # Wait for cleanup
44
+ sleep 2
45
+ ```
46
+
47
+ **Why this works:**
48
+
49
+ - ✅ Dev + test ports are unique to this project → safe to kill
50
+ - ✅ `$(pwd)` ensures only THIS project's tests are killed
51
+ - ✅ Other projects completely untouched
52
+
53
+ ---
54
+
55
+ ## Project-Specific Cleanup Script
56
+
57
+ For frequent cleanup needs, create `scripts/cleanup.sh` in each project:
58
+
59
+ ```bash
60
+ #!/bin/bash
61
+ # scripts/cleanup.sh - Kill only THIS project's processes
62
+
63
+ DEV_PORT=3000 # Dev server port (change per project)
64
+ TEST_PORT=$((DEV_PORT + 1000)) # Test server port (Playwright managed)
65
+ PROJECT_DIR="$(pwd)"
66
+
67
+ echo "Cleaning up $PROJECT_DIR (dev: $DEV_PORT, test: $TEST_PORT)..."
68
+
69
+ # Kill both dev and test servers by port
70
+ lsof -ti:$DEV_PORT -ti:$TEST_PORT | xargs kill -9 2>/dev/null
71
+
72
+ # Kill Playwright browsers for this project
73
+ ps aux | grep -E "(playwright|chromium)" | grep "$PROJECT_DIR" | grep -v grep | awk '{print $2}' | xargs kill -9 2>/dev/null
74
+
75
+ # Kill test runners
76
+ pgrep -f "playwright test.*$(basename $PROJECT_DIR)" | xargs kill -9 2>/dev/null
77
+
78
+ echo "Cleanup complete!"
79
+ ```
80
+
81
+ **Make executable:** `chmod +x scripts/cleanup.sh`
82
+
83
+ **Usage:** `./scripts/cleanup.sh`
84
+
85
+ ---
86
+
87
+ ## Common Patterns by Tech Stack
88
+
89
+ ### Next.js Projects
90
+
91
+ ```bash
92
+ # Kill Next.js dev server (port 3000)
93
+ lsof -ti:3000 | xargs kill -9 2>/dev/null
94
+
95
+ # Kill Next.js build processes for this project
96
+ ps aux | grep "next dev" | grep "$(pwd)" | grep -v grep | awk '{print $2}' | xargs kill -9 2>/dev/null
97
+ ```
98
+
99
+ ### Playwright E2E Tests
100
+
101
+ ```bash
102
+ # Kill Playwright browsers and test runners
103
+ pkill -f "playwright.*$(pwd)" 2>/dev/null
104
+
105
+ # Or more specific (by project name)
106
+ pkill -f "playwright.*my-project-name" 2>/dev/null
107
+ ```
108
+
109
+ ### Vite Projects
110
+
111
+ ```bash
112
+ # Kill Vite dev server (typically port 5173)
113
+ lsof -ti:5173 | xargs kill -9 2>/dev/null
114
+ ```
115
+
116
+ ### React Native / Expo
117
+
118
+ ```bash
119
+ # Kill Metro bundler (port 8081)
120
+ lsof -ti:8081 | xargs kill -9 2>/dev/null
121
+
122
+ # Kill Expo dev tools (port 19000-19006)
123
+ lsof -ti:19000-19006 | xargs kill -9 2>/dev/null
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Alternative: tmux/Screen Sessions
129
+
130
+ For complete isolation, run each project in its own terminal session:
131
+
132
+ ```bash
133
+ # Start project in named session
134
+ tmux new -s project-name
135
+ # Run dev server here
136
+
137
+ # Kill everything in this session only
138
+ tmux kill-session -t project-name
139
+ ```
140
+
141
+ **Pros:**
142
+
143
+ - ✅ Complete isolation between projects
144
+ - ✅ One command kills everything
145
+ - ✅ Can detach/reattach sessions
146
+
147
+ **Cons:**
148
+
149
+ - ⚠️ Requires learning tmux
150
+ - ⚠️ Different workflow
151
+
152
+ ---
153
+
154
+ ## Best Practices
155
+
156
+ 1. **Assign unique ports** - Set `PORT=3000` in one project, `PORT=3001` in another
157
+ 2. **Use port-based cleanup first** - Simplest and safest
158
+ 3. **Create project cleanup scripts** - Reusable, documented
159
+ 4. **Never `killall node`** - Too broad when working on multiple projects
160
+ 5. **Clean up before starting** - Run cleanup script before `npm run dev`
161
+ 6. **Check what's running** - Use `lsof -i:PORT` to see what's using a port
162
+
163
+ ---
164
+
165
+ ## Debugging Zombie Processes
166
+
167
+ ### Find What's Using a Port
168
+
169
+ ```bash
170
+ # Check what's on port 3000
171
+ lsof -i:3000
172
+
173
+ # More details
174
+ lsof -i:3000 -P -n
175
+ ```
176
+
177
+ ### Find All Node Processes
178
+
179
+ ```bash
180
+ # List all node processes
181
+ ps aux | grep -E "(node|playwright|chromium)"
182
+
183
+ # More detailed (with working directory)
184
+ lsof -p $(pgrep node) | grep cwd
185
+ ```
186
+
187
+ ### Find Processes by Project Directory
188
+
189
+ ```bash
190
+ # Find processes running in specific directory
191
+ ps aux | grep "/Users/alex/projects/my-project"
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Quick Reference
197
+
198
+ | Situation | Command |
199
+ | ---------------------------------------- | ---------------------------------------------------------------- |
200
+ | Kill dev + test servers (use your ports) | `lsof -ti:$DEV_PORT -ti:$TEST_PORT \| xargs kill -9 2>/dev/null` |
201
+ | Kill Playwright (this project) | `pkill -f "playwright.*$(pwd)"` |
202
+ | Kill all for this project | `./scripts/cleanup.sh` |
203
+ | Check what's on port | `lsof -i:3000` |
204
+ | Find zombie processes | `ps aux \| grep -E "(node\|playwright\|chromium)"` |
205
+ | Kill by process ID | `kill -9 <PID>` |
206
+
207
+ ---
208
+
209
+ ## What NOT to Do
210
+
211
+ ❌ **DON'T:** `killall node` (kills all projects)
212
+ ❌ **DON'T:** `pkill -9 node` (kills all projects)
213
+ ❌ **DON'T:** Kill processes without checking working directory
214
+ ❌ **DON'T:** Assume zombie browsers will clean themselves up (they won't)
215
+
216
+ ✅ **DO:** Use port-based cleanup
217
+ ✅ **DO:** Filter by project directory with `$(pwd)`
218
+ ✅ **DO:** Create project-specific cleanup scripts
219
+ ✅ **DO:** Clean up before AND after development sessions
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+ # Safeword AGENTS.md self-healing hook
3
+ # Ensures the AGENTS.md link is always present
4
+
5
+ LINK='**⚠️ ALWAYS READ FIRST: @./.safeword/SAFEWORD.md**'
6
+
7
+ if [ ! -d ".safeword" ]; then
8
+ # Not a safeword project, skip
9
+ exit 0
10
+ fi
11
+
12
+ if [ ! -f "AGENTS.md" ]; then
13
+ # AGENTS.md doesn't exist, create it
14
+ echo "$LINK" > AGENTS.md
15
+ echo "SAFEWORD: Created AGENTS.md with safeword link"
16
+ exit 0
17
+ fi
18
+
19
+ # Check if link is present
20
+ if ! grep -q "@./.safeword/SAFEWORD.md" AGENTS.md; then
21
+ # Link missing, prepend it
22
+ CONTENT=$(cat AGENTS.md)
23
+ echo -e "$LINK\n\n$CONTENT" > AGENTS.md
24
+ echo "SAFEWORD: Restored AGENTS.md link (was removed)"
25
+ fi
26
+
27
+ exit 0
@@ -1,7 +1,6 @@
1
1
  #!/bin/bash
2
- # Inject Timestamp - Notification Hook
3
- # Outputs current Unix timestamp at session start for Claude's context awareness
2
+ # Inject Timestamp - UserPromptSubmit Hook
3
+ # Outputs current Unix timestamp for Claude's context awareness
4
4
  # Helps with accurate ticket timestamps and time-based reasoning
5
5
 
6
6
  echo "Current time: $(date +%s) ($(date -u +%Y-%m-%dT%H:%M:%SZ))"
7
-
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ # Safeword post-tool hook
3
+ # Placeholder for post-tool validations
4
+ exit 0
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+ # Safeword pre-commit hook
3
+ # Runs architecture checks before commit
4
+
5
+ # Run linting if available
6
+ if [ -f "package.json" ] && grep -q '"lint"' package.json; then
7
+ npm run lint --silent || exit 1
8
+ fi
9
+
10
+ exit 0
@@ -0,0 +1,26 @@
1
+ #!/bin/bash
2
+ # Safeword common utilities for hook scripts
3
+
4
+ # Output JSON response for Claude Code hooks
5
+ # Usage: json_response '{"key": "value"}'
6
+ json_response() {
7
+ echo "$1"
8
+ }
9
+
10
+ # Check if running in a safeword project
11
+ is_safeword_project() {
12
+ [ -d ".safeword" ]
13
+ }
14
+
15
+ # Get project root (directory containing .safeword)
16
+ get_project_root() {
17
+ local dir="$PWD"
18
+ while [ "$dir" != "/" ]; do
19
+ if [ -d "$dir/.safeword" ]; then
20
+ echo "$dir"
21
+ return 0
22
+ fi
23
+ dir=$(dirname "$dir")
24
+ done
25
+ return 1
26
+ }
@@ -0,0 +1,20 @@
1
+ #!/bin/bash
2
+ # Fallback JSON output when jq is not available
3
+ # Uses printf for safe JSON string escaping
4
+
5
+ # Escape a string for JSON output
6
+ json_escape() {
7
+ local str="$1"
8
+ str="${str//\\/\\\\}"
9
+ str="${str//\"/\\\"}"
10
+ str="${str//$'\n'/\\n}"
11
+ str="${str//$'\t'/\\t}"
12
+ echo "$str"
13
+ }
14
+
15
+ # Output a simple JSON object with one key-value pair
16
+ json_kv() {
17
+ local key="$1"
18
+ local value="$2"
19
+ printf '{"proposedChanges": false, "madeChanges": false, "askedQuestion": false, "%s": "%s"}\n' "$key" "$(json_escape "$value")"
20
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ // Safeword markdownlint configuration
3
+ "default": true,
4
+
5
+ // Allow inline HTML (needed for some markdown features)
6
+ "MD033": false,
7
+
8
+ // Allow multiple headings with same content
9
+ "MD024": {
10
+ "siblings_only": true
11
+ },
12
+
13
+ // Line length - be lenient
14
+ "MD013": {
15
+ "line_length": 120,
16
+ "code_blocks": false,
17
+ "tables": false
18
+ },
19
+
20
+ // Allow trailing punctuation in headings
21
+ "MD026": false,
22
+
23
+ // Allow emphasis as heading
24
+ "MD036": false
25
+ }
@@ -0,0 +1,43 @@
1
+ # Architecture Review Prompt
2
+
3
+ Review the following code changes for architectural issues.
4
+
5
+ ## Check for:
6
+
7
+ 1. **Misplaced logic** - Business rules in wrong layer?
8
+ 2. **God module** - Too many responsibilities (>10 dependents or >500 lines)?
9
+ 3. **Leaky abstraction** - Implementation details exposed to callers?
10
+ 4. **Tight coupling** - Changes would cascade unnecessarily?
11
+ 5. **Boundary violation** - Import from disallowed layer?
12
+
13
+ ## Context
14
+
15
+ Read the project's ARCHITECTURE.md for:
16
+
17
+ - Defined layers and their responsibilities
18
+ - Allowed dependencies between layers
19
+ - Project-specific patterns and conventions
20
+
21
+ ## Response Format
22
+
23
+ Return JSON:
24
+
25
+ ```json
26
+ {
27
+ "issues": [
28
+ {
29
+ "type": "misplaced_logic | god_module | leaky_abstraction | tight_coupling | boundary_violation",
30
+ "location": "file:line or module name",
31
+ "description": "What's wrong",
32
+ "fix": "How to fix it"
33
+ }
34
+ ],
35
+ "verdict": "clean | minor | refactor_needed"
36
+ }
37
+ ```
38
+
39
+ ### Verdict definitions:
40
+
41
+ - **clean**: No issues found
42
+ - **minor**: Small issues that should be noted but don't block commit
43
+ - **refactor_needed**: Significant issues that should be addressed before commit
@@ -0,0 +1,10 @@
1
+ # Quality Review Prompt
2
+
3
+ Double check and critique your work just in case.
4
+
5
+ - Is it correct?
6
+ - Is it elegant?
7
+ - Does it adhere to the latest documentation and best practices for the relevant stack items, UX principles, domain requirements, and testing practices?
8
+ - Ask me any non-obvious questions you can't research yourself in the codebase or online.
9
+ - Think hard.
10
+ - Avoid bloat.