start-vibing 2.0.45 → 2.0.47
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
|
@@ -39,7 +39,9 @@ The stop-validator categorizes changed files and maps them to CLAUDE.md sections
|
|
|
39
39
|
| Config files | Stack, Configuration |
|
|
40
40
|
| Hooks/scripts | Workflow, Stop Hook Validations |
|
|
41
41
|
|
|
42
|
-
If ONLY "Last Change" was modified but categorized source files changed, `CLAUDE_MD_SHALLOW_UPDATE` blocks completion.
|
|
42
|
+
If ONLY "Last Change" was modified but **significant** categorized source files changed, `CLAUDE_MD_SHALLOW_UPDATE` blocks completion.
|
|
43
|
+
|
|
44
|
+
**Exempt (minor changes):** < 3 categorized files AND < 30 lines changed AND no new files = Last Change only is OK.
|
|
43
45
|
|
|
44
46
|
---
|
|
45
47
|
|
|
@@ -820,13 +820,133 @@ The stop hook will BLOCK until CLAUDE.md is updated with ALL relevant sections.
|
|
|
820
820
|
};
|
|
821
821
|
}
|
|
822
822
|
|
|
823
|
+
// ============================================================================
|
|
824
|
+
// CHANGE RELEVANCE ASSESSMENT
|
|
825
|
+
// ============================================================================
|
|
826
|
+
|
|
827
|
+
/**
|
|
828
|
+
* Minimum thresholds for changes to be considered "relevant enough" to require
|
|
829
|
+
* updating CLAUDE.md sections beyond "Last Change".
|
|
830
|
+
*
|
|
831
|
+
* Minor changes (small fixes, typos, internal refactors) that don't affect
|
|
832
|
+
* project rules, flows, or patterns should NOT require deep section updates.
|
|
833
|
+
*/
|
|
834
|
+
const RELEVANCE_THRESHOLDS = {
|
|
835
|
+
/** Minimum total lines added+removed across categorized files to require section updates */
|
|
836
|
+
minLinesChanged: 30,
|
|
837
|
+
/** Minimum number of categorized files changed to require section updates */
|
|
838
|
+
minFilesChanged: 3,
|
|
839
|
+
/** If ANY new files were created in categorized areas, always require section updates */
|
|
840
|
+
newFilesAlwaysRelevant: true,
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Assess whether the changes in categorized files are significant enough
|
|
845
|
+
* to require updating CLAUDE.md sections beyond "Last Change".
|
|
846
|
+
*
|
|
847
|
+
* Returns true if changes are relevant (should require deep updates).
|
|
848
|
+
* Returns false if changes are minor (Last Change only is acceptable).
|
|
849
|
+
*/
|
|
850
|
+
function areChangesRelevantForClaudeMd(
|
|
851
|
+
categories: Array<{ category: string; sections: string[]; files: string[] }>
|
|
852
|
+
): boolean {
|
|
853
|
+
const totalCategorizedFiles = categories.reduce((sum, c) => sum + c.files.length, 0);
|
|
854
|
+
|
|
855
|
+
// Check for new files (new files = new patterns/features = always relevant)
|
|
856
|
+
if (RELEVANCE_THRESHOLDS.newFilesAlwaysRelevant) {
|
|
857
|
+
try {
|
|
858
|
+
const untrackedRaw = execSync('git ls-files --others --exclude-standard', {
|
|
859
|
+
cwd: PROJECT_DIR,
|
|
860
|
+
encoding: 'utf8',
|
|
861
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
862
|
+
}).trim();
|
|
863
|
+
const newInLastCommitRaw = execSync('git diff --name-only --diff-filter=A HEAD~1 HEAD 2>/dev/null || echo ""', {
|
|
864
|
+
cwd: PROJECT_DIR,
|
|
865
|
+
encoding: 'utf8',
|
|
866
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
867
|
+
}).trim();
|
|
868
|
+
|
|
869
|
+
const newFiles = [...untrackedRaw.split('\n'), ...newInLastCommitRaw.split('\n')].filter(Boolean);
|
|
870
|
+
const allCategorizedFiles = categories.flatMap((c) => c.files);
|
|
871
|
+
const newCategorizedFiles = newFiles.filter((f) =>
|
|
872
|
+
allCategorizedFiles.some((cf) => f.includes(cf) || cf.includes(f))
|
|
873
|
+
);
|
|
874
|
+
|
|
875
|
+
if (newCategorizedFiles.length > 0) {
|
|
876
|
+
return true; // New files in categorized areas = always relevant
|
|
877
|
+
}
|
|
878
|
+
} catch {
|
|
879
|
+
// Can't determine, continue with other checks
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// Check minimum files threshold
|
|
884
|
+
if (totalCategorizedFiles < RELEVANCE_THRESHOLDS.minFilesChanged) {
|
|
885
|
+
// Few files changed - check if the diff is substantial
|
|
886
|
+
try {
|
|
887
|
+
const allCategorizedFiles = categories.flatMap((c) => c.files);
|
|
888
|
+
let totalLinesChanged = 0;
|
|
889
|
+
|
|
890
|
+
// Try to get numstat from various diff sources
|
|
891
|
+
const numstatCommands = [
|
|
892
|
+
'git diff --numstat',
|
|
893
|
+
'git diff --cached --numstat',
|
|
894
|
+
'git diff --numstat HEAD~1 HEAD',
|
|
895
|
+
];
|
|
896
|
+
|
|
897
|
+
for (const cmd of numstatCommands) {
|
|
898
|
+
try {
|
|
899
|
+
const numstat = execSync(cmd, {
|
|
900
|
+
cwd: PROJECT_DIR,
|
|
901
|
+
encoding: 'utf8',
|
|
902
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
903
|
+
}).trim();
|
|
904
|
+
|
|
905
|
+
if (!numstat) continue;
|
|
906
|
+
|
|
907
|
+
for (const line of numstat.split('\n')) {
|
|
908
|
+
const parts = line.split('\t');
|
|
909
|
+
if (parts.length < 3) continue;
|
|
910
|
+
const added = parseInt(parts[0] || '0', 10) || 0;
|
|
911
|
+
const removed = parseInt(parts[1] || '0', 10) || 0;
|
|
912
|
+
const file = parts[2] || '';
|
|
913
|
+
|
|
914
|
+
// Only count lines in categorized files
|
|
915
|
+
if (allCategorizedFiles.some((cf) => file.includes(cf) || cf.includes(file))) {
|
|
916
|
+
totalLinesChanged += added + removed;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
if (totalLinesChanged > 0) break;
|
|
921
|
+
} catch {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
if (totalLinesChanged < RELEVANCE_THRESHOLDS.minLinesChanged) {
|
|
927
|
+
return false; // Small diff + few files = minor change, Last Change is enough
|
|
928
|
+
}
|
|
929
|
+
} catch {
|
|
930
|
+
// Can't determine line count, fall through to relevant
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
return true; // Meets thresholds = relevant, require section updates
|
|
935
|
+
}
|
|
936
|
+
|
|
823
937
|
/**
|
|
824
|
-
*
|
|
825
|
-
* section was modified (shallow update).
|
|
826
|
-
* changed, CLAUDE.md sections beyond Last Change should also be updated.
|
|
938
|
+
* Content depth validation: Checks if CLAUDE.md was updated but only the
|
|
939
|
+
* "Last Change" section was modified (shallow update).
|
|
827
940
|
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
941
|
+
* ALLOWS shallow updates when changes are minor:
|
|
942
|
+
* - Few files changed (< 3 categorized files)
|
|
943
|
+
* - Small diff (< 30 lines total in categorized files)
|
|
944
|
+
* - No new files created in categorized areas
|
|
945
|
+
*
|
|
946
|
+
* BLOCKS shallow updates when changes are significant:
|
|
947
|
+
* - Many categorized files changed
|
|
948
|
+
* - Large diffs that likely introduce new rules/flows
|
|
949
|
+
* - New files created (new patterns/features)
|
|
830
950
|
*/
|
|
831
951
|
function validateClaudeMdContentDepth(modifiedFiles: string[]): ValidationError | null {
|
|
832
952
|
const significantFiles = getSignificantFiles(modifiedFiles);
|
|
@@ -842,6 +962,11 @@ function validateClaudeMdContentDepth(modifiedFiles: string[]): ValidationError
|
|
|
842
962
|
const categories = categorizeChangedFiles(significantFiles);
|
|
843
963
|
if (categories.length === 0) return null; // No categorizable changes, Last Change is enough
|
|
844
964
|
|
|
965
|
+
// RELEVANCE CHECK: Skip if changes are minor/not relevant enough
|
|
966
|
+
if (!areChangesRelevantForClaudeMd(categories)) {
|
|
967
|
+
return null; // Minor changes - Last Change only is acceptable
|
|
968
|
+
}
|
|
969
|
+
|
|
845
970
|
// Try to detect if only "Last Change" section was modified in CLAUDE.md
|
|
846
971
|
// Check git diff of CLAUDE.md (staged, unstaged, or last commit)
|
|
847
972
|
let claudeMdDiff = '';
|
|
@@ -881,6 +1006,7 @@ function validateClaudeMdContentDepth(modifiedFiles: string[]): ValidationError
|
|
|
881
1006
|
if (!onlyLastChange) return null; // Other sections were also modified, good
|
|
882
1007
|
|
|
883
1008
|
// Build specific guidance for what sections need updating
|
|
1009
|
+
const totalFiles = categories.reduce((sum, c) => sum + c.files.length, 0);
|
|
884
1010
|
const sectionGuidance = categories
|
|
885
1011
|
.map((c) => {
|
|
886
1012
|
const uniqueSections = [...new Set(c.sections)];
|
|
@@ -891,14 +1017,16 @@ function validateClaudeMdContentDepth(modifiedFiles: string[]): ValidationError
|
|
|
891
1017
|
|
|
892
1018
|
return {
|
|
893
1019
|
type: 'CLAUDE_MD_SHALLOW_UPDATE',
|
|
894
|
-
message: `CLAUDE.md was updated but ONLY "Last Change" was modified. ${categories.length}
|
|
1020
|
+
message: `CLAUDE.md was updated but ONLY "Last Change" was modified. ${categories.length} category(ies) with ${totalFiles} file(s) require updating additional rule/flow sections.`,
|
|
895
1021
|
action: `
|
|
896
1022
|
================================================================================
|
|
897
1023
|
CLAUDE.MD SHALLOW UPDATE DETECTED - MUST UPDATE RELEVANT SECTIONS
|
|
898
1024
|
================================================================================
|
|
899
1025
|
|
|
900
1026
|
You updated CLAUDE.md but ONLY modified the "Last Change" section.
|
|
901
|
-
|
|
1027
|
+
The changes are significant enough to require updating rule/flow sections.
|
|
1028
|
+
|
|
1029
|
+
(Minor changes with < ${RELEVANCE_THRESHOLDS.minFilesChanged} files and < ${RELEVANCE_THRESHOLDS.minLinesChanged} lines are exempt from this check.)
|
|
902
1030
|
|
|
903
1031
|
CHANGES DETECTED THAT REQUIRE SECTION UPDATES:
|
|
904
1032
|
|
|
@@ -919,18 +1047,12 @@ For EACH category above, review the corresponding CLAUDE.md section and:
|
|
|
919
1047
|
3. If a FLOW changed (e.g., new middleware, data fetching pattern):
|
|
920
1048
|
→ UPDATE Workflow, Architecture, or Next.js App Router Patterns
|
|
921
1049
|
|
|
922
|
-
4. If NOTHING changed in rules/flows (just implementation):
|
|
923
|
-
→
|
|
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
|
|
1050
|
+
4. If NOTHING changed in rules/flows (just implementation details):
|
|
1051
|
+
→ This should not happen for significant changes. Review again.
|
|
930
1052
|
|
|
931
1053
|
RULE: "Last Change" documents WHAT was done.
|
|
932
1054
|
Other sections document HOW things work NOW.
|
|
933
|
-
Both must be current.
|
|
1055
|
+
Both must be current for significant changes.
|
|
934
1056
|
|
|
935
1057
|
The stop hook will BLOCK until relevant sections are also updated.
|
|
936
1058
|
================================================================================`,
|