@ryuenn3123/agentic-senior-core 3.0.17 → 3.0.20
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/.agent-context/prompts/bootstrap-design.md +84 -94
- package/.agent-context/prompts/init-project.md +32 -100
- package/.agent-context/prompts/refactor.md +22 -44
- package/.agent-context/prompts/review-code.md +28 -52
- package/.agent-context/review-checklists/architecture-review.md +31 -62
- package/.agent-context/review-checklists/pr-checklist.md +74 -108
- package/.agent-context/rules/api-docs.md +18 -206
- package/.agent-context/rules/architecture.md +40 -207
- package/.agent-context/rules/database-design.md +10 -199
- package/.agent-context/rules/docker-runtime.md +5 -5
- package/.agent-context/rules/efficiency-vs-hype.md +11 -149
- package/.agent-context/rules/error-handling.md +9 -231
- package/.agent-context/rules/event-driven.md +17 -221
- package/.agent-context/rules/frontend-architecture.md +66 -119
- package/.agent-context/rules/git-workflow.md +1 -1
- package/.agent-context/rules/microservices.md +28 -161
- package/.agent-context/rules/naming-conv.md +8 -138
- package/.agent-context/rules/performance.md +9 -175
- package/.agent-context/rules/realtime.md +11 -44
- package/.agent-context/rules/security.md +11 -295
- package/.agent-context/rules/testing.md +9 -174
- package/.agent-context/state/benchmark-analysis.json +3 -3
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agent-context/state/onboarding-report.json +71 -11
- package/.agents/workflows/init-project.md +7 -24
- package/.agents/workflows/refactor.md +7 -24
- package/.agents/workflows/review-code.md +7 -24
- package/.cursorrules +22 -21
- package/.gemini/instructions.md +2 -2
- package/.github/copilot-instructions.md +2 -2
- package/.instructions.md +112 -213
- package/.windsurfrules +22 -21
- package/AGENTS.md +4 -4
- package/CONTRIBUTING.md +13 -22
- package/README.md +6 -20
- package/lib/cli/commands/init.mjs +102 -148
- package/lib/cli/commands/launch.mjs +3 -3
- package/lib/cli/commands/optimize.mjs +14 -4
- package/lib/cli/commands/upgrade.mjs +25 -23
- package/lib/cli/compiler.mjs +96 -62
- package/lib/cli/constants.mjs +28 -136
- package/lib/cli/detector/design-evidence.mjs +189 -6
- package/lib/cli/detector.mjs +6 -7
- package/lib/cli/init-detection-flow.mjs +10 -93
- package/lib/cli/init-selection.mjs +2 -68
- package/lib/cli/project-scaffolder/constants.mjs +1 -1
- package/lib/cli/project-scaffolder/design-contract.mjs +438 -335
- package/lib/cli/project-scaffolder/discovery.mjs +36 -82
- package/lib/cli/project-scaffolder/prompt-builders.mjs +55 -63
- package/lib/cli/project-scaffolder/storage.mjs +0 -4
- package/lib/cli/token-optimization.mjs +1 -1
- package/lib/cli/utils.mjs +75 -9
- package/package.json +2 -2
- package/scripts/detection-benchmark.mjs +4 -15
- package/scripts/documentation-boundary-audit.mjs +9 -9
- package/scripts/explain-on-demand-audit.mjs +11 -11
- package/scripts/forbidden-content-check.mjs +9 -9
- package/scripts/frontend-usability-audit.mjs +57 -36
- package/scripts/llm-judge.mjs +1 -1
- package/scripts/mcp-server/constants.mjs +60 -0
- package/scripts/mcp-server/tool-registry.mjs +149 -0
- package/scripts/mcp-server/tools.mjs +446 -0
- package/scripts/mcp-server.mjs +23 -661
- package/scripts/release-gate/audit-checks.mjs +426 -0
- package/scripts/release-gate/constants.mjs +53 -0
- package/scripts/release-gate/runtime.mjs +63 -0
- package/scripts/release-gate/static-checks.mjs +182 -0
- package/scripts/release-gate.mjs +13 -794
- package/scripts/rules-guardian-audit.mjs +14 -13
- package/scripts/single-source-lazy-loading-audit.mjs +3 -3
- package/scripts/sync-thin-adapters.mjs +5 -5
- package/scripts/ui-design-judge/constants.mjs +24 -0
- package/scripts/ui-design-judge/design-execution-summary.mjs +259 -0
- package/scripts/ui-design-judge/git-input.mjs +131 -0
- package/scripts/ui-design-judge/prompting.mjs +73 -0
- package/scripts/ui-design-judge/providers.mjs +102 -0
- package/scripts/ui-design-judge/reporting.mjs +182 -0
- package/scripts/ui-design-judge/rubric-calibration.mjs +214 -0
- package/scripts/ui-design-judge/rubric-goldset.json +188 -0
- package/scripts/ui-design-judge.mjs +166 -771
- package/scripts/ui-rubric-calibration.mjs +35 -0
- package/scripts/validate/config.mjs +198 -55
- package/scripts/validate/coverage-checks.mjs +32 -7
- package/scripts/validate.mjs +8 -4
- package/lib/cli/architect.mjs +0 -431
|
@@ -7,15 +7,6 @@
|
|
|
7
7
|
* Publishes top-1 accuracy and manual-correction-rate proxy.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
const BLUEPRINT_RECOMMENDATIONS = {
|
|
11
|
-
'typescript.md': 'api-nextjs.md',
|
|
12
|
-
'python.md': 'fastapi-service.md',
|
|
13
|
-
'java.md': 'spring-boot-api.md',
|
|
14
|
-
'php.md': 'laravel-api.md',
|
|
15
|
-
'go.md': 'go-service.md',
|
|
16
|
-
'csharp.md': 'aspnet-api.md',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
10
|
const AMBIGUITY_THRESHOLD = 0.08;
|
|
20
11
|
|
|
21
12
|
const BENCHMARK_FIXTURES = [
|
|
@@ -71,8 +62,7 @@ function detectProjectFromMarkers(markers) {
|
|
|
71
62
|
|
|
72
63
|
if (candidates.length === 0) {
|
|
73
64
|
return {
|
|
74
|
-
|
|
75
|
-
recommendedBlueprint: null,
|
|
65
|
+
detectedStack: null,
|
|
76
66
|
confidenceScore: 0,
|
|
77
67
|
confidenceGap: 0,
|
|
78
68
|
needsManualCorrection: true,
|
|
@@ -87,8 +77,7 @@ function detectProjectFromMarkers(markers) {
|
|
|
87
77
|
: Number(strongestCandidate.confidenceScore.toFixed(2));
|
|
88
78
|
|
|
89
79
|
return {
|
|
90
|
-
|
|
91
|
-
recommendedBlueprint: BLUEPRINT_RECOMMENDATIONS[strongestCandidate.stackFileName] || null,
|
|
80
|
+
detectedStack: strongestCandidate.stackFileName,
|
|
92
81
|
confidenceScore: strongestCandidate.confidenceScore,
|
|
93
82
|
confidenceGap,
|
|
94
83
|
needsManualCorrection: confidenceGap < AMBIGUITY_THRESHOLD,
|
|
@@ -101,7 +90,7 @@ function runBenchmark() {
|
|
|
101
90
|
|
|
102
91
|
const fixtureResults = BENCHMARK_FIXTURES.map((benchmarkFixture) => {
|
|
103
92
|
const detectionResult = detectProjectFromMarkers(benchmarkFixture.markers);
|
|
104
|
-
const isCorrect = detectionResult.
|
|
93
|
+
const isCorrect = detectionResult.detectedStack === benchmarkFixture.expectedStack;
|
|
105
94
|
|
|
106
95
|
if (isCorrect) {
|
|
107
96
|
passingFixtureCount += 1;
|
|
@@ -114,7 +103,7 @@ function runBenchmark() {
|
|
|
114
103
|
return {
|
|
115
104
|
fixtureName: benchmarkFixture.fixtureName,
|
|
116
105
|
expectedStack: benchmarkFixture.expectedStack,
|
|
117
|
-
detectedStack: detectionResult.
|
|
106
|
+
detectedStack: detectionResult.detectedStack,
|
|
118
107
|
confidenceGap: detectionResult.confidenceGap,
|
|
119
108
|
needsManualCorrection: detectionResult.needsManualCorrection,
|
|
120
109
|
isCorrect,
|
|
@@ -29,7 +29,7 @@ const BOUNDARY_RULES = [
|
|
|
29
29
|
{
|
|
30
30
|
boundaryName: 'public-surface',
|
|
31
31
|
requirement: 'Public surface changes must update README.md, CHANGELOG.md, or docs/* in the same scope.',
|
|
32
|
-
|
|
32
|
+
requiredDocumentationUpdates: [
|
|
33
33
|
'README.md',
|
|
34
34
|
'CHANGELOG.md',
|
|
35
35
|
'docs/architecture-decision-record.md',
|
|
@@ -45,7 +45,7 @@ const BOUNDARY_RULES = [
|
|
|
45
45
|
{
|
|
46
46
|
boundaryName: 'api-contract',
|
|
47
47
|
requirement: 'API endpoint or contract changes must update API/OpenAPI documentation in the same scope.',
|
|
48
|
-
|
|
48
|
+
requiredDocumentationUpdates: [
|
|
49
49
|
'docs/api-contract.md',
|
|
50
50
|
'docs/flow-overview.md',
|
|
51
51
|
'.agent-context/rules/api-docs.md',
|
|
@@ -67,7 +67,7 @@ const BOUNDARY_RULES = [
|
|
|
67
67
|
{
|
|
68
68
|
boundaryName: 'database-structure',
|
|
69
69
|
requirement: 'Database structure changes must update schema or migration documentation in the same scope.',
|
|
70
|
-
|
|
70
|
+
requiredDocumentationUpdates: [
|
|
71
71
|
'docs/database-schema.md',
|
|
72
72
|
'docs/flow-overview.md',
|
|
73
73
|
'.agent-context/rules/database-design.md',
|
|
@@ -163,8 +163,8 @@ function isDocumentationFilePath(filePath) {
|
|
|
163
163
|
|
|
164
164
|
function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles) {
|
|
165
165
|
const boundaryChangedFiles = changedFiles.filter((filePath) => boundaryRule.trigger(filePath));
|
|
166
|
-
const expectedDocumentationPaths = Array.isArray(boundaryRule.
|
|
167
|
-
? boundaryRule.
|
|
166
|
+
const expectedDocumentationPaths = Array.isArray(boundaryRule.requiredDocumentationUpdates)
|
|
167
|
+
? boundaryRule.requiredDocumentationUpdates
|
|
168
168
|
: [];
|
|
169
169
|
|
|
170
170
|
if (boundaryChangedFiles.length === 0) {
|
|
@@ -177,14 +177,14 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
177
177
|
documentationFiles: [],
|
|
178
178
|
expectedDocumentationPaths,
|
|
179
179
|
missingDocumentationUpdates: false,
|
|
180
|
-
|
|
180
|
+
requiredActions: [],
|
|
181
181
|
details: 'Boundary not triggered by changed scope.',
|
|
182
182
|
};
|
|
183
183
|
}
|
|
184
184
|
|
|
185
185
|
const matchingDocumentationFiles = changedDocumentationFiles.filter((filePath) => boundaryRule.docsMatcher(filePath));
|
|
186
186
|
const boundaryPassed = matchingDocumentationFiles.length > 0;
|
|
187
|
-
const
|
|
187
|
+
const requiredActions = boundaryPassed
|
|
188
188
|
? []
|
|
189
189
|
: [
|
|
190
190
|
`Update one or more boundary docs: ${expectedDocumentationPaths.join(', ')}`,
|
|
@@ -204,7 +204,7 @@ function evaluateBoundary(boundaryRule, changedFiles, changedDocumentationFiles)
|
|
|
204
204
|
documentationFiles: matchingDocumentationFiles,
|
|
205
205
|
expectedDocumentationPaths,
|
|
206
206
|
missingDocumentationUpdates: !boundaryPassed,
|
|
207
|
-
|
|
207
|
+
requiredActions,
|
|
208
208
|
details,
|
|
209
209
|
};
|
|
210
210
|
}
|
|
@@ -225,7 +225,7 @@ function runDocumentationBoundaryAudit() {
|
|
|
225
225
|
requirement: boundaryResult.requirement,
|
|
226
226
|
changedFiles: boundaryResult.changedFiles,
|
|
227
227
|
expectedDocumentationPaths: boundaryResult.expectedDocumentationPaths,
|
|
228
|
-
|
|
228
|
+
requiredActions: boundaryResult.requiredActions,
|
|
229
229
|
diagnosticCode: `BOUNDARY_${boundaryResult.boundaryName.toUpperCase().replace(/-/g, '_')}_DOCS_SYNC_REQUIRED`,
|
|
230
230
|
}));
|
|
231
231
|
|
|
@@ -39,7 +39,7 @@ const REQUIRED_PR_CHECKLIST_SNIPPETS = [
|
|
|
39
39
|
];
|
|
40
40
|
|
|
41
41
|
const REQUIRED_REVIEW_PROMPT_SNIPPETS = [
|
|
42
|
-
'
|
|
42
|
+
'Review the code with a production-risk mindset.',
|
|
43
43
|
];
|
|
44
44
|
|
|
45
45
|
const INTERNAL_STATE_SIGNAL_PATTERNS = [
|
|
@@ -225,11 +225,11 @@ function assertSnippetCoverage(sourceLabel, sourcePath, requiredSnippets, failur
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
function buildDefaultResponseSummary(onboardingReport) {
|
|
228
|
-
const
|
|
229
|
-
const
|
|
228
|
+
const runtimeDecision = String(onboardingReport?.runtimeDecision?.mode || onboardingReport?.selectedStack || 'unknown-runtime-decision').trim() || 'unknown-runtime-decision';
|
|
229
|
+
const architectureDecision = String(onboardingReport?.architectureDecision?.mode || onboardingReport?.selectedBlueprint || 'unknown-architecture-decision').trim() || 'unknown-architecture-decision';
|
|
230
230
|
const selectedProfile = String(onboardingReport?.selectedProfile || 'unknown-profile').trim() || 'unknown-profile';
|
|
231
231
|
|
|
232
|
-
return `Active setup summary:
|
|
232
|
+
return `Active setup summary: runtimeDecision=${runtimeDecision}, architectureDecision=${architectureDecision}, profile=${selectedProfile}.`;
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
function detectInternalSignals(textValue) {
|
|
@@ -240,14 +240,14 @@ function detectInternalSignals(textValue) {
|
|
|
240
240
|
function buildDiagnosticDecisionSummaries(onboardingReport) {
|
|
241
241
|
const explanations = [];
|
|
242
242
|
|
|
243
|
-
const
|
|
244
|
-
if (
|
|
245
|
-
explanations.push(`
|
|
243
|
+
const runtimeDecision = String(onboardingReport?.runtimeDecision?.mode || onboardingReport?.selectedStack || '').trim();
|
|
244
|
+
if (runtimeDecision) {
|
|
245
|
+
explanations.push(`Runtime decision: ${runtimeDecision}.`);
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
250
|
-
explanations.push(`
|
|
248
|
+
const architectureDecision = String(onboardingReport?.architectureDecision?.mode || onboardingReport?.selectedBlueprint || '').trim();
|
|
249
|
+
if (architectureDecision) {
|
|
250
|
+
explanations.push(`Architecture decision: ${architectureDecision}.`);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
const selectedProfile = String(onboardingReport?.selectedProfile || '').trim();
|
|
@@ -423,4 +423,4 @@ function runAudit() {
|
|
|
423
423
|
process.exit(reportPayload.passed ? 0 : 1);
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
runAudit();
|
|
426
|
+
runAudit();
|
|
@@ -15,22 +15,22 @@ const FORBIDDEN_PATTERNS = [
|
|
|
15
15
|
{
|
|
16
16
|
name: 'Hardcoded API Key',
|
|
17
17
|
regex: /api_?key\s*[:=]\s*['"][a-zA-Z0-9_\-]{16,}['"]/i,
|
|
18
|
-
|
|
18
|
+
requiredAction: 'API Keys must be provided via environment variables (process.env) or config files, never hardcoded.'
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
name: 'Hardcoded Password',
|
|
22
22
|
regex: /password\s*[:=]\s*['"][^'"]+['"]/i,
|
|
23
|
-
|
|
23
|
+
requiredAction: 'Passwords must be injected via secret managers or environment variables.'
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: 'Absolute Local Desktop Path',
|
|
27
27
|
regex: /file:\/\/\/?([c-zC-Z]:|\/Users\/|\/home\/)/,
|
|
28
|
-
|
|
28
|
+
requiredAction: 'Do not commit local absolute file paths. Use relative paths or process.cwd().'
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: 'Stray Breakpoint (debugger)',
|
|
32
32
|
regex: /\bdebugger\s*;?/,
|
|
33
|
-
|
|
33
|
+
requiredAction: 'Remove debug breakpoints before publishing to production.'
|
|
34
34
|
}
|
|
35
35
|
];
|
|
36
36
|
|
|
@@ -48,7 +48,7 @@ function scanFile(filePath) {
|
|
|
48
48
|
line: i + 1,
|
|
49
49
|
content: line.trim().substring(0, 80), // truncate long lines
|
|
50
50
|
rule: pattern.name,
|
|
51
|
-
|
|
51
|
+
requiredAction: pattern.requiredAction
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -97,12 +97,12 @@ async function runCheck() {
|
|
|
97
97
|
|
|
98
98
|
if (violations.length > 0) {
|
|
99
99
|
const relPath = relative(ROOT_DIR, file);
|
|
100
|
-
console.error(`\
|
|
100
|
+
console.error(`\nFORBIDDEN CONTENT DETECTED IN: ${relPath}`);
|
|
101
101
|
|
|
102
102
|
for (const v of violations) {
|
|
103
103
|
console.error(` Line ${v.line}: [${v.rule}]`);
|
|
104
104
|
console.error(` > ${v.content}`);
|
|
105
|
-
console.error(` Action required: ${v.
|
|
105
|
+
console.error(` Action required: ${v.requiredAction}`);
|
|
106
106
|
totalViolations++;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -112,10 +112,10 @@ async function runCheck() {
|
|
|
112
112
|
console.log(`\nScanned ${filesScanned.length} files across ${SCAN_DIRECTORIES.length} source directories.`);
|
|
113
113
|
|
|
114
114
|
if (totalViolations > 0) {
|
|
115
|
-
console.error(`\
|
|
115
|
+
console.error(`\nPUBLISH ABORTED: Found ${totalViolations} forbidden content violation(s).`);
|
|
116
116
|
process.exit(1);
|
|
117
117
|
} else {
|
|
118
|
-
console.log('
|
|
118
|
+
console.log('Clean. No forbidden content detected.');
|
|
119
119
|
process.exit(0);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
@@ -23,6 +23,9 @@ const REQUIRED_FILES = [
|
|
|
23
23
|
'.instructions.md',
|
|
24
24
|
'.agent-context/prompts/bootstrap-design.md',
|
|
25
25
|
'scripts/ui-design-judge.mjs',
|
|
26
|
+
'scripts/ui-rubric-calibration.mjs',
|
|
27
|
+
'scripts/ui-design-judge/rubric-calibration.mjs',
|
|
28
|
+
'scripts/ui-design-judge/rubric-goldset.json',
|
|
26
29
|
'.agent-context/rules/frontend-architecture.md',
|
|
27
30
|
'.agent-context/review-checklists/pr-checklist.md',
|
|
28
31
|
'.agent-context/review-checklists/architecture-review.md',
|
|
@@ -50,63 +53,77 @@ const REQUIRED_ARCHITECTURE_CHECKLIST_SNIPPETS = [
|
|
|
50
53
|
];
|
|
51
54
|
|
|
52
55
|
const REQUIRED_FRONTEND_RULE_SNIPPETS = [
|
|
53
|
-
'Frontend
|
|
54
|
-
'UI
|
|
55
|
-
'
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'
|
|
56
|
+
'Frontend Design and Interaction Boundaries',
|
|
57
|
+
'UI work must load the smallest relevant surface, not the entire engineering handbook.',
|
|
58
|
+
'## Auto Activation',
|
|
59
|
+
'UI scope triggers:',
|
|
60
|
+
'Do not use this file to teach generic frontend basics the model already knows.',
|
|
61
|
+
'## Source Hygiene and Source Boundaries',
|
|
62
|
+
'This rule guides the LLM; it must not choose the final style',
|
|
59
63
|
'Design continuity is opt-in.',
|
|
60
|
-
'
|
|
61
|
-
'
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
67
|
-
'
|
|
68
|
-
'Responsive
|
|
64
|
+
'Repo evidence outranks memory residue every time.',
|
|
65
|
+
'## Accessibility Split',
|
|
66
|
+
'Treat WCAG 2.2 AA as the hard compliance floor.',
|
|
67
|
+
'Treat APCA as advisory perceptual tuning only.',
|
|
68
|
+
'## Anti-Generic UI Boundaries',
|
|
69
|
+
'Do not default to interchangeable dashboard chrome',
|
|
70
|
+
'Do not let repeated surfaces share the same visual treatment by habit.',
|
|
71
|
+
'Do not use default framework button and input treatment as the final UI language.',
|
|
72
|
+
'## Responsive Mutation Requirements',
|
|
73
|
+
'Responsive quality is not allowed to be scale-only.',
|
|
74
|
+
'## Surface and Morphology Requirements',
|
|
75
|
+
'Define the primary user task or reading path from current evidence',
|
|
76
|
+
'## Implementation Boundaries',
|
|
77
|
+
'Do not hardcode Zustand, React Query, smart/dumb component doctrine',
|
|
69
78
|
];
|
|
70
79
|
|
|
71
80
|
const REQUIRED_BOOTSTRAP_DESIGN_SNIPPETS = [
|
|
72
|
-
'
|
|
73
|
-
'
|
|
81
|
+
'This contract is a decision scaffold, not a style preset.',
|
|
82
|
+
'We guide the agent; we do not pick the final style',
|
|
83
|
+
'Responsive Recomposition Plan',
|
|
74
84
|
'Token Architecture and Alias Strategy',
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
'
|
|
81
|
-
'
|
|
82
|
-
'
|
|
83
|
-
'
|
|
84
|
-
'
|
|
85
|
-
'APCA only as advisory perceptual tuning',
|
|
86
|
-
'Hybrid visual QA must stay deterministic-first',
|
|
85
|
+
'repoEvidence.designEvidenceSummary',
|
|
86
|
+
'research current official docs',
|
|
87
|
+
'Responsive design means recomposition, not resizing.',
|
|
88
|
+
'agent-chosen visual direction',
|
|
89
|
+
'viewport mutation rules',
|
|
90
|
+
'WCAG 2.2 AA is the hard floor',
|
|
91
|
+
'APCA may be used only as advisory perceptual tuning',
|
|
92
|
+
'unresearched dependency choices',
|
|
93
|
+
'default component-kit styling without product rationale',
|
|
94
|
+
'genericity findings that cannot name the exact drift signal',
|
|
87
95
|
];
|
|
88
96
|
|
|
89
97
|
const REQUIRED_UI_DESIGN_JUDGE_SNIPPETS = [
|
|
90
|
-
'Advisory-
|
|
98
|
+
'Advisory-default UI design contract judge.',
|
|
91
99
|
'Repo-internal workflow audit; no user-facing runtime modes.',
|
|
92
|
-
'
|
|
100
|
+
'genericityAutoFail',
|
|
101
|
+
'blocking required actions',
|
|
93
102
|
'Do not reward generic SaaS defaults or popular template patterns.',
|
|
94
103
|
'UI design judge only evaluates changed UI surfaces.',
|
|
95
|
-
'
|
|
96
|
-
'
|
|
97
|
-
'
|
|
104
|
+
'Structured design execution summary was supplied to semantic review.',
|
|
105
|
+
'designExecutionSignalCount',
|
|
106
|
+
'designExecutionPolicy',
|
|
107
|
+
'designExecutionHandoff',
|
|
108
|
+
'reviewRubric',
|
|
109
|
+
'genericityStatus',
|
|
110
|
+
'handoffReady',
|
|
111
|
+
'calibratedStatus',
|
|
112
|
+
'structuredInspectionAvailable',
|
|
113
|
+
'applyGenericityAutoFail',
|
|
98
114
|
];
|
|
99
115
|
|
|
100
116
|
const REQUIRED_INSTRUCTIONS_SNIPPETS = [
|
|
101
117
|
'UI Design Mode',
|
|
118
|
+
'Resolve the smallest relevant layer set for the current request.',
|
|
102
119
|
'bootstrap-design.md',
|
|
103
120
|
'frontend-architecture.md',
|
|
104
121
|
'do not eagerly load unrelated backend-only rules',
|
|
105
122
|
'valid style context',
|
|
106
|
-
'
|
|
123
|
+
'External references, prior-chat memory, unrelated-project visuals, and remembered screenshots are tainted',
|
|
107
124
|
'WCAG 2.2 AA as the hard compliance floor',
|
|
108
125
|
'APCA as advisory perceptual tuning only',
|
|
109
|
-
'
|
|
126
|
+
'Do not require screenshot capture as a baseline dependency',
|
|
110
127
|
];
|
|
111
128
|
|
|
112
129
|
const REQUIRED_DESIGN_EVIDENCE_SNIPPETS = [
|
|
@@ -114,6 +131,9 @@ const REQUIRED_DESIGN_EVIDENCE_SNIPPETS = [
|
|
|
114
131
|
"source: 'lightweight-static-scan'",
|
|
115
132
|
'cssVariables',
|
|
116
133
|
'componentInventory',
|
|
134
|
+
'structuredInspection',
|
|
135
|
+
'classAttributeCount',
|
|
136
|
+
'inlineStyleObjectCount',
|
|
117
137
|
'tokenBypassSignals',
|
|
118
138
|
];
|
|
119
139
|
|
|
@@ -243,6 +263,7 @@ function runAudit() {
|
|
|
243
263
|
extractorIncludesSummaryVersion: designEvidenceExtractorContent.includes('summaryVersion'),
|
|
244
264
|
extractorIncludesCssVariables: designEvidenceExtractorContent.includes('cssVariables'),
|
|
245
265
|
extractorIncludesComponentInventory: designEvidenceExtractorContent.includes('componentInventory'),
|
|
266
|
+
extractorIncludesStructuredInspection: designEvidenceExtractorContent.includes('structuredInspection'),
|
|
246
267
|
extractorIncludesTokenBypassSignals: designEvidenceExtractorContent.includes('tokenBypassSignals'),
|
|
247
268
|
compilerProjectsFrontendEvidenceMetrics: compilerContent.includes('frontendEvidenceMetrics'),
|
|
248
269
|
compilerProjectsDesignEvidenceSummary: compilerContent.includes('designEvidenceSummary'),
|
package/scripts/llm-judge.mjs
CHANGED
|
@@ -242,7 +242,7 @@ You must categorize each violation with a severity level: critical, high, medium
|
|
|
242
242
|
- critical: Security vulnerabilities (hardcoded secrets, SQL/command injection, missing auth checks, CORS), unvalidated external inputs.
|
|
243
243
|
- high: N+1 database queries, swallowed errors (empty catch blocks without re-throw/recovery), layer boundary violations.
|
|
244
244
|
- medium: TypeScript \`any\` type used without justification, missing test coverage, bad architectural patterns.
|
|
245
|
-
- low: Style preferences, minor naming nitpicks, documentation
|
|
245
|
+
- low: Style preferences, minor naming nitpicks, documentation nitpicks, performance micro-optimizations.
|
|
246
246
|
|
|
247
247
|
## Mandatory output format:
|
|
248
248
|
You MUST output your findings in EXACTLY this structure:
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
|
|
8
|
+
export const REPOSITORY_ROOT = resolve(dirname(SCRIPT_FILE_PATH), '..', '..');
|
|
9
|
+
export const STATE_DIRECTORY = resolve(REPOSITORY_ROOT, '.agent-context', 'state');
|
|
10
|
+
export const DEFAULT_PROTOCOL_VERSION = '2024-11-05';
|
|
11
|
+
export const DEFAULT_FETCH_TIMEOUT_MS = 15000;
|
|
12
|
+
export const DEFAULT_FETCH_MAX_CHARS = 6000;
|
|
13
|
+
export const MAX_FETCH_MAX_CHARS = 20000;
|
|
14
|
+
export const DEFAULT_TREND_WINDOW_DAYS = 90;
|
|
15
|
+
export const MAX_TREND_PACKAGES = 10;
|
|
16
|
+
export const FALLBACK_PACKAGE_VERSION = '0.0.0-local';
|
|
17
|
+
|
|
18
|
+
function resolvePackageVersion() {
|
|
19
|
+
try {
|
|
20
|
+
const parsedPackageManifest = JSON.parse(
|
|
21
|
+
readFileSync(resolve(REPOSITORY_ROOT, 'package.json'), 'utf8')
|
|
22
|
+
);
|
|
23
|
+
const rawVersion = typeof parsedPackageManifest?.version === 'string'
|
|
24
|
+
? parsedPackageManifest.version.trim()
|
|
25
|
+
: '';
|
|
26
|
+
|
|
27
|
+
return rawVersion || FALLBACK_PACKAGE_VERSION;
|
|
28
|
+
} catch {
|
|
29
|
+
return FALLBACK_PACKAGE_VERSION;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const PACKAGE_VERSION = resolvePackageVersion();
|
|
34
|
+
|
|
35
|
+
export const TEST_SUITE_ARGS = {
|
|
36
|
+
full: ['--test', './tests/cli-smoke.test.mjs', './tests/mcp-server.test.mjs', './tests/llm-judge.test.mjs', './tests/operations.test.mjs'],
|
|
37
|
+
cli: ['--test', './tests/cli-smoke.test.mjs'],
|
|
38
|
+
operations: ['--test', './tests/operations.test.mjs'],
|
|
39
|
+
'llm-judge': ['--test', './tests/llm-judge.test.mjs'],
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const INTERNAL_SCRIPT_PATHS = {
|
|
43
|
+
validate: resolve(REPOSITORY_ROOT, 'scripts', 'validate.mjs'),
|
|
44
|
+
release_gate: resolve(REPOSITORY_ROOT, 'scripts', 'release-gate.mjs'),
|
|
45
|
+
forbidden_content_check: resolve(REPOSITORY_ROOT, 'scripts', 'forbidden-content-check.mjs'),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function getAvailableTestSuites() {
|
|
49
|
+
return Object.entries(TEST_SUITE_ARGS)
|
|
50
|
+
.filter(([, commandArguments]) => (
|
|
51
|
+
Array.isArray(commandArguments)
|
|
52
|
+
&& commandArguments.length > 1
|
|
53
|
+
&& commandArguments
|
|
54
|
+
.slice(1)
|
|
55
|
+
.every((relativeTestPath) => existsSync(resolve(REPOSITORY_ROOT, relativeTestPath)))
|
|
56
|
+
))
|
|
57
|
+
.map(([suiteName]) => suiteName);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const AVAILABLE_TEST_SUITES = getAvailableTestSuites();
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { AVAILABLE_TEST_SUITES, INTERNAL_SCRIPT_PATHS } from './constants.mjs';
|
|
5
|
+
|
|
6
|
+
export function buildToolDefinitions() {
|
|
7
|
+
const toolDefinitions = [];
|
|
8
|
+
|
|
9
|
+
if (existsSync(INTERNAL_SCRIPT_PATHS.validate)) {
|
|
10
|
+
toolDefinitions.push({
|
|
11
|
+
name: 'validate',
|
|
12
|
+
description: 'Run repository validation checks.',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {},
|
|
16
|
+
additionalProperties: false,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (AVAILABLE_TEST_SUITES.length > 0) {
|
|
22
|
+
toolDefinitions.push({
|
|
23
|
+
name: 'test',
|
|
24
|
+
description: 'Run test suites (full or targeted).',
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
suite: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
enum: AVAILABLE_TEST_SUITES,
|
|
31
|
+
description: 'Target test suite. Defaults to the first available suite.',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
additionalProperties: false,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (existsSync(INTERNAL_SCRIPT_PATHS.release_gate)) {
|
|
40
|
+
toolDefinitions.push({
|
|
41
|
+
name: 'release_gate',
|
|
42
|
+
description: 'Run release gate checks.',
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {},
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (existsSync(INTERNAL_SCRIPT_PATHS.forbidden_content_check)) {
|
|
52
|
+
toolDefinitions.push({
|
|
53
|
+
name: 'forbidden_content_check',
|
|
54
|
+
description: 'Run forbidden content scan used by publish gate.',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {},
|
|
58
|
+
additionalProperties: false,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
toolDefinitions.push(
|
|
64
|
+
{
|
|
65
|
+
name: 'research_fetch',
|
|
66
|
+
description: 'Fetch external documentation/news content and return query-focused excerpts with citation metadata.',
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
url: {
|
|
71
|
+
type: 'string',
|
|
72
|
+
description: 'Absolute HTTP/HTTPS URL to fetch.',
|
|
73
|
+
},
|
|
74
|
+
query: {
|
|
75
|
+
type: 'string',
|
|
76
|
+
description: 'Optional search query used to extract focused excerpts.',
|
|
77
|
+
},
|
|
78
|
+
maxChars: {
|
|
79
|
+
type: 'integer',
|
|
80
|
+
description: 'Maximum characters to return when query is not provided (default 6000, max 20000).',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
required: ['url'],
|
|
84
|
+
additionalProperties: false,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'trend_snapshot',
|
|
89
|
+
description: 'Generate ecosystem trend snapshot from npm registry metadata with source timestamps.',
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
packages: {
|
|
94
|
+
type: 'array',
|
|
95
|
+
items: { type: 'string' },
|
|
96
|
+
description: 'Package names to inspect (max 10).',
|
|
97
|
+
},
|
|
98
|
+
windowDays: {
|
|
99
|
+
type: 'integer',
|
|
100
|
+
description: 'Release activity window in days (default 90).',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
required: ['packages'],
|
|
104
|
+
additionalProperties: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'state_read',
|
|
109
|
+
description: 'Read a file from .agent-context/state for cross-session continuity.',
|
|
110
|
+
inputSchema: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
path: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
description: 'Path relative to .agent-context/state, such as memory-continuity-benchmark.json.',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
required: ['path'],
|
|
119
|
+
additionalProperties: false,
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: 'state_write',
|
|
124
|
+
description: 'Write a file under .agent-context/state for cross-session continuity updates.',
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: 'object',
|
|
127
|
+
properties: {
|
|
128
|
+
path: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
description: 'Path relative to .agent-context/state.',
|
|
131
|
+
},
|
|
132
|
+
content: {
|
|
133
|
+
type: 'string',
|
|
134
|
+
description: 'UTF-8 content to write.',
|
|
135
|
+
},
|
|
136
|
+
mode: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
enum: ['overwrite', 'append'],
|
|
139
|
+
description: 'Write mode. Defaults to overwrite.',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
required: ['path', 'content'],
|
|
143
|
+
additionalProperties: false,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
return toolDefinitions;
|
|
149
|
+
}
|