@ryuenn3123/agentic-senior-core 6.0.0 → 6.1.0
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/.agents/plugins/agentic-senior-core/hooks/lib/known-ui-slop-patterns.json +34 -0
- package/.agents/plugins/agentic-senior-core/hooks/post-edit-enforce.js +47 -3
- package/.agents/plugins/agentic-senior-core/plugin.json +1 -1
- package/.agents/plugins/agentic-senior-core/skills/asc-reference/SKILL.md +1 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugin.yaml +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"patterns": [
|
|
3
|
+
{
|
|
4
|
+
"id": "ui-gradient-purple-blue",
|
|
5
|
+
"regex": "from-purple-[0-9]+\\s+to-blue-[0-9]+|from-indigo-[0-9]+\\s+to-purple-[0-9]+|from-teal-[0-9]+\\s+to-indigo-[0-9]+",
|
|
6
|
+
"message": "note: 'purple-to-blue gradient' (AI generic style) was flagged, consider continuing with brand-specific colors instead."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "ui-generic-card-shadcn",
|
|
10
|
+
"regex": "shadow-lg\\s+rounded-2xl\\s+p-6|shadow-md\\s+rounded-xl\\s+p-4|border\\s+border-gray-200\\s+rounded-xl\\s+shadow-sm",
|
|
11
|
+
"message": "note: 'generic boilerplate card' (AI default) was flagged, consider continuing with project's existing card component instead."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "ui-inter-font-unpaired",
|
|
15
|
+
"regex": "font-family:\\s*['\"]?Inter['\"]?\\s*(?:!important)?;(?!.*sans-serif)|className=[\"'][^\"']*font-sans[^\"']*[\"'](?=.*Inter)",
|
|
16
|
+
"message": "note: 'unpaired Inter font' (AI default typography) was flagged, consider continuing with the project's design system typography instead."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "ui-colored-left-border",
|
|
20
|
+
"regex": "border-l-4\\s+border-(?:blue|purple|indigo)-[0-9]+|border-l-\\[(?:3px|4px)\\]\\s+border-(?:blue|purple|indigo)-[0-9]+",
|
|
21
|
+
"message": "note: 'colored left-border strip' (AI default alert/card) was flagged, consider continuing with native UI patterns instead."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "ui-glassmorphism",
|
|
25
|
+
"regex": "backdrop-blur-(?:md|lg|xl)\\s+bg-white/10|backdrop-filter:\\s*blur\\(|bg-opacity-20\\s+backdrop-blur",
|
|
26
|
+
"message": "note: 'generic glassmorphism' (AI trend default) was flagged, consider continuing with solid semantic surfaces instead."
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "ui-pill-badge-generic",
|
|
30
|
+
"regex": "rounded-full\\s+px-4\\s+py-1\\s+text-sm\\s+font-medium\\s+bg-(?:blue|purple|indigo)-100\\s+text-(?:blue|purple|indigo)-800",
|
|
31
|
+
"message": "note: 'generic pill badge' (AI default tag) was flagged, consider continuing with the project's existing badge component instead."
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -37,6 +37,14 @@ try {
|
|
|
37
37
|
}
|
|
38
38
|
} catch (_) {}
|
|
39
39
|
|
|
40
|
+
let UI_SLOP_PATTERNS = { patterns: [] };
|
|
41
|
+
try {
|
|
42
|
+
const slopPath = path.join(__dirname, 'lib', 'known-ui-slop-patterns.json');
|
|
43
|
+
if (fs.existsSync(slopPath)) {
|
|
44
|
+
UI_SLOP_PATTERNS = JSON.parse(fs.readFileSync(slopPath, 'utf8'));
|
|
45
|
+
}
|
|
46
|
+
} catch (_) {}
|
|
47
|
+
|
|
40
48
|
const {
|
|
41
49
|
SOURCE_EXTENSIONS,
|
|
42
50
|
LOC_DELTA_THRESHOLD,
|
|
@@ -165,6 +173,11 @@ function processSingleEdit(toolName, toolInput, emitFn, skipArray) {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
checkSecurityPatterns(toolName, toolInput, filePath, findings);
|
|
176
|
+
|
|
177
|
+
if (ext === 'html' || ext === 'css' || ext === 'jsx' || ext === 'tsx' || ext === 'vue' || ext === 'svelte') {
|
|
178
|
+
checkUiSlopPatterns(toolName, toolInput, filePath, findings);
|
|
179
|
+
}
|
|
180
|
+
|
|
168
181
|
if (ext === 'js' || ext === 'ts' || ext === 'jsx' || ext === 'tsx' || ext === 'mjs' || ext === 'cjs') {
|
|
169
182
|
checkLinter(filePath, findings);
|
|
170
183
|
}
|
|
@@ -255,6 +268,13 @@ function checkNewFileSize(toolInput, filePath, findings) {
|
|
|
255
268
|
}
|
|
256
269
|
}
|
|
257
270
|
|
|
271
|
+
function logPatternCheck(checkType, patternId, isMatch) {
|
|
272
|
+
try {
|
|
273
|
+
var result = isMatch ? 'match' : 'no-match';
|
|
274
|
+
process.stderr.write('[pattern-check] ' + patternId + ': ' + result + '\n');
|
|
275
|
+
} catch (_) {}
|
|
276
|
+
}
|
|
277
|
+
|
|
258
278
|
function checkSecurityPatterns(toolName, toolInput, filePath, findings) {
|
|
259
279
|
var target = toolName === 'Edit' ? (toolInput.new_string || '') : (toolInput.content || '');
|
|
260
280
|
if (!target) return;
|
|
@@ -263,7 +283,9 @@ function checkSecurityPatterns(toolName, toolInput, filePath, findings) {
|
|
|
263
283
|
SECURITY_PATTERNS.patterns.forEach(function (p) {
|
|
264
284
|
try {
|
|
265
285
|
var regex = new RegExp(p.regex, 'ig');
|
|
266
|
-
|
|
286
|
+
var isMatch = regex.test(target);
|
|
287
|
+
logPatternCheck('security', p.id || 'sec-pattern', isMatch);
|
|
288
|
+
if (isMatch) {
|
|
267
289
|
findings.push('[ASC Security] ' + p.message);
|
|
268
290
|
}
|
|
269
291
|
} catch (_) {}
|
|
@@ -275,13 +297,35 @@ function checkSecurityPatterns(toolName, toolInput, filePath, findings) {
|
|
|
275
297
|
var spec = SECURITY_PATTERNS.fileSpecific[basename];
|
|
276
298
|
try {
|
|
277
299
|
var regex = new RegExp(spec.require, 'g');
|
|
278
|
-
if (target.trim().length > 0
|
|
279
|
-
|
|
300
|
+
if (target.trim().length > 0) {
|
|
301
|
+
var isMatch = !regex.test(target);
|
|
302
|
+
logPatternCheck('security', spec.id || 'sec-file-specific', isMatch);
|
|
303
|
+
if (isMatch) {
|
|
304
|
+
findings.push('[ASC Security] ' + spec.message);
|
|
305
|
+
}
|
|
280
306
|
}
|
|
281
307
|
} catch (_) {}
|
|
282
308
|
}
|
|
283
309
|
}
|
|
284
310
|
|
|
311
|
+
function checkUiSlopPatterns(toolName, toolInput, filePath, findings) {
|
|
312
|
+
var target = toolName === 'Edit' ? (toolInput.new_string || '') : (toolInput.content || '');
|
|
313
|
+
if (!target) return;
|
|
314
|
+
|
|
315
|
+
if (UI_SLOP_PATTERNS.patterns) {
|
|
316
|
+
UI_SLOP_PATTERNS.patterns.forEach(function (p) {
|
|
317
|
+
try {
|
|
318
|
+
var regex = new RegExp(p.regex, 'ig');
|
|
319
|
+
var isMatch = regex.test(target);
|
|
320
|
+
logPatternCheck('ui-slop', p.id || 'ui-pattern', isMatch);
|
|
321
|
+
if (isMatch) {
|
|
322
|
+
findings.push('[ASC UI Note] ' + p.message);
|
|
323
|
+
}
|
|
324
|
+
} catch (_) {}
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
285
329
|
function checkLinter(filePath, findings) {
|
|
286
330
|
try {
|
|
287
331
|
var cwd = process.cwd();
|
|
@@ -39,6 +39,7 @@ Grounded in: WCAG 2.2 AA (accessibility), Fowler's Money Pattern (monetary types
|
|
|
39
39
|
|
|
40
40
|
## Frontend
|
|
41
41
|
|
|
42
|
+
- Match the project's existing styling paradigm (Tailwind, CSS Modules, Vanilla CSS, styled-components, etc.). Do not introduce a new CSS framework or build tool without explicit user confirmation.
|
|
42
43
|
- Semantic HTML before custom components.
|
|
43
44
|
- WCAG 2.2 AA is the accessibility floor.
|
|
44
45
|
- Responsive by default. Handle empty, loading, error, and offline states.
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
package/plugin.yaml
CHANGED