start-vibing 2.0.42 → 2.0.45

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "start-vibing",
3
- "version": "2.0.42",
3
+ "version": "2.0.45",
4
4
  "description": "Setup Claude Code agents, skills, and hooks in your project. Smart copy that preserves your custom domains and configurations.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,6 +13,7 @@ The stop hook validates `/CLAUDE.md` before allowing task completion:
13
13
  | Character limit | Max 40,000 chars |
14
14
  | Required sections | Last Change, 30s Overview, Stack, Architecture |
15
15
  | Last Change | Must be updated with session info (branch, date, summary) |
16
+ | Content depth | Relevant rule/flow sections must also be updated |
16
17
  | No stacking | Only ONE Last Change section (latest only) |
17
18
  | Branch | Must be on main (PR merged) |
18
19
  | Git tree | Must be clean (no uncommitted changes) |
@@ -21,6 +22,25 @@ The stop hook validates `/CLAUDE.md` before allowing task completion:
21
22
 
22
23
  **If not on main:** Complete PR workflow (commit, push, PR, merge, checkout main).
23
24
 
25
+ ### Content Depth Rule (CLAUDE_MD_SHALLOW_UPDATE)
26
+
27
+ > **"Last Change" = WHAT was done. Other sections = HOW things work NOW. Both MUST be current.**
28
+
29
+ The stop-validator categorizes changed files and maps them to CLAUDE.md sections:
30
+
31
+ | Changed Files | Must Also Update |
32
+ |---------------|-----------------|
33
+ | API/CRUD routes | Critical Rules, HTTP Requests |
34
+ | UI components | UI Architecture, Component Organization |
35
+ | Pages/layouts | Architecture, Next.js App Router Patterns |
36
+ | Styling/aesthetics | UI Architecture, Design System |
37
+ | Auth/middleware | Critical Rules, Workflow |
38
+ | Database/models | Architecture, Critical Rules |
39
+ | Config files | Stack, Configuration |
40
+ | Hooks/scripts | Workflow, Stop Hook Validations |
41
+
42
+ If ONLY "Last Change" was modified but categorized source files changed, `CLAUDE_MD_SHALLOW_UPDATE` blocks completion.
43
+
24
44
  ---
25
45
 
26
46
  ## System Architecture
@@ -46,17 +66,16 @@ All agents MUST use these MCP servers when applicable:
46
66
  | `context7` | Up-to-date library documentation | research, analyzer, tester |
47
67
  | `sequential-thinking` | Complex problem-solving | orchestrator, analyzer, final-validator |
48
68
  | `memory` | Persistent knowledge graph | domain-updater, commit-manager |
49
- | `playwright` | Browser automation and E2E testing | tester, ui-ux-reviewer |
69
+ | `playwright` | Browser automation (via MCP tools) | ui-ux-reviewer |
50
70
  | `nextjs-devtools` | Next.js specific development tools | analyzer (Next.js projects) |
51
71
  | `mongodb` | MongoDB database operations | tester, security-auditor |
52
72
 
53
73
  ### Agent MCP Usage Rules
54
74
 
55
75
  - **research agent**: MUST use `context7` for library docs before recommending patterns
56
- - **tester agent**: MUST use `playwright` for E2E tests
57
76
  - **analyzer agent**: SHOULD use `context7` to verify current API patterns
58
77
  - **domain-updater**: SHOULD use `memory` to persist patterns across sessions
59
- - **ui-ux-reviewer**: MUST use `playwright` to verify UI implementations
78
+ - **ui-ux-reviewer**: MUST use `playwright` MCP tools to verify UI implementations
60
79
 
61
80
  ---
62
81
 
@@ -205,9 +224,8 @@ All implementations MUST:
205
224
  - [ ] Pass typecheck (command from config)
206
225
  - [ ] Pass lint (command from config)
207
226
  - [ ] Pass unit tests (command from config)
208
- - [ ] Pass E2E tests (command from config)
209
227
  - [ ] Pass build (command from config)
210
- - [ ] Have E2E tests with real auth
228
+ - [ ] Use Playwright MCP for browser testing when needed
211
229
  - [ ] Have documentation in `docs/`
212
230
  - [ ] Be security audited
213
231
  - [ ] Be committed with conventional commits
@@ -215,6 +233,142 @@ All implementations MUST:
215
233
 
216
234
  ---
217
235
 
236
+ ## Claude 4.6 Best Practices
237
+
238
+ > **Source:** [Anthropic Claude 4 Best Practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-4-best-practices)
239
+
240
+ ### Model Selection
241
+
242
+ | Model | API ID | Cost (In/Out) | Best For |
243
+ |-------|--------|---------------|----------|
244
+ | **Opus 4.6** | `claude-opus-4-6` | $5/$25 MTok | Orchestrators, long-horizon tasks, 128K output |
245
+ | **Sonnet 4.6** | `claude-sonnet-4-6` | $3/$15 MTok | Daily coding, teammates (5x cheaper) |
246
+ | **Haiku 4.5** | `claude-haiku-4-5-20251001` | $1/$5 MTok | Classification, simple tasks |
247
+
248
+ ### Effort Levels
249
+
250
+ | Level | Behavior | Use Case |
251
+ |-------|----------|----------|
252
+ | `max` | Always thinks, no limits | Complex architecture (**Opus ONLY**) |
253
+ | `high` | Deep thinking (DEFAULT) | Agentic tasks, complex coding |
254
+ | `medium` | Moderate, may skip simple | Most workloads |
255
+ | `low` | Minimal thinking | Subagents, teammates, high-volume |
256
+
257
+ **CLI:** `/model` then arrow keys to adjust effort.
258
+
259
+ ### Adaptive Thinking (Replaces budget_tokens)
260
+
261
+ ```typescript
262
+ // CORRECT for 4.6 models
263
+ thinking: { type: "adaptive" },
264
+ output_config: { effort: "medium" }
265
+
266
+ // DEPRECATED (will be removed)
267
+ thinking: { type: "enabled", budget_tokens: 10000 }
268
+ ```
269
+
270
+ Adaptive thinking enables **interleaved thinking** — Claude reasons BETWEEN tool calls.
271
+
272
+ ### Prompting Rules (CRITICAL)
273
+
274
+ **AVOID (causes overtriggering):**
275
+ - "CRITICAL: You MUST use..."
276
+ - "be thorough", "think carefully", "do not be lazy"
277
+ - "use the think tool to plan your approach"
278
+
279
+ **USE INSTEAD:**
280
+ - "Use this tool when..." (softer language)
281
+ - Remove anti-laziness prompts entirely
282
+ - Lower effort level instead of adding constraints
283
+
284
+ **Why:** Opus 4.6 does MORE upfront exploration than older models. Anti-laziness prompts cause runaway thinking.
285
+
286
+ ### Tool Use Patterns
287
+
288
+ ```text
289
+ # Claude will only SUGGEST:
290
+ "Can you suggest some changes?"
291
+
292
+ # Claude will IMPLEMENT:
293
+ "Change this function to improve performance."
294
+ ```
295
+
296
+ For proactive action by default, add to system prompt:
297
+ ```text
298
+ By default, implement changes rather than only suggesting them.
299
+ ```
300
+
301
+ ### Subagent Control
302
+
303
+ Opus 4.6 has a **strong predilection for subagents** — may spawn them when direct grep/read is faster.
304
+
305
+ **Use subagents when:** Parallel tasks, isolated context, independent workstreams
306
+ **Work directly when:** Sequential operations, single-file edits, shared state needed
307
+
308
+ ```text
309
+ # Add if seeing excessive subagent use:
310
+ For simple tasks, sequential operations, or single-file edits, work directly.
311
+ ```
312
+
313
+ ### Avoid Over-Engineering
314
+
315
+ Opus 4.6 tends to create extra files and unnecessary abstractions.
316
+
317
+ ```text
318
+ # Add to prompt:
319
+ Avoid over-engineering. Only make changes directly requested.
320
+ Don't add features, docstrings, or error handling beyond what's asked.
321
+ ```
322
+
323
+ ### Parallel Tool Calls
324
+
325
+ ```text
326
+ # Add for maximum efficiency:
327
+ If calling multiple tools with no dependencies, make all calls in parallel.
328
+ ```
329
+
330
+ ### Cost Control
331
+
332
+ | Issue | Solution |
333
+ |-------|----------|
334
+ | Runaway thinking | Lower effort (not prompt constraints) |
335
+ | `stop_reason: "max_tokens"` | Increase `max_tokens` to 64K+ |
336
+ | High costs | Use `low` effort for subagents |
337
+ | Billing confusion | Billed for FULL thinking, not visible summary |
338
+
339
+ ### Common Pitfalls
340
+
341
+ | Pitfall | Fix |
342
+ |---------|-----|
343
+ | `max` effort on Sonnet/Haiku | Error — Opus only |
344
+ | Prefilled responses | Deprecated in 4.6 |
345
+ | Multiple agents editing same file | Isolate files per agent |
346
+ | Aggressive prompts from older models | Remove "MUST", "CRITICAL" |
347
+
348
+ ### API Examples
349
+
350
+ ```typescript
351
+ // Standard agentic call
352
+ await client.messages.create({
353
+ model: "claude-opus-4-6",
354
+ max_tokens: 64000,
355
+ thinking: { type: "adaptive" },
356
+ output_config: { effort: "high" },
357
+ messages: [...]
358
+ });
359
+
360
+ // Cost-optimized subagent
361
+ await client.messages.create({
362
+ model: "claude-sonnet-4-6",
363
+ max_tokens: 16000,
364
+ thinking: { type: "adaptive" },
365
+ output_config: { effort: "low" },
366
+ messages: [...]
367
+ });
368
+ ```
369
+
370
+ ---
371
+
218
372
  ## Domain Updater Agent
219
373
 
220
374
  The **domain-updater** runs BEFORE commit-manager to ensure git stays clean.
@@ -54,6 +54,93 @@ const IGNORE_PATTERNS = [
54
54
 
55
55
  const DOC_EXTENSIONS = new Set(['.md', '.mdx', '.txt', '.rst']);
56
56
 
57
+ // ============================================================================
58
+ // FILE CHANGE CATEGORIES → CLAUDE.MD SECTIONS MAPPING
59
+ // ============================================================================
60
+
61
+ interface ChangeCategory {
62
+ name: string;
63
+ claudeMdSections: string[];
64
+ filePatterns: RegExp[];
65
+ }
66
+
67
+ const CHANGE_CATEGORIES: ChangeCategory[] = [
68
+ {
69
+ name: 'API/CRUD',
70
+ claudeMdSections: ['Critical Rules', 'HTTP Requests'],
71
+ filePatterns: [/\/api\//, /\/routers\//, /\/server\//, /\.route\./, /\.controller\./],
72
+ },
73
+ {
74
+ name: 'UI Components',
75
+ claudeMdSections: ['UI Architecture', 'Component Organization', 'Design System'],
76
+ filePatterns: [/\/components\//, /\/ui\//],
77
+ },
78
+ {
79
+ name: 'Pages/Layouts',
80
+ claudeMdSections: ['Next.js App Router Patterns', 'Architecture'],
81
+ filePatterns: [/\/app\/.*page\.tsx/, /\/app\/.*layout\.tsx/, /\/app\/.*loading\.tsx/],
82
+ },
83
+ {
84
+ name: 'Styling/Aesthetics',
85
+ claudeMdSections: ['UI Architecture', 'Design System', 'Design Trends'],
86
+ filePatterns: [/\.css$/, /globals\.css/, /theme/, /tailwind\.config/],
87
+ },
88
+ {
89
+ name: 'Auth/Middleware',
90
+ claudeMdSections: ['Critical Rules', 'Workflow'],
91
+ filePatterns: [/middleware/, /auth/, /session/],
92
+ },
93
+ {
94
+ name: 'Database/Models',
95
+ claudeMdSections: ['Architecture', 'Critical Rules'],
96
+ filePatterns: [/\/models\//, /\.model\./, /\/schema\//, /\.schema\./],
97
+ },
98
+ {
99
+ name: 'Configuration',
100
+ claudeMdSections: ['Stack', 'Configuration'],
101
+ filePatterns: [/\.config\./, /next\.config/, /tsconfig/],
102
+ },
103
+ {
104
+ name: 'Testing',
105
+ claudeMdSections: ['Quality Gates'],
106
+ filePatterns: [/\.test\./, /\.spec\./, /playwright/, /vitest/],
107
+ },
108
+ {
109
+ name: 'Workflow/Hooks',
110
+ claudeMdSections: ['Workflow', 'Stop Hook Validations'],
111
+ filePatterns: [/\.claude\/hooks\//, /\.claude\/scripts\//, /\.husky\//],
112
+ },
113
+ ];
114
+
115
+ function categorizeChangedFiles(
116
+ files: string[]
117
+ ): Array<{ category: string; sections: string[]; files: string[] }> {
118
+ const result = new Map<string, { sections: string[]; files: string[] }>();
119
+
120
+ for (const file of files) {
121
+ const normalizedFile = file.replace(/\\/g, '/');
122
+ for (const cat of CHANGE_CATEGORIES) {
123
+ for (const pattern of cat.filePatterns) {
124
+ if (pattern.test(normalizedFile)) {
125
+ if (!result.has(cat.name)) {
126
+ result.set(cat.name, { sections: [...cat.claudeMdSections], files: [] });
127
+ }
128
+ const entry = result.get(cat.name)!;
129
+ if (!entry.files.includes(file)) {
130
+ entry.files.push(file);
131
+ }
132
+ break;
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ return Array.from(result.entries()).map(([category, data]) => ({
139
+ category,
140
+ ...data,
141
+ }));
142
+ }
143
+
57
144
  const SOURCE_EXTENSIONS = new Set([
58
145
  '.ts',
59
146
  '.tsx',
@@ -603,7 +690,8 @@ IMPORTANT: This section should ONLY contain the LAST change, not a history.
603
690
  }
604
691
 
605
692
  // Check for multiple Last Change sections (stacking is forbidden)
606
- const multipleChanges = content.match(/## Last Change/g);
693
+ // Use negative lookbehind to avoid matching ### Last Change (H3 subheadings)
694
+ const multipleChanges = content.match(/(?<!#)## Last Change/g);
607
695
  if (multipleChanges && multipleChanges.length > 1) {
608
696
  return {
609
697
  type: 'CLAUDE_MD_STACKED_CHANGES',
@@ -628,8 +716,10 @@ This keeps the file focused and within the 40k character limit.
628
716
  return null;
629
717
  }
630
718
 
631
- function validateClaudeMdUpdated(modifiedFiles: string[]): ValidationError | null {
632
- // Files that don't require CLAUDE.md update (auto-generated, locks, etc)
719
+ /**
720
+ * Helper: Get files exempt from CLAUDE.md update requirement
721
+ */
722
+ function getSignificantFiles(modifiedFiles: string[]): string[] {
633
723
  const EXEMPT_PATTERNS = [
634
724
  'bun.lockb',
635
725
  'package-lock.json',
@@ -641,13 +731,10 @@ function validateClaudeMdUpdated(modifiedFiles: string[]): ValidationError | nul
641
731
  /^packages\/start-vibing\/template\//,
642
732
  ];
643
733
 
644
- // Filter out exempt files
645
- const significantFiles = modifiedFiles.filter((f) => {
646
- // Always exempt CLAUDE.md itself
734
+ return modifiedFiles.filter((f) => {
647
735
  if (f === 'CLAUDE.md' || f.endsWith('/CLAUDE.md') || f.endsWith('\\CLAUDE.md')) {
648
736
  return false;
649
737
  }
650
- // Check exempt patterns
651
738
  for (const pattern of EXEMPT_PATTERNS) {
652
739
  if (typeof pattern === 'string') {
653
740
  if (f === pattern || f.includes(pattern)) return false;
@@ -657,17 +744,39 @@ function validateClaudeMdUpdated(modifiedFiles: string[]): ValidationError | nul
657
744
  }
658
745
  return true;
659
746
  });
747
+ }
748
+
749
+ /**
750
+ * Helper: Build categorized section guidance for error messages
751
+ */
752
+ function buildSectionGuidance(significantFiles: string[]): string {
753
+ const categories = categorizeChangedFiles(significantFiles);
754
+ if (categories.length === 0) return '';
755
+
756
+ const lines = categories.map((c) => {
757
+ const uniqueSections = [...new Set(c.sections)];
758
+ return ` - ${c.category} (${c.files.length} file${c.files.length > 1 ? 's' : ''}) → Update sections: ${uniqueSections.join(', ')}`;
759
+ });
760
+
761
+ return `
762
+ DETECTED CHANGE CATEGORIES (update these CLAUDE.md sections):
660
763
 
661
- // If no significant files modified, no need to check
764
+ ${lines.join('\n')}
765
+ `;
766
+ }
767
+
768
+ function validateClaudeMdUpdated(modifiedFiles: string[]): ValidationError | null {
769
+ const significantFiles = getSignificantFiles(modifiedFiles);
662
770
  if (significantFiles.length === 0) return null;
663
771
 
664
- // Check if CLAUDE.md is in the modified files
665
772
  const claudeMdModified = modifiedFiles.some(
666
773
  (f) => f === 'CLAUDE.md' || f.endsWith('/CLAUDE.md') || f.endsWith('\\CLAUDE.md')
667
774
  );
668
775
 
669
776
  if (claudeMdModified) return null;
670
777
 
778
+ const sectionGuidance = buildSectionGuidance(significantFiles);
779
+
671
780
  return {
672
781
  type: 'CLAUDE_MD_NOT_UPDATED',
673
782
  message: `${significantFiles.length} file(s) were modified but CLAUDE.md was not updated.`,
@@ -683,7 +792,7 @@ ${significantFiles
683
792
  .slice(0, 10)
684
793
  .map((f) => ` - ${f}`)
685
794
  .join('\n')}${significantFiles.length > 10 ? '\n ... and more' : ''}
686
-
795
+ ${sectionGuidance}
687
796
  REQUIRED UPDATES TO CLAUDE.MD:
688
797
 
689
798
  1. Update "## Last Change" section:
@@ -691,24 +800,193 @@ REQUIRED UPDATES TO CLAUDE.MD:
691
800
  **Date:** ${new Date().toISOString().split('T')[0]}
692
801
  **Summary:** What you implemented/fixed
693
802
 
694
- 2. If architecture changed:
695
- Update "## Architecture" section
803
+ 2. UPDATE RELEVANT RULE/FLOW SECTIONS (NOT just Last Change!):
804
+ - Changed API/CRUD logic? → Update "Critical Rules" or "HTTP Requests"
805
+ - Changed UI components? → Update "UI Architecture" or "Component Organization"
806
+ - Changed page structure? → Update "Architecture" or "Next.js App Router Patterns"
807
+ - Changed aesthetic rules? → Update "Design System" or "UI Architecture"
808
+ - Changed auth/middleware? → Update "Critical Rules" or "Workflow"
809
+ - Changed config? → Update "Stack" or "Configuration"
810
+ - Changed testing? → Update "Quality Gates"
811
+
812
+ 3. CONTEXT SYNTHESIS:
813
+ Think about what the user asked and what you learned.
814
+ If a rule changed, document the NEW rule in the relevant section.
815
+ If a flow changed, document the NEW flow.
816
+ CLAUDE.md is the single source of truth for ALL project rules.
817
+
818
+ The stop hook will BLOCK until CLAUDE.md is updated with ALL relevant sections.
819
+ ================================================================================`,
820
+ };
821
+ }
696
822
 
697
- 3. If new patterns/rules were established:
698
- Add to appropriate section
823
+ /**
824
+ * NEW VALIDATION: Checks if CLAUDE.md was updated but only the "Last Change"
825
+ * section was modified (shallow update). When source files in categorized areas
826
+ * changed, CLAUDE.md sections beyond Last Change should also be updated.
827
+ *
828
+ * This catches the common pattern where Claude updates only "Last Change"
829
+ * but ignores updating the actual rules/flows that changed.
830
+ */
831
+ function validateClaudeMdContentDepth(modifiedFiles: string[]): ValidationError | null {
832
+ const significantFiles = getSignificantFiles(modifiedFiles);
833
+ if (significantFiles.length === 0) return null;
699
834
 
700
- 4. If user mentioned preferences or corrections:
701
- Add as rules in relevant section
835
+ // Only run if CLAUDE.md WAS modified (otherwise validateClaudeMdUpdated handles it)
836
+ const claudeMdModified = modifiedFiles.some(
837
+ (f) => f === 'CLAUDE.md' || f.endsWith('/CLAUDE.md') || f.endsWith('\\CLAUDE.md')
838
+ );
839
+ if (!claudeMdModified) return null;
840
+
841
+ // Categorize the source changes
842
+ const categories = categorizeChangedFiles(significantFiles);
843
+ if (categories.length === 0) return null; // No categorizable changes, Last Change is enough
844
+
845
+ // Try to detect if only "Last Change" section was modified in CLAUDE.md
846
+ // Check git diff of CLAUDE.md (staged, unstaged, or last commit)
847
+ let claudeMdDiff = '';
848
+ const diffCommands = [
849
+ 'git diff -- CLAUDE.md',
850
+ 'git diff --cached -- CLAUDE.md',
851
+ 'git diff HEAD~1 HEAD -- CLAUDE.md',
852
+ ];
702
853
 
703
- CONTEXT SYNTHESIS:
704
- Think about what the user asked and what you learned.
705
- Capture important decisions and patterns for the next session.
854
+ for (const cmd of diffCommands) {
855
+ try {
856
+ const result = execSync(cmd, {
857
+ cwd: PROJECT_DIR,
858
+ encoding: 'utf8',
859
+ stdio: ['pipe', 'pipe', 'pipe'],
860
+ }).trim();
861
+ if (result) {
862
+ claudeMdDiff = result;
863
+ break;
864
+ }
865
+ } catch {
866
+ continue;
867
+ }
868
+ }
869
+
870
+ if (!claudeMdDiff) return null; // Can't determine diff, skip this check
871
+
872
+ // Parse the diff to detect which sections were modified
873
+ const modifiedSections = parseClaudeMdDiffSections(claudeMdDiff);
874
+
875
+ // Check if ONLY "Last Change" was modified
876
+ const onlyLastChange =
877
+ modifiedSections.size > 0 &&
878
+ modifiedSections.size === 1 &&
879
+ modifiedSections.has('Last Change');
880
+
881
+ if (!onlyLastChange) return null; // Other sections were also modified, good
882
+
883
+ // Build specific guidance for what sections need updating
884
+ const sectionGuidance = categories
885
+ .map((c) => {
886
+ const uniqueSections = [...new Set(c.sections)];
887
+ const fileExamples = c.files.slice(0, 3).join(', ');
888
+ return ` - ${c.category}: ${fileExamples}\n → Must review/update: ${uniqueSections.join(', ')}`;
889
+ })
890
+ .join('\n');
891
+
892
+ return {
893
+ type: 'CLAUDE_MD_SHALLOW_UPDATE',
894
+ message: `CLAUDE.md was updated but ONLY "Last Change" was modified. ${categories.length} change category(ies) require updating additional rule/flow sections.`,
895
+ action: `
896
+ ================================================================================
897
+ CLAUDE.MD SHALLOW UPDATE DETECTED - MUST UPDATE RELEVANT SECTIONS
898
+ ================================================================================
899
+
900
+ You updated CLAUDE.md but ONLY modified the "Last Change" section.
901
+ This is NOT sufficient when source files that affect rules/flows were changed.
902
+
903
+ CHANGES DETECTED THAT REQUIRE SECTION UPDATES:
904
+
905
+ ${sectionGuidance}
906
+
907
+ --------------------------------------------------------------------------------
908
+ WHAT TO DO
909
+ --------------------------------------------------------------------------------
910
+
911
+ For EACH category above, review the corresponding CLAUDE.md section and:
912
+
913
+ 1. If a RULE changed (e.g., CRUD validation, auth flow):
914
+ → UPDATE the rule in its section (Critical Rules, Workflow, etc.)
706
915
 
707
- The stop hook will BLOCK until CLAUDE.md is updated.
916
+ 2. If an AESTHETIC/UI pattern changed (e.g., new component style):
917
+ → UPDATE UI Architecture, Design System, or Component Organization
918
+
919
+ 3. If a FLOW changed (e.g., new middleware, data fetching pattern):
920
+ → UPDATE Workflow, Architecture, or Next.js App Router Patterns
921
+
922
+ 4. If NOTHING changed in rules/flows (just implementation):
923
+ → Add a comment in the relevant section noting the implementation
924
+
925
+ EXAMPLES:
926
+ - Changed how users are fetched? → Update HTTP Requests section
927
+ - Changed button styles? → Update Design System section
928
+ - Added new page? → Update Architecture section
929
+ - Changed form validation? → Update Critical Rules section
930
+
931
+ RULE: "Last Change" documents WHAT was done.
932
+ Other sections document HOW things work NOW.
933
+ Both must be current.
934
+
935
+ The stop hook will BLOCK until relevant sections are also updated.
708
936
  ================================================================================`,
709
937
  };
710
938
  }
711
939
 
940
+ /**
941
+ * Parse a git diff of CLAUDE.md to determine which ## sections were modified.
942
+ * Returns a Set of section names that had actual content changes.
943
+ */
944
+ function parseClaudeMdDiffSections(diff: string): Set<string> {
945
+ const modifiedSections = new Set<string>();
946
+ const lines = diff.split('\n');
947
+ let currentSection = '';
948
+
949
+ for (const line of lines) {
950
+ // Skip diff metadata
951
+ if (
952
+ line.startsWith('diff ') ||
953
+ line.startsWith('index ') ||
954
+ line.startsWith('--- ') ||
955
+ line.startsWith('+++ ')
956
+ ) {
957
+ continue;
958
+ }
959
+
960
+ // Parse @@ hunk headers - they sometimes contain section context
961
+ const hunkMatch = line.match(/^@@ .+ @@\s*(## .+)?/);
962
+ if (hunkMatch && hunkMatch[1]) {
963
+ currentSection = hunkMatch[1].replace('## ', '').trim();
964
+ continue;
965
+ }
966
+ if (line.startsWith('@@')) continue;
967
+
968
+ // Detect section headers in changed or context lines
969
+ const sectionMatch = line.match(/^[+ -]?## (.+)/);
970
+ if (sectionMatch) {
971
+ currentSection = sectionMatch[1].trim();
972
+ // If the section header itself is a change, count it
973
+ if (line.startsWith('+') || line.startsWith('-')) {
974
+ modifiedSections.add(currentSection);
975
+ }
976
+ continue;
977
+ }
978
+
979
+ // Track actual content changes (+ or - lines, not context)
980
+ if (line.startsWith('+') || line.startsWith('-')) {
981
+ if (currentSection) {
982
+ modifiedSections.add(currentSection);
983
+ }
984
+ }
985
+ }
986
+
987
+ return modifiedSections;
988
+ }
989
+
712
990
  function validateDocumentation(sourceFiles: string[]): ValidationError | null {
713
991
  if (sourceFiles.length === 0) return null;
714
992
 
@@ -996,7 +1274,13 @@ Validate with: wc -m CLAUDE.md (must be < 40000)`,
996
1274
  },
997
1275
  CLAUDE_MD_NOT_UPDATED: {
998
1276
  agent: 'documenter',
999
- prompt: 'Update CLAUDE.md Last Change section with current session summary',
1277
+ prompt:
1278
+ 'Update CLAUDE.md: Last Change section AND all relevant rule/flow sections based on what files were changed (API rules, UI rules, workflow, architecture, etc.)',
1279
+ },
1280
+ CLAUDE_MD_SHALLOW_UPDATE: {
1281
+ agent: 'documenter',
1282
+ prompt:
1283
+ 'CLAUDE.md was updated but only Last Change was modified. Review changed source files, categorize them, and update the corresponding CLAUDE.md sections (Critical Rules, UI Architecture, Workflow, etc.) to reflect current rules and flows.',
1000
1284
  },
1001
1285
  SOURCE_FILES_NOT_DOCUMENTED: {
1002
1286
  agent: 'documenter',
@@ -1087,11 +1371,15 @@ function collectAllErrors(
1087
1371
  const updatedError = validateClaudeMdUpdated(modifiedFiles);
1088
1372
  if (updatedError) errors.push(updatedError);
1089
1373
 
1090
- // 9. Source files must be documented
1374
+ // 9. CLAUDE.md must have relevant sections updated (not just Last Change)
1375
+ const contentDepthError = validateClaudeMdContentDepth(modifiedFiles);
1376
+ if (contentDepthError) errors.push(contentDepthError);
1377
+
1378
+ // 11. Source files must be documented
1091
1379
  const docError = validateDocumentation(sourceFiles);
1092
1380
  if (docError) errors.push(docError);
1093
1381
 
1094
- // 10. Domain documentation must be complete
1382
+ // 12. Domain documentation must be complete
1095
1383
  const domainDocError = validateDomainDocumentation(modifiedFiles);
1096
1384
  if (domainDocError) errors.push(domainDocError);
1097
1385
 
@@ -55,17 +55,43 @@ async function main(): Promise<void> {
55
55
 
56
56
  const systemMessage = `TASK WORKFLOW (English only):
57
57
 
58
- 0. READ both CLAUDE.md (project root) and .claude/CLAUDE.md before making any changes. These contain project rules, architecture, and context you need.
59
- 1. CREATE a detailed todo-list (TaskCreate) breaking down the user's request into subtopics/steps.
58
+ 0. READ both CLAUDE.md (project root) and .claude/CLAUDE.md before making any changes.
59
+
60
+ 1. CREATE a detailed todo-list (TaskCreate) breaking down the request into steps.
61
+ - This is MANDATORY for ALL tasks, not optional.
62
+ - Include "Update CLAUDE.md with changes" as final task.
63
+
60
64
  2. WORK through each item sequentially — mark in_progress when starting, completed when done.
61
- 3. COMMIT using conventional commits (feat/fix/refactor/docs/chore). Use the commit-manager agent for proper git workflow: branch → implement → commit → merge to main.
62
- 4. UPDATE CLAUDE.md before finishing — this is the project's fast-recall memory across sessions:
63
- a. "## Last Change" section (date: ${today}, branch, summary). Keep only the latest, never stack.
64
- b. If you changed how the app works (new flows, changed workflows, new patterns): update the relevant CLAUDE.md sections (Architecture, Workflow, Rules, UI patterns, etc.) so the next session knows.
65
- c. If you added new rules, gotchas, or forbidden patterns: add them to the appropriate section.
66
- d. If you changed config, stack, or tooling: update the Stack/Configuration sections.
67
- CLAUDE.md is the single source of truth for quick context. Anything not recorded here will be forgotten next session.
68
- 5. RUN stop-validator before finishing: npx tsx .claude/hooks/stop-validator.ts`;
65
+
66
+ 3. UI/UX IMPLEMENTATION:
67
+ - BEFORE implementing any UI: invoke ui-mobile, ui-tablet, ui-desktop agents in PARALLEL.
68
+ - RESEARCH competitors in the same niche using competitor-analyzer or research-web agent.
69
+ - UI changes without market research will be REJECTED by final-validator.
70
+
71
+ 4. TESTING (via Playwright MCP):
72
+ - Use the Playwright MCP server (mcp__playwright__*) for browser testing.
73
+ - Do NOT run bun run test:e2e - use MCP tools directly.
74
+ - Test on 3 viewports: mobile (375px), tablet (768px), desktop (1280px).
75
+
76
+ 5. COMMIT using conventional commits via commit-manager agent.
77
+
78
+ 6. UPDATE CLAUDE.md BEFORE finishing (MANDATORY - NOT JUST "Last Change"!):
79
+ a. "## Last Change" section (date: ${today}, branch, summary). Keep only latest.
80
+ b. THEN update ALL sections affected by your changes:
81
+ - Changed API/CRUD rules? → Update "Critical Rules" or "HTTP Requests"
82
+ - Changed UI components/aesthetics? → Update "UI Architecture", "Design System", "Component Organization"
83
+ - Changed pages/layouts? → Update "Architecture" or "Next.js App Router Patterns"
84
+ - Changed auth/middleware? → Update "Critical Rules" or "Workflow"
85
+ - Changed config/stack? → Update "Stack" or "Configuration"
86
+ - Changed testing patterns? → Update "Quality Gates"
87
+ - Changed workflow/hooks? → Update "Workflow" or "Stop Hook Validations"
88
+ - New gotchas discovered? → Add to "FORBIDDEN" or "NRY"
89
+
90
+ RULE: "Last Change" = WHAT was done. Other sections = HOW things work NOW.
91
+ If you ONLY update Last Change, the stop-validator will BLOCK with CLAUDE_MD_SHALLOW_UPDATE.
92
+ CLAUDE.md is the SINGLE SOURCE OF TRUTH for ALL project rules and flows.
93
+
94
+ 7. RUN stop-validator before finishing: npx tsx .claude/hooks/stop-validator.ts`;
69
95
 
70
96
  console.log(JSON.stringify({ continue: true, systemMessage }));
71
97
  process.exit(0);
@@ -1,5 +1,5 @@
1
1
  {
2
- "model": "claude-opus-4-5-20251101",
2
+ "model": "opus",
3
3
  "max_tokens": 8192,
4
4
  "max_turns": 100,
5
5
 
@@ -239,7 +239,7 @@
239
239
  },
240
240
  "testing": {
241
241
  "unit_tests_required": true,
242
- "e2e_for_ui_features": true,
242
+ "playwright_mcp_for_browser_tests": true,
243
243
  "data_testid_required": true,
244
244
  "edge_cases_research_required": true
245
245
  },
@@ -266,11 +266,6 @@
266
266
  "required": true,
267
267
  "blocking": true
268
268
  },
269
- "test_e2e": {
270
- "command": "bun run test:e2e",
271
- "required": "when_ui_changes",
272
- "blocking": true
273
- },
274
269
  "build": {
275
270
  "command": "bun run build",
276
271
  "required": true,