feat: add six specialized Claude agent definitions under .claude/agents for audit, devii, docs, dry, fanout, and frontend maintenance
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
export const meta = {
|
||||
name: 'review',
|
||||
description: 'Read-only pre-commit review of the current git diff across every DevPlace quality dimension, with adversarial verification of each finding before it is reported',
|
||||
phases: [
|
||||
{ title: 'Diff', detail: 'collect the changed files and a summary of the diff' },
|
||||
{ title: 'Review', detail: 'each dimension reviews the diff in parallel' },
|
||||
{ title: 'Verify', detail: 'adversarially refute each candidate finding against source' },
|
||||
],
|
||||
}
|
||||
|
||||
const DIMENSIONS = [
|
||||
{ key: 'security', agent: 'security-maintainer' },
|
||||
{ key: 'audit', agent: 'audit-maintainer' },
|
||||
{ key: 'fanout', agent: 'fanout-maintainer' },
|
||||
{ key: 'style', agent: 'style-maintainer' },
|
||||
{ key: 'dry', agent: 'dry-maintainer' },
|
||||
{ key: 'frontend', agent: 'frontend-maintainer' },
|
||||
{ key: 'docs', agent: 'docs-maintainer' },
|
||||
{ key: 'seo', agent: 'seo-maintainer' },
|
||||
{ key: 'test', agent: 'test-maintainer' },
|
||||
]
|
||||
|
||||
const DIFF_SCHEMA = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['files'],
|
||||
properties: {
|
||||
base: { type: 'string' },
|
||||
files: { type: 'array', items: { type: 'string' } },
|
||||
summary: { type: 'string' },
|
||||
},
|
||||
}
|
||||
|
||||
const FINDINGS_SCHEMA = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['summary', 'findings'],
|
||||
properties: {
|
||||
summary: { type: 'string' },
|
||||
findings: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['severity', 'file', 'rule', 'message'],
|
||||
properties: {
|
||||
severity: { type: 'string', enum: ['error', 'warning', 'info'] },
|
||||
file: { type: 'string' },
|
||||
line: { type: 'integer' },
|
||||
rule: { type: 'string' },
|
||||
message: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const VERDICT_SCHEMA = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['isReal', 'reason'],
|
||||
properties: {
|
||||
isReal: { type: 'boolean' },
|
||||
reason: { type: 'string' },
|
||||
},
|
||||
}
|
||||
|
||||
function baseRef() {
|
||||
if (typeof args === 'string' && args.trim()) return args.trim()
|
||||
if (args && typeof args.base === 'string') return args.base
|
||||
return ''
|
||||
}
|
||||
|
||||
const base = baseRef()
|
||||
const diffCmd = base
|
||||
? `git diff ${base}... and git diff (unstaged) and git status --porcelain`
|
||||
: `git status --porcelain, git diff, and git diff --staged`
|
||||
|
||||
const diff = await agent(
|
||||
`Read-only. Collect the set of changed files in this repository for review using ${diffCmd}. Keep only existing files under devplacepy/ and tests/. Return the file list and a one-paragraph summary of what changed. Do not modify anything.`,
|
||||
{ agentType: 'Explore', label: 'diff', phase: 'Diff', schema: DIFF_SCHEMA }
|
||||
)
|
||||
|
||||
const files = (diff && diff.files) || []
|
||||
if (!files.length) {
|
||||
log('No changed files under devplacepy/ or tests/; nothing to review.')
|
||||
return { files: [], confirmed: [] }
|
||||
}
|
||||
|
||||
const fileList = files.join('\n')
|
||||
log(`Reviewing ${files.length} changed file(s) across ${DIMENSIONS.length} dimensions`)
|
||||
|
||||
const reviewed = await pipeline(
|
||||
DIMENSIONS,
|
||||
(dimension) =>
|
||||
agent(
|
||||
`Operate in REPORT mode (read-only). Review ONLY the changes in these files for your single dimension. Read the actual diff (git diff -- <file>) and enough surrounding context to judge intent. Confirm each finding against the source.\n\nChanged files:\n${fileList}`,
|
||||
{ agentType: dimension.agent, label: `review:${dimension.key}`, phase: 'Review', schema: FINDINGS_SCHEMA }
|
||||
),
|
||||
(review, dimension) =>
|
||||
parallel(
|
||||
((review && review.findings) || []).map((finding) => () =>
|
||||
agent(
|
||||
`Adversarially verify a candidate "${dimension.key}" review finding. Try to REFUTE it: open the file, read the changed region and its context, and decide if it is a genuine violation introduced by this diff. Rule it out (isReal=false) if it is a contract identifier, DATA rather than prose, vendored, pre-existing and untouched by this diff, or already correct under a known exemption. When uncertain, default to isReal=false.\n\nFinding:\n- file: ${finding.file}\n- line: ${finding.line == null ? 'unspecified' : finding.line}\n- severity: ${finding.severity}\n- rule: ${finding.rule}\n- message: ${finding.message}`,
|
||||
{ agentType: dimension.agent, label: `verify:${dimension.key}`, phase: 'Verify', schema: VERDICT_SCHEMA }
|
||||
).then((verdict) => ({ ...finding, dimension: dimension.key, verdict }))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
const candidates = reviewed.flat().filter(Boolean)
|
||||
const confirmed = candidates.filter((f) => f.verdict && f.verdict.isReal)
|
||||
const dropped = candidates.length - confirmed.length
|
||||
|
||||
log(`Review complete: ${confirmed.length} confirmed, ${dropped} refuted`)
|
||||
|
||||
return {
|
||||
base: base || 'working tree',
|
||||
files,
|
||||
candidates: candidates.length,
|
||||
confirmed,
|
||||
droppedAsFalsePositive: dropped,
|
||||
}
|
||||
Reference in New Issue
Block a user