@massu/core 0.4.0 → 0.4.2
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/commands/_shared-preamble.md +10 -0
- package/commands/massu-batch.md +327 -0
- package/commands/massu-bearings.md +204 -0
- package/commands/massu-ci-fix.md +148 -0
- package/commands/massu-gap-enhancement-analyzer.md +480 -0
- package/commands/massu-hooks.md +111 -0
- package/commands/massu-incident.md +162 -0
- package/commands/massu-plan-audit.md +64 -0
- package/commands/massu-recap.md +164 -0
- package/commands/massu-scaffold-hook.md +96 -0
- package/commands/massu-scaffold-page.md +108 -0
- package/commands/massu-scaffold-router.md +125 -0
- package/commands/massu-squirrels.md +101 -0
- package/dist/cli.js +0 -1
- package/package.json +2 -2
- package/src/cli.ts +0 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-incident
|
|
3
|
+
description: "When a bug is confirmed, a production issue is found, or user reports 'this broke', 'incident', 'production error' — triggers incident documentation protocol"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
name: massu-incident
|
|
7
|
+
|
|
8
|
+
# Massu Incident: Automated Post-Mortem & Prevention Pipeline
|
|
9
|
+
|
|
10
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
11
|
+
|
|
12
|
+
## Objective
|
|
13
|
+
|
|
14
|
+
When a bug is discovered that an audit should have caught, execute a
|
|
15
|
+
structured post-mortem that AUTOMATICALLY:
|
|
16
|
+
1. Logs the incident to INCIDENT-LOG.md
|
|
17
|
+
2. Proposes a new CR rule or VR-* check
|
|
18
|
+
3. Proposes a pattern-scanner addition
|
|
19
|
+
4. Updates relevant protocol files with incident reminder
|
|
20
|
+
|
|
21
|
+
## INPUT
|
|
22
|
+
|
|
23
|
+
User provides: description of what went wrong and how it was discovered.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## STEP 1: CAPTURE INCIDENT DETAILS
|
|
28
|
+
|
|
29
|
+
Gather from user and investigation:
|
|
30
|
+
|
|
31
|
+
```markdown
|
|
32
|
+
### Incident Capture
|
|
33
|
+
- **What happened**: [user-visible bug]
|
|
34
|
+
- **Root cause**: [why it happened]
|
|
35
|
+
- **Discovery**: USER / AUDIT / AUTOMATED
|
|
36
|
+
- **Impact**: [what broke, who was affected]
|
|
37
|
+
- **Files involved**: [list]
|
|
38
|
+
- **Which audit should have caught this**: [massu-plan / massu-loop / massu-commit / etc.]
|
|
39
|
+
- **Why the audit missed it**: [specific reason]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## STEP 2: DETERMINE NEXT INCIDENT NUMBER
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
grep -c "^## Incident #" .claude/incidents/INCIDENT-LOG.md
|
|
46
|
+
# Next number = count + 1
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## STEP 3: LOG TO INCIDENT-LOG.md
|
|
50
|
+
|
|
51
|
+
Append to `.claude/incidents/INCIDENT-LOG.md`:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Incident #[N]: [Short Title]
|
|
55
|
+
|
|
56
|
+
**Date**: [YYYY-MM-DD]
|
|
57
|
+
**Severity**: CRITICAL / HIGH / MEDIUM
|
|
58
|
+
**Discovery**: USER / AUDIT / AUTOMATED
|
|
59
|
+
**Root Cause**: [description]
|
|
60
|
+
**Files Involved**: [list]
|
|
61
|
+
**What Should Have Caught It**: [audit/protocol name]
|
|
62
|
+
**Why It Was Missed**: [reason]
|
|
63
|
+
**Prevention Added**: [CR-XX / VR-XX / pattern-scanner rule]
|
|
64
|
+
**Lesson**: [one-line lesson]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## STEP 4: PROPOSE PREVENTION
|
|
68
|
+
|
|
69
|
+
### 4a: New CR Rule (if pattern is new)
|
|
70
|
+
If the failure mode isn't covered by existing CRs:
|
|
71
|
+
- Propose CR-[N+1] with rule text
|
|
72
|
+
- Add to CLAUDE.md CR table
|
|
73
|
+
|
|
74
|
+
### 4b: New VR-* Check (always)
|
|
75
|
+
Every incident MUST produce a verifiable check:
|
|
76
|
+
- Define the verification command
|
|
77
|
+
- Add to VR table in CLAUDE.md
|
|
78
|
+
- Specify when to run it
|
|
79
|
+
|
|
80
|
+
### 4c: Pattern Scanner Rule (if automatable)
|
|
81
|
+
If the failure can be caught by grep:
|
|
82
|
+
- Add rule to `scripts/pattern-scanner.sh`
|
|
83
|
+
- Test it catches the original failure
|
|
84
|
+
- Verify it doesn't false-positive
|
|
85
|
+
|
|
86
|
+
### 4d: Protocol Update (always)
|
|
87
|
+
Add incident reminder to the protocol that should have caught it:
|
|
88
|
+
- Add `## INCIDENT #[N] REMINDER` section
|
|
89
|
+
- Explain the failure mode
|
|
90
|
+
- Explain what to check for
|
|
91
|
+
|
|
92
|
+
## STEP 5: VERIFY PREVENTION WORKS
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# If pattern-scanner rule added:
|
|
96
|
+
./scripts/pattern-scanner.sh
|
|
97
|
+
|
|
98
|
+
# If VR-* check added, run it:
|
|
99
|
+
[verification command]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## OUTPUT
|
|
103
|
+
|
|
104
|
+
```markdown
|
|
105
|
+
## INCIDENT POST-MORTEM COMPLETE
|
|
106
|
+
|
|
107
|
+
### Incident #[N]: [Title]
|
|
108
|
+
- Logged to: INCIDENT-LOG.md
|
|
109
|
+
- CR rule: [CR-XX added/updated]
|
|
110
|
+
- VR check: [VR-XX added]
|
|
111
|
+
- Pattern scanner: [rule added / not automatable]
|
|
112
|
+
- Protocol updated: [which protocol]
|
|
113
|
+
|
|
114
|
+
### Prevention Chain
|
|
115
|
+
1. Pattern scanner: Will catch at pre-push
|
|
116
|
+
2. Protocol: Explicit reminder in [protocol name]
|
|
117
|
+
3. CR rule: Documented in CLAUDE.md
|
|
118
|
+
4. MEMORY.md: Wrong vs correct pattern recorded for all future sessions
|
|
119
|
+
|
|
120
|
+
**This failure mode is now prevented at 4 levels.**
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## STEP 6: UPDATE MEMORY.md (MANDATORY)
|
|
124
|
+
|
|
125
|
+
Every incident MUST be recorded in `memory/MEMORY.md` with the wrong vs correct pattern:
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
## Critical Rule: CR-[XX] - [Short Title] (Incident #[N], [date])
|
|
129
|
+
- [Wrong pattern description]
|
|
130
|
+
- [Correct pattern description]
|
|
131
|
+
- [Key insight that prevents recurrence]
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This ensures that even without accessing the incident log, future sessions
|
|
135
|
+
will have the pattern in their system prompt via MEMORY.md.
|
|
136
|
+
|
|
137
|
+
## STEP 7: CODEBASE-WIDE SEARCH (CR-9)
|
|
138
|
+
|
|
139
|
+
Search the ENTIRE codebase for the same bad pattern that caused the incident:
|
|
140
|
+
```bash
|
|
141
|
+
grep -rn "[bad_pattern]" src/ --include="*.ts" --include="*.tsx"
|
|
142
|
+
```
|
|
143
|
+
Fix ALL instances found. The incident that triggered this post-mortem
|
|
144
|
+
may not be the only occurrence.
|
|
145
|
+
|
|
146
|
+
## STEP 8: COUPLING CHECK
|
|
147
|
+
|
|
148
|
+
If the incident involved a feature that was implemented but not exposed in the UI, run the coupling check to verify all backend procedures have UI exposure:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
./scripts/check-coupling.sh
|
|
152
|
+
# Expected: Exit 0 (no uncoupled backend features)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Any backend procedure without UI exposure is a hidden feature that cannot be used - fix immediately.**
|
|
156
|
+
|
|
157
|
+
## Gotchas
|
|
158
|
+
|
|
159
|
+
- **Update INCIDENT-LOG.md** — every incident gets a numbered entry in `incidents/INCIDENT-LOG.md` with root cause, prevention, and CR reference
|
|
160
|
+
- **Add CR if pattern emerges** — if the incident reveals a repeatable failure pattern, add a new Canonical Rule to CLAUDE.md
|
|
161
|
+
- **Update pattern scanner** — if the incident could be caught by static analysis, add a check to `scripts/pattern-scanner.sh`
|
|
162
|
+
- **Never blame the user** — incidents are system failures. Frame prevention as system guardrails, not user discipline
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-plan-audit
|
|
3
|
+
description: "When user wants to create a plan AND audit it to zero gaps in one flow, says 'plan audit', 'create and audit plan', or needs the combined create-then-audit workflow"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*), Task(*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Massu Plan-Audit: Autonomous Plan Creation + Zero-Gap Audit
|
|
8
|
+
|
|
9
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
10
|
+
|
|
11
|
+
## Workflow Position
|
|
12
|
+
This command COMBINES /massu-create-plan + /massu-plan into ONE uninterrupted flow.
|
|
13
|
+
**DISTINCT FROM**: `/massu-plan` (audit-only loop) and `/massu-create-plan` (plan creation only). This command is the autonomous combination of both.
|
|
14
|
+
|
|
15
|
+
## What This Command Does
|
|
16
|
+
1. Phase A: Create the plan (follows massu-create-plan protocol)
|
|
17
|
+
2. Phase B: IMMEDIATELY transition to audit loop (follows massu-plan protocol)
|
|
18
|
+
3. Phase C: Loop until zero gaps (no user intervention needed)
|
|
19
|
+
4. Phase D: Present zero-gap plan to user and STOP
|
|
20
|
+
|
|
21
|
+
## CRITICAL: NO MODE CONFUSION
|
|
22
|
+
- Do NOT enter plan mode. Work in normal mode throughout.
|
|
23
|
+
- Do NOT ask user "should I audit now?" — just do it.
|
|
24
|
+
- Do NOT exit early after plan creation — audit is MANDATORY.
|
|
25
|
+
- The ONLY stopping point is after a clean zero-gap audit pass.
|
|
26
|
+
|
|
27
|
+
## Execution Protocol
|
|
28
|
+
|
|
29
|
+
### Phase A: Plan Creation
|
|
30
|
+
1. Parse $ARGUMENTS as task description
|
|
31
|
+
2. Follow massu-create-plan Phase 1-6 (requirements, DB check, codebase check, patterns, security, generation)
|
|
32
|
+
3. Write plan document to `.claude/plans/[date]-[name].md`
|
|
33
|
+
4. Do NOT present plan to user yet — proceed directly to Phase B
|
|
34
|
+
|
|
35
|
+
### Phase B: Audit Loop (IMMEDIATE — no pause)
|
|
36
|
+
5. Spawn massu-plan-auditor subagent for audit iteration 1
|
|
37
|
+
6. Parse GAPS_DISCOVERED from result
|
|
38
|
+
7. If gaps > 0: fix plan document, spawn another iteration
|
|
39
|
+
8. If gaps == 0: proceed to Phase C
|
|
40
|
+
9. Maximum 10 iterations
|
|
41
|
+
|
|
42
|
+
### Phase C: Present to User
|
|
43
|
+
10. Output plan summary with zero-gap certification
|
|
44
|
+
11. STOP and WAIT for user to run /massu-loop
|
|
45
|
+
|
|
46
|
+
## Rules
|
|
47
|
+
| Rule | Meaning |
|
|
48
|
+
|------|---------|
|
|
49
|
+
| No plan mode | Stay in normal mode throughout |
|
|
50
|
+
| No pauses between phases | A→B transition is automatic |
|
|
51
|
+
| Audit is mandatory | Creating plan without auditing = INCOMPLETE |
|
|
52
|
+
| Zero gaps required | Only zero-gap plan is presentable |
|
|
53
|
+
| Max 10 audit iterations | Bail and report if not converging |
|
|
54
|
+
| **VR-SPEC-MATCH** | For EVERY plan item with specific CSS classes, component names, layout instructions, or visual specs — the plan MUST include those EXACT strings as verifiable specs. If a plan item says "add a sidebar" without specifying classes/structure, that is a specificity gap. |
|
|
55
|
+
|
|
56
|
+
## Literal Spec Verification (Auditor Instruction)
|
|
57
|
+
|
|
58
|
+
**MANDATORY during every audit pass**: For EVERY plan item that contains specific CSS classes, component names, layout instructions, or visual specifications:
|
|
59
|
+
|
|
60
|
+
1. **Extract** the literal strings from the plan item (e.g., `ml-6`, `border-l-2`, `grid-cols-3`, `<Badge variant="outline">`)
|
|
61
|
+
2. **If auditing a plan document (pre-implementation)**: Verify each item has enough literal spec detail to enable VR-SPEC-MATCH during implementation. If an item says "add a card" but doesn't specify classes → **SPECIFICITY GAP**
|
|
62
|
+
3. **If auditing implementation (post-implementation)**: Grep the implementation files for those EXACT strings. Missing string = **VR-SPEC-MATCH failure = gap**
|
|
63
|
+
|
|
64
|
+
This prevents the failure mode where plans specify visual requirements loosely and implementations diverge from intent.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-recap
|
|
3
|
+
description: "When user says 'done for today', 'wrapping up', 'end session', 'handoff', or is about to close the terminal"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
name: massu-recap
|
|
7
|
+
|
|
8
|
+
# Massu Recap: Session Handoff
|
|
9
|
+
|
|
10
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Answer one question: **"What happened this session and what does the next session need to know?"**
|
|
17
|
+
|
|
18
|
+
This command captures the current session's work, updates session state, and ensures nothing is lost before the session ends. It is the counterpart to `/massu-bearings` — recap writes the handoff note that bearings reads tomorrow.
|
|
19
|
+
|
|
20
|
+
**Privilege level**: Level 1.5 (reads state + writes to session-state files only, no code changes).
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Data Sources
|
|
25
|
+
|
|
26
|
+
Read these to build the session summary:
|
|
27
|
+
|
|
28
|
+
| # | Source | What to extract |
|
|
29
|
+
|---|--------|----------------|
|
|
30
|
+
| 1 | `session-state/CURRENT.md` | What was planned, active task |
|
|
31
|
+
| 2 | `git log --since="6am" --oneline` | Commits made this session |
|
|
32
|
+
| 3 | `git diff --stat` | Uncommitted changes |
|
|
33
|
+
| 4 | `session-state/squirrels.md` | Ideas parked during session |
|
|
34
|
+
| 5 | `.claude/plans/*.md` | Plan progress (items completed vs total) |
|
|
35
|
+
| 6 | `memory/MEMORY.md` | Whether memory was updated this session |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Actions (Execute in Order)
|
|
40
|
+
|
|
41
|
+
### Step 1: Generate Session Summary
|
|
42
|
+
|
|
43
|
+
Present to terminal:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
47
|
+
RECAP — [date]
|
|
48
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
49
|
+
|
|
50
|
+
WHAT GOT DONE
|
|
51
|
+
- [commit hash] [message]
|
|
52
|
+
- [commit hash] [message]
|
|
53
|
+
- [non-committed work: files changed, what was done]
|
|
54
|
+
(or "No commits this session")
|
|
55
|
+
|
|
56
|
+
WHAT'S STILL OPEN
|
|
57
|
+
- [incomplete item 1 — status/progress]
|
|
58
|
+
- [incomplete item 2]
|
|
59
|
+
(or "All planned work completed")
|
|
60
|
+
|
|
61
|
+
NEW DISCOVERIES
|
|
62
|
+
- [issue found but not yet addressed]
|
|
63
|
+
- [pattern violation noticed]
|
|
64
|
+
(or "None")
|
|
65
|
+
|
|
66
|
+
SQUIRRELS ADDED ([N] new)
|
|
67
|
+
- [idea 1]
|
|
68
|
+
(or "No new squirrels this session")
|
|
69
|
+
|
|
70
|
+
UNCOMMITTED CHANGES
|
|
71
|
+
[git diff --stat output or "Working tree clean"]
|
|
72
|
+
|
|
73
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 2: Memory Persistence Check
|
|
77
|
+
|
|
78
|
+
Check whether significant work was done this session:
|
|
79
|
+
|
|
80
|
+
| Signal | Indicates significant work |
|
|
81
|
+
|--------|---------------------------|
|
|
82
|
+
| Commits made | Yes |
|
|
83
|
+
| Plan items completed | Yes |
|
|
84
|
+
| Bugs fixed | Yes |
|
|
85
|
+
| New patterns discovered | Yes |
|
|
86
|
+
| User corrections received | Yes |
|
|
87
|
+
| Architecture decisions made | Yes |
|
|
88
|
+
|
|
89
|
+
If significant work detected:
|
|
90
|
+
```
|
|
91
|
+
MEMORY CHECK
|
|
92
|
+
Significant work detected: [list signals]
|
|
93
|
+
Memory updated this session: YES / NO
|
|
94
|
+
|
|
95
|
+
[If NO]: You should persist key learnings to memory/ before ending.
|
|
96
|
+
Suggested memory writes:
|
|
97
|
+
- [topic]: [what to record]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If no significant work: skip this section.
|
|
101
|
+
|
|
102
|
+
### Step 3: Update Session State
|
|
103
|
+
|
|
104
|
+
Update `session-state/CURRENT.md` with:
|
|
105
|
+
- Final status of the session's work
|
|
106
|
+
- Any open items carrying forward
|
|
107
|
+
- Failed approaches (if any)
|
|
108
|
+
- Next steps for the next session
|
|
109
|
+
|
|
110
|
+
### Step 4: Archive Decision
|
|
111
|
+
|
|
112
|
+
If the active task in CURRENT.md is fully complete:
|
|
113
|
+
- Ask user: "Task [name] appears complete. Archive session state? (yes/no)"
|
|
114
|
+
- If yes: `mv session-state/CURRENT.md session-state/archive/YYYY-MM-DD-[desc].md`
|
|
115
|
+
- Create fresh CURRENT.md for next session
|
|
116
|
+
- If no: leave CURRENT.md as-is
|
|
117
|
+
|
|
118
|
+
If the task is still in progress:
|
|
119
|
+
- Do NOT archive — just update CURRENT.md with current state
|
|
120
|
+
- Do NOT ask about archiving
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## What Recap Does NOT Do
|
|
125
|
+
|
|
126
|
+
- Does NOT commit code (use `/massu-commit`)
|
|
127
|
+
- Does NOT push to remote (use `/massu-push`)
|
|
128
|
+
- Does NOT modify source code or configuration
|
|
129
|
+
- Does NOT auto-promote squirrels (that requires explicit `/massu-squirrels promote`)
|
|
130
|
+
- Does NOT write to memory/ files directly (it reminds you to, but doesn't do it for you)
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Edge Cases
|
|
135
|
+
|
|
136
|
+
- **No CURRENT.md**: Create one with the session summary as the initial content
|
|
137
|
+
- **No commits today**: Focus on uncommitted changes and discoveries
|
|
138
|
+
- **No squirrels.md**: Skip the squirrels section
|
|
139
|
+
- **Multiple sessions in one day**: Use `git log --since="6am"` to capture the current session (adjust if user started later)
|
|
140
|
+
- **Session was just reading/research**: Still worth a recap — record what was learned and any decisions made
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Recap History
|
|
145
|
+
|
|
146
|
+
After presenting the recap output, append a JSONL line to `.claude/metrics/recap-history.jsonl`:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{"timestamp":"ISO","session_duration_approx":"3h","commits":2,"plans_completed":1,"incidents":0,"memories_written":3}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
On next recap, read last 3 entries from `recap-history.jsonl` to compare session productivity. If no history file exists, skip comparisons.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## START NOW
|
|
157
|
+
|
|
158
|
+
1. Read all data sources in parallel
|
|
159
|
+
2. Generate and present the session summary
|
|
160
|
+
3. Run the memory persistence check
|
|
161
|
+
4. Update CURRENT.md with final state
|
|
162
|
+
5. Append recap-history.jsonl entry
|
|
163
|
+
6. If task is complete, ask about archiving
|
|
164
|
+
7. Confirm: "Recap complete. Ready for next session."
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-scaffold-hook
|
|
3
|
+
description: "When user wants to create a new Claude Code hook — scaffolds the hook script, adds to settings.json, sets up profile gating"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Scaffold New Hook
|
|
8
|
+
|
|
9
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
10
|
+
|
|
11
|
+
Creates a complete Claude Code hook following the 3-tier profile system.
|
|
12
|
+
|
|
13
|
+
## What Gets Created
|
|
14
|
+
|
|
15
|
+
| File | Purpose |
|
|
16
|
+
|------|---------|
|
|
17
|
+
| `scripts/hooks/[hook-name].sh` | Hook script |
|
|
18
|
+
| Entry in `.claude/settings.json` | Hook registration under lifecycle event |
|
|
19
|
+
|
|
20
|
+
## Hook Lifecycle Events
|
|
21
|
+
|
|
22
|
+
| Event | Fires When | Use For |
|
|
23
|
+
|-------|-----------|---------|
|
|
24
|
+
| `PreToolUse` | Before a tool runs | Blocking destructive ops, validation, logging |
|
|
25
|
+
| `PostToolUse` | After a tool runs | Auditing, pattern scanning, metrics |
|
|
26
|
+
| `SessionStart` | Session starts/resumes/compacts | Context injection, state loading |
|
|
27
|
+
|
|
28
|
+
## Template — Hook Script
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
#!/usr/bin/env bash
|
|
32
|
+
# [Hook Name] — [brief description]
|
|
33
|
+
# Profile: [minimal|standard|strict]
|
|
34
|
+
source "$(dirname "$0")/hook-gate.sh" [tier] [hook-name] 2>/dev/null || true
|
|
35
|
+
set -euo pipefail
|
|
36
|
+
|
|
37
|
+
# Read tool input from stdin
|
|
38
|
+
TOOL_INPUT=$(cat)
|
|
39
|
+
|
|
40
|
+
# Extract relevant fields (adapt per event type)
|
|
41
|
+
# For PreToolUse: tool_input contains the tool's parameters
|
|
42
|
+
# For PostToolUse: tool_input contains tool output + parameters
|
|
43
|
+
|
|
44
|
+
# Your hook logic here
|
|
45
|
+
|
|
46
|
+
# Output options:
|
|
47
|
+
# - Exit 0 silently (no feedback)
|
|
48
|
+
# - Echo JSON for structured feedback:
|
|
49
|
+
# echo '{"decision":"block","reason":"..."}' (PreToolUse only)
|
|
50
|
+
# echo '{"message":"..."}' (advisory feedback)
|
|
51
|
+
|
|
52
|
+
exit 0
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Template — settings.json Entry
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"matcher": "ToolName|OtherTool",
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "PROFILE=${LIMN_HOOK_PROFILE:-strict}; [ \"$PROFILE\" = \"minimal\" ] && exit 0; bash \"$CLAUDE_PROJECT_DIR/scripts/hooks/hook-name.sh\""
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Profile Tiers
|
|
70
|
+
|
|
71
|
+
| Tier | When to Use | Gate Pattern |
|
|
72
|
+
|------|------------|--------------|
|
|
73
|
+
| `critical` | Security, secrets, rate limiting | NO gate — always runs |
|
|
74
|
+
| `standard` | Pattern feedback, session lifecycle | `source hook-gate.sh standard hook-name` |
|
|
75
|
+
| `strict` | Advisory, CSS audit, auto-review | `source hook-gate.sh strict hook-name` |
|
|
76
|
+
|
|
77
|
+
## Gotchas
|
|
78
|
+
|
|
79
|
+
- **stdin piping**: Hook receives tool input via stdin — `TOOL_INPUT=$(cat)` must be first
|
|
80
|
+
- **Exit codes**: Exit 0 = success/allow, non-zero = hook failure (not tool blocking)
|
|
81
|
+
- **hook-gate.sh sourcing**: MUST use `2>/dev/null || true` suffix (hook-gate may not exist in CI)
|
|
82
|
+
- **Inline PROFILE check**: settings.json entry needs `PROFILE=${LIMN_HOOK_PROFILE:-strict}` prefix for minimal profile bypass
|
|
83
|
+
- **jq dependency**: Use `jq` for JSON parsing (installed on dev machine), never grep for JSON fields
|
|
84
|
+
- **Performance**: Hooks run on every tool invocation — keep under 10ms for standard tier
|
|
85
|
+
|
|
86
|
+
## Process
|
|
87
|
+
|
|
88
|
+
1. Ask user: What event? What tool? What should the hook do?
|
|
89
|
+
2. Determine profile tier (critical/standard/strict)
|
|
90
|
+
3. Create hook script in `scripts/hooks/`
|
|
91
|
+
4. Add entry to `.claude/settings.json` under appropriate event
|
|
92
|
+
5. Test by invoking the relevant tool
|
|
93
|
+
|
|
94
|
+
## START NOW
|
|
95
|
+
|
|
96
|
+
Ask the user what the hook should do, which lifecycle event it fires on, and which tool it should match.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: massu-scaffold-page
|
|
3
|
+
description: "When user wants to create a new page, route, or section in the app — scaffolds the page component, layout, loading/error states, and tRPC integration"
|
|
4
|
+
allowed-tools: Bash(*), Read(*), Write(*), Edit(*), Grep(*), Glob(*)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Scaffold New Page
|
|
8
|
+
|
|
9
|
+
> **Shared rules apply.** Read `.claude/commands/_shared-preamble.md` before proceeding.
|
|
10
|
+
|
|
11
|
+
Creates a complete Next.js App Router page following all project patterns.
|
|
12
|
+
|
|
13
|
+
## What Gets Created
|
|
14
|
+
|
|
15
|
+
| File | Purpose |
|
|
16
|
+
|------|---------|
|
|
17
|
+
| `page.tsx` | Main page component with Suspense boundary |
|
|
18
|
+
| `loading.tsx` | Skeleton loading state |
|
|
19
|
+
| `error.tsx` | Error boundary with retry |
|
|
20
|
+
|
|
21
|
+
## Template
|
|
22
|
+
|
|
23
|
+
### page.tsx
|
|
24
|
+
```tsx
|
|
25
|
+
import { Suspense } from 'react';
|
|
26
|
+
import { PageContent } from './page-content';
|
|
27
|
+
import Loading from './loading';
|
|
28
|
+
|
|
29
|
+
export default function Page() {
|
|
30
|
+
return (
|
|
31
|
+
<div className="page-container">
|
|
32
|
+
<Suspense fallback={<Loading />}>
|
|
33
|
+
<PageContent />
|
|
34
|
+
</Suspense>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### page-content.tsx (with params)
|
|
41
|
+
```tsx
|
|
42
|
+
'use client';
|
|
43
|
+
|
|
44
|
+
import { use } from 'react';
|
|
45
|
+
import { api } from '@/trpc/react';
|
|
46
|
+
|
|
47
|
+
export function PageContent({ params }: { params: Promise<{ id: string }> }) {
|
|
48
|
+
const { id } = use(params);
|
|
49
|
+
const { data, isLoading } = api.routerName.getById.useQuery({ id });
|
|
50
|
+
|
|
51
|
+
if (isLoading) return <Loading />;
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<>
|
|
55
|
+
<PageHeader title="Page Title" />
|
|
56
|
+
{/* Page content */}
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### loading.tsx
|
|
63
|
+
```tsx
|
|
64
|
+
import { Skeleton } from '@/components/ui/skeleton';
|
|
65
|
+
|
|
66
|
+
export default function Loading() {
|
|
67
|
+
return (
|
|
68
|
+
<div className="page-container">
|
|
69
|
+
<Skeleton className="h-8 w-48 mb-6" />
|
|
70
|
+
<Skeleton className="h-64 w-full" />
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### error.tsx
|
|
77
|
+
```tsx
|
|
78
|
+
'use client';
|
|
79
|
+
|
|
80
|
+
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
|
|
81
|
+
return (
|
|
82
|
+
<div className="page-container">
|
|
83
|
+
<h2>Something went wrong</h2>
|
|
84
|
+
<p className="text-muted-foreground">{error.message}</p>
|
|
85
|
+
<button onClick={reset}>Try again</button>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Gotchas
|
|
92
|
+
|
|
93
|
+
- **ALWAYS use `page-container`** class on root div — never `container mx-auto`
|
|
94
|
+
- **Suspense boundaries** are REQUIRED for pages using `use(params)` or `useSearchParams()`
|
|
95
|
+
- **protectedProcedure** for ALL tRPC queries that need auth
|
|
96
|
+
- **Breadcrumbs**: Add to PageHeader if page is nested (e.g., `/dashboard/settings/[id]`)
|
|
97
|
+
|
|
98
|
+
## Process
|
|
99
|
+
|
|
100
|
+
1. Ask user: What URL path? What data does it fetch?
|
|
101
|
+
2. Determine route segment: `src/app/(app)/[section]/[subsection]/`
|
|
102
|
+
3. Create all 3 files (page.tsx, loading.tsx, error.tsx)
|
|
103
|
+
4. If data-fetching: verify tRPC router exists, add query
|
|
104
|
+
5. Run `npx tsc --noEmit` to verify types
|
|
105
|
+
|
|
106
|
+
## START NOW
|
|
107
|
+
|
|
108
|
+
Ask the user what page to create and where it should live in the route hierarchy.
|