sumulige-claude 1.1.0 → 1.1.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.
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Pre-commit Quality Gate
4
+ *
5
+ * Runs quality checks before committing.
6
+ * Fails the commit if critical or error issues are found.
7
+ *
8
+ * Install: ln -s ../../.claude/hooks/pre-commit.cjs .git/hooks/pre-commit
9
+ * Or use: smc hooks install
10
+ */
11
+
12
+ const { execSync } = require('child_process');
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+
16
+ const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
17
+
18
+ async function main() {
19
+ // Check if quality gate is enabled
20
+ const configPath = path.join(projectDir, '.claude', 'quality-gate.json');
21
+ let config = { enabled: true, gates: { preCommit: true } };
22
+
23
+ if (fs.existsSync(configPath)) {
24
+ try {
25
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
26
+ } catch {}
27
+ }
28
+
29
+ if (!config.enabled || !config.gates?.preCommit) {
30
+ process.exit(0);
31
+ }
32
+
33
+ // Get staged files
34
+ let stagedFiles = [];
35
+ try {
36
+ const output = execSync('git diff --cached --name-only --diff-filter=ACM', {
37
+ encoding: 'utf-8',
38
+ stdio: 'pipe'
39
+ });
40
+ stagedFiles = output.trim().split('\n').filter(Boolean);
41
+ } catch {
42
+ // Not in git repo or no staged files
43
+ process.exit(0);
44
+ }
45
+
46
+ if (stagedFiles.length === 0) {
47
+ process.exit(0);
48
+ }
49
+
50
+ // Filter to checkable files
51
+ const checkable = stagedFiles.filter(f => {
52
+ const ext = path.extname(f);
53
+ return ['.js', '.ts', '.jsx', '.tsx', '.cjs', '.mjs', '.json', '.md'].includes(ext);
54
+ });
55
+
56
+ if (checkable.length === 0) {
57
+ process.exit(0);
58
+ }
59
+
60
+ console.log(`Running pre-commit quality checks on ${checkable.length} file(s)...`);
61
+
62
+ // Run quality gate
63
+ const { QualityGate } = require(path.join(__dirname, '..', '..', 'lib', 'quality-gate.js'));
64
+ const gate = new QualityGate({
65
+ projectDir,
66
+ config
67
+ });
68
+
69
+ const result = await gate.check({
70
+ files: checkable.map(f => path.join(projectDir, f)),
71
+ severity: 'error' // Block on errors and critical only
72
+ });
73
+
74
+ if (!result.passed) {
75
+ console.error('\nPre-commit quality gate failed.');
76
+ console.error('Fix issues or use --no-verify to bypass (not recommended).\n');
77
+ process.exit(1);
78
+ }
79
+
80
+ console.log('Pre-commit quality checks passed.\n');
81
+ }
82
+
83
+ main().catch(err => {
84
+ console.error('Pre-commit hook error:', err.message);
85
+ process.exit(1);
86
+ });
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Pre-push Quality Gate
4
+ *
5
+ * Runs full quality checks before pushing.
6
+ * More comprehensive than pre-commit.
7
+ *
8
+ * Install: ln -s ../../.claude/hooks/pre-push.cjs .git/hooks/pre-push
9
+ * Or use: smc hooks install
10
+ */
11
+
12
+ const { execSync } = require('child_process');
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+
16
+ const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd();
17
+
18
+ async function main() {
19
+ // Check if quality gate is enabled
20
+ const configPath = path.join(projectDir, '.claude', 'quality-gate.json');
21
+ let config = { enabled: true, gates: { prePush: true } };
22
+
23
+ if (fs.existsSync(configPath)) {
24
+ try {
25
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
26
+ } catch {}
27
+ }
28
+
29
+ if (!config.enabled || !config.gates?.prePush) {
30
+ process.exit(0);
31
+ }
32
+
33
+ console.log('Running pre-push quality checks...\n');
34
+
35
+ // Get all files that will be pushed
36
+ let filesToCheck = [];
37
+ try {
38
+ // Get files changed since last push
39
+ const upstream = execSync('git rev-parse --abbrev-ref --symbolic-full-name @{u}', {
40
+ encoding: 'utf-8',
41
+ stdio: 'pipe'
42
+ }).trim() || 'origin/main';
43
+
44
+ const output = execSync(`git diff --name-only ${upstream}...HEAD`, {
45
+ encoding: 'utf-8',
46
+ stdio: 'pipe'
47
+ });
48
+ filesToCheck = output.trim().split('\n').filter(Boolean);
49
+ } catch {
50
+ // No upstream or other git error - check staged files only
51
+ try {
52
+ const output = execSync('git diff --cached --name-only --diff-filter=ACM', {
53
+ encoding: 'utf-8',
54
+ stdio: 'pipe'
55
+ });
56
+ filesToCheck = output.trim().split('\n').filter(Boolean);
57
+ } catch {
58
+ // Not in git repo
59
+ process.exit(0);
60
+ }
61
+ }
62
+
63
+ if (filesToCheck.length === 0) {
64
+ process.exit(0);
65
+ }
66
+
67
+ // Filter to checkable files
68
+ const checkable = filesToCheck.filter(f => {
69
+ const ext = path.extname(f);
70
+ return ['.js', '.ts', '.jsx', '.tsx', '.cjs', '.mjs', '.json', '.md'].includes(ext);
71
+ });
72
+
73
+ if (checkable.length === 0) {
74
+ process.exit(0);
75
+ }
76
+
77
+ console.log(`Checking ${checkable.length} changed file(s)...\n`);
78
+
79
+ // Run quality gate
80
+ const { QualityGate } = require(path.join(__dirname, '..', '..', 'lib', 'quality-gate.js'));
81
+ const gate = new QualityGate({
82
+ projectDir,
83
+ config
84
+ });
85
+
86
+ const result = await gate.check({
87
+ files: checkable.map(f => path.join(projectDir, f)),
88
+ severity: 'warn' // Block on warnings too for push
89
+ });
90
+
91
+ if (!result.passed) {
92
+ console.error('\nPush blocked by quality gate.');
93
+ console.error('Fix issues or use --no-verify to bypass (not recommended).\n');
94
+ process.exit(1);
95
+ }
96
+
97
+ console.log('All quality checks passed. Proceeding with push.\n');
98
+ }
99
+
100
+ main().catch(err => {
101
+ console.error('Pre-push hook error:', err.message);
102
+ process.exit(1);
103
+ });
@@ -0,0 +1,61 @@
1
+ {
2
+ "enabled": true,
3
+ "severity": "warn",
4
+ "rules": [
5
+ {
6
+ "id": "line-count-limit",
7
+ "enabled": true,
8
+ "severity": "error",
9
+ "config": {
10
+ "maxLines": 800
11
+ }
12
+ },
13
+ {
14
+ "id": "file-size-limit",
15
+ "enabled": true,
16
+ "severity": "warn",
17
+ "config": {
18
+ "maxSize": 819200
19
+ }
20
+ },
21
+ {
22
+ "id": "no-empty-files",
23
+ "enabled": true,
24
+ "severity": "warn"
25
+ },
26
+ {
27
+ "id": "no-trailing-whitespace",
28
+ "enabled": true,
29
+ "severity": "warn"
30
+ },
31
+ {
32
+ "id": "todo-comments",
33
+ "enabled": true,
34
+ "severity": "info"
35
+ },
36
+ {
37
+ "id": "directory-depth",
38
+ "enabled": false,
39
+ "severity": "warn"
40
+ },
41
+ {
42
+ "id": "no-console-logs",
43
+ "enabled": false,
44
+ "severity": "warn"
45
+ },
46
+ {
47
+ "id": "function-length",
48
+ "enabled": false,
49
+ "severity": "warn"
50
+ }
51
+ ],
52
+ "gates": {
53
+ "preCommit": true,
54
+ "prePush": true,
55
+ "onToolUse": false
56
+ },
57
+ "reporting": {
58
+ "format": "console",
59
+ "outputFile": null
60
+ }
61
+ }
@@ -87,7 +87,10 @@
87
87
  "Bash(git init:*)",
88
88
  "Bash(git branch:*)",
89
89
  "Bash(gh repo create:*)",
90
- "Bash(npm view:*)"
90
+ "Bash(npm view:*)",
91
+ "Bash(npm update:*)",
92
+ "Bash(ln:*)",
93
+ "Bash(git reset:*)"
91
94
  ]
92
95
  },
93
96
  "hooks": {