@event4u/agent-config 7.4.0 → 7.5.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/.claude-plugin/marketplace.json +4 -1
- package/CHANGELOG.md +48 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/review-changes.md +14 -7
- package/dist/agent-src/rules/artifact-engagement-recording.md +9 -0
- package/dist/agent-src/rules/domain-safety-pii.md +4 -3
- package/dist/agent-src/rules/icon-consistency.md +1 -0
- package/dist/agent-src/rules/legal-safety-floor.md +2 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +8 -5
- package/dist/agent-src/skills/adr-create/SKILL.md +5 -1
- package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
- package/dist/agent-src/skills/blade-ui/SKILL.md +4 -0
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +2 -1
- package/dist/agent-src/skills/code-review/SKILL.md +4 -0
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/SKILL.md +40 -0
- package/dist/agent-src/skills/design-review/SKILL.md +23 -11
- package/dist/agent-src/skills/design-system-capture/SKILL.md +41 -0
- package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +62 -0
- package/dist/agent-src/skills/design-tokens/SKILL.md +1 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +6 -0
- package/dist/agent-src/skills/flux/SKILL.md +4 -0
- package/dist/agent-src/skills/iconography/SKILL.md +1 -0
- package/dist/agent-src/skills/image-editing/evals/triggers.json +13 -13
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +136 -0
- package/dist/agent-src/skills/judge-artifact-completeness/calibration/fixtures.json +149 -0
- package/dist/agent-src/skills/judge-artifact-completeness/evals/triggers.json +17 -0
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/architecture-score.json +73 -0
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/pr-review-score.json +65 -0
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/roadmap-score.json +73 -0
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +73 -0
- package/dist/agent-src/skills/judge-injection-defense/SKILL.md +99 -0
- package/dist/agent-src/skills/judge-injection-defense/calibration/fixtures.json +24 -0
- package/dist/agent-src/skills/judge-injection-defense/evals/triggers.json +17 -0
- package/dist/agent-src/skills/judge-injection-defense/fixtures/behavioral-fixtures.json +63 -0
- package/dist/agent-src/skills/judge-injection-defense/fixtures/coverage-report.md +53 -0
- package/dist/agent-src/skills/judge-injection-defense/fixtures/perturbation-taxonomy.json +110 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +134 -0
- package/dist/agent-src/skills/judge-synthesis/evals/triggers.json +17 -0
- package/dist/agent-src/skills/logo-generation/SKILL.md +1 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +1 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +18 -0
- package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +59 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +5 -1
- package/dist/agent-src/skills/release-comms/SKILL.md +1 -1
- package/dist/agent-src/skills/roadmap-management/SKILL.md +4 -0
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/script-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/sql-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -0
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
- package/dist/agent-src/skills/typography-system/SKILL.md +2 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +107 -41
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +8 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +7 -4
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/server/schemas/settings.js +3 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/docs/architecture.md +2 -2
- package/docs/catalog.md +28 -20
- package/docs/command-flows.md +1 -1
- package/docs/guidelines/design-antipatterns.md +26 -0
- package/docs/guidelines/design-canon.md +62 -0
- package/package.json +1 -1
- package/src/config/agent-settings.template.yml +12 -0
- package/src/scripts/design_slop_rules.test.ts +193 -0
- package/src/scripts/design_slop_rules.ts +502 -0
- package/src/scripts/external_sources_denylist.json +7 -1
- package/src/scripts/hook_manifest.yaml +14 -3
- package/src/scripts/hooks/design_slop_hook.ts +181 -0
- package/src/scripts/lint_agent_security.ts +1 -0
- package/src/scripts/lint_confusables.ts +197 -0
- package/src/scripts/lint_design_slop.ts +245 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "Universal AI Agent OS — audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -731,6 +731,18 @@ hooks:
|
|
|
731
731
|
rtk_wrap:
|
|
732
732
|
enabled: false
|
|
733
733
|
|
|
734
|
+
# PreToolUse anti-slop nudge (road-to-anti-slop-detector Phase 3). Default-OFF.
|
|
735
|
+
# When enabled, runs the lint_design_slop registry against about-to-be-written
|
|
736
|
+
# UI content (html/css/jsx/…) and WARNS (exit 2, never blocks) on P0/P1
|
|
737
|
+
# aesthetic tells — the side-stripe signature, gradient-text, magic z-index,
|
|
738
|
+
# etc. Flags are rebuttable: declare intent in DESIGN.md, design-slop-disable,
|
|
739
|
+
# or proceed. Anti-loop: a file::rule signature surfaced 3x goes silent so it
|
|
740
|
+
# never traps the agent. The universal gate is the lint_design_slop linter/CI;
|
|
741
|
+
# this hook is a host-limited convenience layer (pre_tool_use fires on ~2-3
|
|
742
|
+
# hosts). Opt in once you trust the signal-to-noise on your UI.
|
|
743
|
+
design_slop:
|
|
744
|
+
enabled: false
|
|
745
|
+
|
|
734
746
|
# --- Decision engine ---
|
|
735
747
|
#
|
|
736
748
|
# Controllable gates layered over the observability surface. Absent
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { SLOP_RULES, type DesignContext } from "./design_slop_rules.js";
|
|
3
|
+
import { scanFile } from "./lint_design_slop.js";
|
|
4
|
+
|
|
5
|
+
// Context with no DESIGN.md → all gates OFF, every rule active.
|
|
6
|
+
const NO_CTX: DesignContext = { raw: "", has: () => false };
|
|
7
|
+
const ctxWith = (raw: string): DesignContext => ({
|
|
8
|
+
raw: raw.toLowerCase(),
|
|
9
|
+
has: (...ks: string[]) => ks.some((k) => raw.toLowerCase().includes(k.toLowerCase())),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Calibration corpus (Phase 4). One positive (must fire) + one negative (must be
|
|
14
|
+
* clean) per rule. `ext` drives the engine class. No untested tell — the guard
|
|
15
|
+
* below asserts every registry rule appears here.
|
|
16
|
+
*/
|
|
17
|
+
const FIXTURES: Record<string, { ext: string; positive: string; negative: string }> = {
|
|
18
|
+
"slop-v1-side-stripe": {
|
|
19
|
+
ext: "css",
|
|
20
|
+
positive: ".card { border-left: 4px solid #6c5ce7; padding: 16px; }",
|
|
21
|
+
negative: ".card { border-left: 1px solid #eee; padding: 16px; }",
|
|
22
|
+
},
|
|
23
|
+
"slop-v3-ghost-card": {
|
|
24
|
+
ext: "css",
|
|
25
|
+
positive: ".card { border: 1px solid #ddd; box-shadow: 0 8px 24px rgba(0,0,0,.1); }",
|
|
26
|
+
negative: ".card { box-shadow: 0 2px 4px rgba(0,0,0,.1); }",
|
|
27
|
+
},
|
|
28
|
+
"slop-v6-diagonal-stripes": {
|
|
29
|
+
ext: "css",
|
|
30
|
+
positive: ".bg { background: repeating-linear-gradient(45deg,#000,#000 10px,#111 10px,#111 20px); }",
|
|
31
|
+
negative: ".bg { background: linear-gradient(#fff,#eee); }",
|
|
32
|
+
},
|
|
33
|
+
"slop-c2-gradient-text": {
|
|
34
|
+
ext: "css",
|
|
35
|
+
positive: ".h { background: linear-gradient(90deg,#f00,#00f); -webkit-background-clip: text; color: transparent; }",
|
|
36
|
+
negative: ".h { color: #111; }",
|
|
37
|
+
},
|
|
38
|
+
"slop-c5-cream-palette": {
|
|
39
|
+
ext: "css",
|
|
40
|
+
positive: "body { background: #f5f1ea; } .a { color: #b08947; }",
|
|
41
|
+
negative: "body { background: #ffffff; } .a { color: #111111; }",
|
|
42
|
+
},
|
|
43
|
+
"slop-t4-eyebrow-overuse": {
|
|
44
|
+
ext: "html",
|
|
45
|
+
positive:
|
|
46
|
+
'<section><span class="uppercase">Features</span></section><section><span class="uppercase">Pricing</span></section><section><h2>Contact</h2></section>',
|
|
47
|
+
negative:
|
|
48
|
+
'<section><span class="uppercase">Features</span></section><section><h2>Pricing</h2></section><section><h2>Contact</h2></section>',
|
|
49
|
+
},
|
|
50
|
+
"slop-t6-crushed-tracking": {
|
|
51
|
+
ext: "css",
|
|
52
|
+
positive: ".display { letter-spacing: -0.05em; }",
|
|
53
|
+
negative: ".display { letter-spacing: -0.02em; }",
|
|
54
|
+
},
|
|
55
|
+
"slop-t7-default-fonts": {
|
|
56
|
+
ext: "css",
|
|
57
|
+
positive: "body { font-family: 'Inter', sans-serif; }",
|
|
58
|
+
negative: "body { font-family: 'Söhne', sans-serif; }",
|
|
59
|
+
},
|
|
60
|
+
"slop-l4-numbered-markers": {
|
|
61
|
+
ext: "html",
|
|
62
|
+
positive: "<div>01</div><div>02</div><div>03</div>",
|
|
63
|
+
negative: "<div>Discover</div><div>Build</div><div>Ship</div>",
|
|
64
|
+
},
|
|
65
|
+
"slop-l8-zindex-magic": {
|
|
66
|
+
ext: "css",
|
|
67
|
+
positive: ".modal { z-index: 9999; }",
|
|
68
|
+
negative: ".modal { z-index: 400; }",
|
|
69
|
+
},
|
|
70
|
+
"slop-m4-transition-all": {
|
|
71
|
+
ext: "css",
|
|
72
|
+
positive: ".x { transition: all 200ms ease-out; }",
|
|
73
|
+
negative: ".x { transition: transform 200ms ease-out; }",
|
|
74
|
+
},
|
|
75
|
+
"slop-m2-animate-layout": {
|
|
76
|
+
ext: "css",
|
|
77
|
+
positive: ".x { transition: width 200ms ease; }",
|
|
78
|
+
negative: ".x { transition: transform 200ms, opacity 200ms; }",
|
|
79
|
+
},
|
|
80
|
+
"slop-cp1-em-dash": {
|
|
81
|
+
ext: "md",
|
|
82
|
+
// ≥80 words is the rule floor; positive carries 4 em-dashes (well over the
|
|
83
|
+
// ~2-per-500 density), negative carries one across the same length.
|
|
84
|
+
positive:
|
|
85
|
+
"We build tools — fast, focused tools — that teams genuinely love using every single day of the working week. " +
|
|
86
|
+
"The product is calm and clear and useful, and people return to it daily because it respects their time — and their attention — and never wastes a single click of effort or a moment of their busy day, and that quiet reliability is the whole point of the thing we set out to make together, and the team keeps shipping the small improvements that matter most to the people who rely on it.",
|
|
87
|
+
negative:
|
|
88
|
+
"We build tools, fast and focused tools, that teams genuinely love using every single day of the working week. " +
|
|
89
|
+
"The product is calm and clear and useful, and people return to it daily because it respects their time and their attention and never wastes a single click of effort or a moment of their busy day — and that quiet reliability is the whole point of the thing we set out to make together, and the team keeps shipping the small improvements that matter most to the people who rely on it.",
|
|
90
|
+
},
|
|
91
|
+
"slop-cp2-buzzword": {
|
|
92
|
+
ext: "md",
|
|
93
|
+
positive: "We streamline and empower your robust, world-class workflow.",
|
|
94
|
+
negative: "We cut page load by 40% and remove three steps from checkout.",
|
|
95
|
+
},
|
|
96
|
+
"slop-lock-shape": {
|
|
97
|
+
ext: "css",
|
|
98
|
+
positive: ".a{border-radius:4px}.b{border-radius:8px}.c{border-radius:12px}.d{border-radius:20px}",
|
|
99
|
+
negative: ".a{border-radius:8px}.b{border-radius:12px}",
|
|
100
|
+
},
|
|
101
|
+
"slop-lock-colour": {
|
|
102
|
+
ext: "css",
|
|
103
|
+
positive: ".a{color:#e11d48}.b{background:#2563eb}.c{border-color:#16a34a}",
|
|
104
|
+
negative: ".a{color:#111827}.b{background:#6b7280}.c{border-color:#2563eb}",
|
|
105
|
+
},
|
|
106
|
+
"slop-l9-section-monotony": {
|
|
107
|
+
ext: "html",
|
|
108
|
+
// 8 identical media+text sections → 1 distinct layout family (< 4)
|
|
109
|
+
positive: '<section><div class="grid"><img src="x"><h2>A</h2><p>t</p></div></section>'.repeat(8),
|
|
110
|
+
// 8 sections, 4 distinct signatures → not monotonous
|
|
111
|
+
negative: (
|
|
112
|
+
'<section><div class="grid"><img src="x"><h2>A</h2></div></section>' +
|
|
113
|
+
"<section><h2>B</h2><p>t</p></section>" +
|
|
114
|
+
'<section><div class="flex"><p>c</p></div></section>' +
|
|
115
|
+
'<section><img src="y"></section>'
|
|
116
|
+
).repeat(2),
|
|
117
|
+
},
|
|
118
|
+
"slop-l10-zigzag": {
|
|
119
|
+
ext: "html",
|
|
120
|
+
// 3 consecutive media+text two-column sections → run > 2
|
|
121
|
+
positive: '<section><div class="grid"><img src="x"><h2>A</h2><p>t</p></div></section>'.repeat(3),
|
|
122
|
+
// only 2 consecutive → within cap
|
|
123
|
+
negative: '<section><div class="grid"><img src="x"><h2>A</h2><p>t</p></div></section>'.repeat(2),
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
function findingsFor(ruleId: string, content: string, ext: string, ctx = NO_CTX) {
|
|
128
|
+
return scanFile(content, `fixture.${ext}`, ctx).filter((f) => f.rule === ruleId);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
describe("design-slop rule registry", () => {
|
|
132
|
+
it("every rule has a unique id + a catalog id", () => {
|
|
133
|
+
const ids = SLOP_RULES.map((r) => r.id);
|
|
134
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
135
|
+
for (const r of SLOP_RULES) {
|
|
136
|
+
expect(r.id).toMatch(/^slop-/);
|
|
137
|
+
expect(r.catalogId).toMatch(/^[A-Z]+\d+$/);
|
|
138
|
+
expect(r.engines.length).toBeGreaterThan(0);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("no untested tell — every registry rule has a +/- fixture", () => {
|
|
143
|
+
for (const r of SLOP_RULES) {
|
|
144
|
+
expect(FIXTURES[r.id], `missing fixture for ${r.id}`).toBeDefined();
|
|
145
|
+
}
|
|
146
|
+
// and no orphan fixtures
|
|
147
|
+
const ids = new Set(SLOP_RULES.map((r) => r.id));
|
|
148
|
+
for (const k of Object.keys(FIXTURES)) {
|
|
149
|
+
expect(ids.has(k), `orphan fixture ${k}`).toBe(true);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe("positive fixtures fire, negative fixtures are clean", () => {
|
|
154
|
+
for (const r of SLOP_RULES) {
|
|
155
|
+
const fx = FIXTURES[r.id];
|
|
156
|
+
if (!fx) continue;
|
|
157
|
+
it(`${r.id} (${r.catalogId})`, () => {
|
|
158
|
+
expect(findingsFor(r.id, fx.positive, fx.ext).length, "positive must fire").toBeGreaterThan(0);
|
|
159
|
+
expect(findingsFor(r.id, fx.negative, fx.ext).length, "negative must be clean").toBe(0);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe("context gates suppress when DESIGN.md declares intent", () => {
|
|
166
|
+
it("t7 default-font is suppressed when DESIGN.md adopts Inter", () => {
|
|
167
|
+
const fx = FIXTURES["slop-t7-default-fonts"]!;
|
|
168
|
+
expect(findingsFor("slop-t7-default-fonts", fx.positive, "css", NO_CTX).length).toBeGreaterThan(0);
|
|
169
|
+
expect(
|
|
170
|
+
findingsFor("slop-t7-default-fonts", fx.positive, "css", ctxWith("Body font: Inter (chosen for variable metrics in a data-dense dashboard)")).length,
|
|
171
|
+
).toBe(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it("c5 cream-palette is suppressed under a declared warm-neutral language", () => {
|
|
175
|
+
const fx = FIXTURES["slop-c5-cream-palette"]!;
|
|
176
|
+
expect(findingsFor("slop-c5-cream-palette", fx.positive, "css", NO_CTX).length).toBeGreaterThan(0);
|
|
177
|
+
expect(
|
|
178
|
+
findingsFor("slop-c5-cream-palette", fx.positive, "css", ctxWith("Palette: warm-neutral, first-party")).length,
|
|
179
|
+
).toBe(0);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe("inline-ignore", () => {
|
|
184
|
+
it("design-slop-disable-next-line suppresses the next line", () => {
|
|
185
|
+
const css = "/* design-slop-disable-next-line slop-m4-transition-all */\n.x { transition: all 200ms; }";
|
|
186
|
+
expect(findingsFor("slop-m4-transition-all", css, "css").length).toBe(0);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("file-scope design-slop-disable suppresses the whole file", () => {
|
|
190
|
+
const css = "/* design-slop-disable slop-l8-zindex-magic */\n.a{z-index:9999}\n.b{z-index:999}";
|
|
191
|
+
expect(findingsFor("slop-l8-zindex-magic", css, "css").length).toBe(0);
|
|
192
|
+
});
|
|
193
|
+
});
|