@ryuenn3123/agentic-senior-core 6.7.2 → 6.7.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "6.7.2",
3
+ "version": "6.7.3",
4
4
  "description": "Universal AI coding rules. Write code like a staff engineer.",
5
5
  "skills": "./skills/",
6
6
  "hooks": "./hooks/hooks.json",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "6.7.2",
3
+ "version": "6.7.3",
4
4
  "description": "Universal AI coding rules. Because your AI writes code like it gets paid by the line.",
5
5
  "contextFileName": "rules/agentic-senior-core.md",
6
6
  "rules": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "6.7.2",
3
+ "version": "6.7.3",
4
4
  "description": "Universal AI coding rules. Write code like a staff engineer.",
5
5
  "author": "fatidaprilian",
6
6
  "license": "MIT",
@@ -138,31 +138,55 @@ function loadDedupConfig(cwd) {
138
138
  };
139
139
  }
140
140
 
141
- function runEslintAutoFix(cwd, stagedFiles) {
142
- const hasTsConfig = fs.existsSync(path.join(cwd, 'tsconfig.json'));
143
- if (!hasTsConfig) return;
144
-
145
- const eslintConfigNames = [
146
- 'eslint.config.js', 'eslint.config.mjs', 'eslint.config.cjs', 'eslint.config.ts',
147
- '.eslintrc', '.eslintrc.js', '.eslintrc.cjs', '.eslintrc.json', '.eslintrc.yaml', '.eslintrc.yml'
141
+ function checkSecrets(stagedFiles, cwd) {
142
+ var SECRET_PATTERNS = [
143
+ { name: 'Private Key', pattern: /BEGIN\\s+(RSA|DSA|EC|OPENSSH|PGP)\\s+PRIVATE\\s+KEY/ },
144
+ { name: 'AWS Access Key', pattern: /AKIA[0-9A-Z]{16}/ },
145
+ { name: 'GitHub Token', pattern: /gh[pousr]_[A-Za-z0-9_]{36,}/ },
146
+ { name: 'GitHub PAT', pattern: /github_pat_[A-Za-z0-9_]{22,}/ },
147
+ { name: 'Generic Secret Key', pattern: /sk[-_](live|test|prod)_[A-Za-z0-9]{20,}/ },
148
+ { name: 'Generic API Key', pattern: /(?:api[_-]?key|apikey|api[_-]?secret)\\s*[:=]\\s*['"][A-Za-z0-9\\/+=]{20,}['"]/i },
148
149
  ];
149
- const hasEslintConfig = eslintConfigNames.some(name => fs.existsSync(path.join(cwd, name)));
150
- if (!hasEslintConfig) return;
151
-
152
- const tsJsExts = new Set(['js', 'ts', 'jsx', 'tsx', 'mjs', 'cjs']);
153
- const stagedTsJsFiles = stagedFiles.filter(file => {
154
- const ext = path.extname(file).slice(1).toLowerCase();
155
- return tsJsExts.has(ext);
156
- });
150
+ for (var i = 0; i < stagedFiles.length; i++) {
151
+ try {
152
+ var content = fs.readFileSync(path.resolve(cwd, stagedFiles[i]), 'utf8');
153
+ for (var j = 0; j < SECRET_PATTERNS.length; j++) {
154
+ if (SECRET_PATTERNS[j].pattern.test(content)) {
155
+ console.error('\\x1b[31m[ASC Secret]\\x1b[0m ' + SECRET_PATTERNS[j].name + ' detected in: ' + stagedFiles[i]);
156
+ console.error('\\x1b[33mCommit blocked. Remove the secret and use environment variables. Use git commit --no-verify to bypass.\\x1b[0m');
157
+ process.exit(1);
158
+ }
159
+ }
160
+ } catch (_) {}
161
+ }
162
+ }
157
163
 
158
- if (stagedTsJsFiles.length === 0) return;
164
+ function checkMergeConflictMarkers(stagedFiles, cwd) {
165
+ var CONFLICT_PATTERN = /^(<{7}|={7}|>{7})/m;
166
+ for (var i = 0; i < stagedFiles.length; i++) {
167
+ try {
168
+ var content = fs.readFileSync(path.resolve(cwd, stagedFiles[i]), 'utf8');
169
+ if (CONFLICT_PATTERN.test(content)) {
170
+ console.error('\\x1b[31m[ASC Conflict]\\x1b[0m Merge conflict markers found in: ' + stagedFiles[i]);
171
+ console.error('\\x1b[33mCommit blocked. Resolve all merge conflicts before committing.\\x1b[0m');
172
+ process.exit(1);
173
+ }
174
+ } catch (_) {}
175
+ }
176
+ }
159
177
 
160
- try {
161
- const fileList = stagedTsJsFiles.map(f => \`"\${f}"\`).join(' ');
162
- execSync(\`npx eslint --fix \${fileList}\`, { stdio: 'ignore', cwd });
163
- execSync(\`git add \${fileList}\`, { stdio: 'ignore', cwd });
164
- } catch (_) {
165
- // Silently ignore ESLint auto-fix errors (never block commit on lint failure alone)
178
+ function checkLargeFiles(stagedFiles, cwd, maxSizeKB) {
179
+ var limit = maxSizeKB || 500;
180
+ for (var i = 0; i < stagedFiles.length; i++) {
181
+ try {
182
+ var stat = fs.statSync(path.resolve(cwd, stagedFiles[i]));
183
+ var sizeKB = Math.round(stat.size / 1024);
184
+ if (sizeKB > limit) {
185
+ console.error('\\x1b[31m[ASC Size]\\x1b[0m File too large: ' + stagedFiles[i] + ' (' + sizeKB + 'KB > ' + limit + 'KB limit)');
186
+ console.error('\\x1b[33mCommit blocked. Use Git LFS for large files or add to .gitignore. Use git commit --no-verify to bypass.\\x1b[0m');
187
+ process.exit(1);
188
+ }
189
+ } catch (_) {}
166
190
  }
167
191
  }
168
192
 
@@ -277,7 +301,13 @@ function runPreCommitGate() {
277
301
  process.exit(0);
278
302
  }
279
303
 
280
- // 1. Filter staged files by SOURCE_EXTENSIONS
304
+ // 1. Universal security & hygiene checks (all staged files, language-agnostic)
305
+ var config = loadDedupConfig(cwd);
306
+ checkSecrets(stagedFiles, cwd);
307
+ checkMergeConflictMarkers(stagedFiles, cwd);
308
+ checkLargeFiles(stagedFiles, cwd, config.maxFileSizeKB);
309
+
310
+ // 2. Filter staged files by SOURCE_EXTENSIONS for dedup scan
281
311
  const stagedSourceFiles = stagedFiles.filter(f => {
282
312
  const ext = path.extname(f).slice(1).toLowerCase();
283
313
  return SOURCE_EXTENSIONS.has(ext);
@@ -287,22 +317,8 @@ function runPreCommitGate() {
287
317
  process.exit(0);
288
318
  }
289
319
 
290
- // 2. Optional pre-step: ESLint auto-fix
291
- runEslintAutoFix(cwd, stagedFiles);
292
-
293
- // Re-fetch staged files after possible eslint auto-fix & git add
294
- const currentStagedSource = getStagedFiles(cwd).filter(f => {
295
- const ext = path.extname(f).slice(1).toLowerCase();
296
- return SOURCE_EXTENSIONS.has(ext);
297
- });
298
-
299
- if (currentStagedSource.length === 0) {
300
- process.exit(0);
301
- }
302
-
303
320
  // 3. Run jscpd dedup scan
304
- const config = loadDedupConfig(cwd);
305
- const scanDirs = Array.from(new Set(currentStagedSource.map(f => {
321
+ const scanDirs = Array.from(new Set(stagedSourceFiles.map(f => {
306
322
  const resolved = path.resolve(cwd, f);
307
323
  return path.dirname(resolved);
308
324
  })));
@@ -321,7 +337,7 @@ function runPreCommitGate() {
321
337
  const scanCmd = \` "\${scanDir}" --min-tokens \${minTokens} --reporters json --silent --output "\${tmpDir}" \${ignoreFlags}\`;
322
338
  const report = runJscpdScan(scanCmd, cwd, tmpDir);
323
339
  if (report) {
324
- finding = checkForDuplicates(report, currentStagedSource, cwd, config);
340
+ finding = checkForDuplicates(report, stagedSourceFiles, cwd, config);
325
341
  if (finding) break;
326
342
  }
327
343
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "6.7.2",
3
+ "version": "6.7.3",
4
4
  "type": "module",
5
5
  "description": "Agentic Senior Core: Universal AI coding rules and workflows. Write code like a staff engineer, not a junior.",
6
6
  "bin": {
package/plugin.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: agentic-senior-core
2
- version: 6.7.2
2
+ version: 6.7.3
3
3
  description: Universal AI coding rules. Write code like a staff engineer.
4
4
  author: fatidaprilian
5
5
  provides_hooks: