feat: Add Role Analysis Reviewer Agent and validation template

- Introduced Role Analysis Reviewer Agent to validate role analysis outputs against templates and quality standards.
- Created a detailed validation ruleset for the system-architect role, including mandatory and recommended sections.
- Added JSON validation report structure for output.
- Implemented execution command for validation process.

test: Add UX tests for HookCard component

- Created comprehensive tests for HookCard component, focusing on delete confirmation UX pattern.
- Verified confirmation dialog appearance, deletion functionality, and button interactions.
- Ensured proper handling of state updates and visual feedback for enabled/disabled status.

test: Add UX tests for ThemeSelector component

- Developed tests for ThemeSelector component, emphasizing delete confirmation UX pattern.
- Validated confirmation dialog display, deletion actions, and toast notifications for undo functionality.
- Ensured proper management of theme slots and state updates.

feat: Implement useDebounce hook

- Added useDebounce hook to delay expensive computations or API calls, enhancing performance.

feat: Create System Architect Analysis Template

- Developed a comprehensive template for system architect role analysis, covering required sections such as architecture overview, data model, state machine, error handling strategy, observability requirements, configuration model, and boundary scenarios.
- Included examples and templates for each section to guide users in producing SPEC.md-level precision modeling.
This commit is contained in:
catlog22
2026-03-05 19:58:10 +08:00
parent bc7a556985
commit 3fd55ebd4b
55 changed files with 4262 additions and 1138 deletions

View File

@@ -3,46 +3,93 @@
// ========================================
// Maps A2UI TextField component to shadcn/ui Input
import { useState, useCallback } from 'react';
import { useState, useCallback, useEffect } from 'react';
import { Input } from '@/components/ui/Input';
import { cn } from '@/lib/utils';
import type { ComponentRenderer } from '../../core/A2UIComponentRegistry';
import { resolveLiteralOrBinding } from '../A2UIRenderer';
import type { TextFieldComponent } from '../../core/A2UITypes';
/**
* A2UI TextField Component Renderer
* Two-way binding via onChange updates to local state
*/
export const A2UITextField: ComponentRenderer = ({ component, onAction, resolveBinding }) => {
const fieldComp = component as TextFieldComponent;
const { TextField: fieldConfig } = fieldComp;
// Resolve initial value from binding or use empty string
const initialValue = fieldConfig.value
? String(resolveLiteralOrBinding(fieldConfig.value, resolveBinding) ?? '')
: '';
// Local state for controlled input
const [localValue, setLocalValue] = useState(initialValue);
const [error, setError] = useState<string | null>(null);
const [touched, setTouched] = useState(false);
const validate = useCallback((value: string) => {
if (fieldConfig.required && !value) {
return 'This field is required.';
}
if (fieldConfig.minLength && value.length < fieldConfig.minLength) {
return `Must be at least ${fieldConfig.minLength} characters.`;
}
if (fieldConfig.maxLength && value.length > fieldConfig.maxLength) {
return `Must be at most ${fieldConfig.maxLength} characters.`;
}
if (fieldConfig.pattern && !new RegExp(fieldConfig.pattern).test(value)) {
return 'Invalid format.';
}
// `validator` is a placeholder for a more complex validation logic if needed
if (fieldConfig.validator) {
// Assuming validator is a regex string for simplicity
try {
if (!new RegExp(fieldConfig.validator).test(value)) {
return 'Custom validation failed.';
}
} catch (e) {
console.error('Invalid validator regex:', fieldConfig.validator);
}
}
return null;
}, [fieldConfig.required, fieldConfig.minLength, fieldConfig.maxLength, fieldConfig.pattern, fieldConfig.validator]);
useEffect(() => {
setLocalValue(initialValue);
// Re-validate when initial value changes
if (touched) {
setError(validate(initialValue));
}
}, [initialValue, touched, validate]);
// Handle change with two-way binding
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setLocalValue(newValue);
// Trigger action with new value
setError(validate(newValue));
onAction(fieldConfig.onChange.actionId, {
value: newValue,
...(fieldConfig.onChange.parameters || {}),
});
}, [fieldConfig.onChange, onAction]);
}, [fieldConfig.onChange, onAction, validate]);
const handleBlur = useCallback(() => {
setTouched(true);
setError(validate(localValue));
}, [localValue, validate]);
return (
<Input
type={fieldConfig.type || 'text'}
value={localValue}
onChange={handleChange}
placeholder={fieldConfig.placeholder}
/>
<div>
<Input
type={fieldConfig.type || 'text'}
value={localValue}
onChange={handleChange}
onBlur={handleBlur}
placeholder={fieldConfig.placeholder}
className={cn(touched && error && 'border-destructive')}
maxLength={fieldConfig.maxLength}
minLength={fieldConfig.minLength}
required={fieldConfig.required}
pattern={fieldConfig.pattern}
/>
{touched && error && (
<p className="text-xs text-destructive mt-1">{error}</p>
)}
</div>
);
};