feat: enforce mandatory rationale and role in explore/diagnosis schema output

- Remove oneOf string option from relevant_files/affected_files, require structured objects
- Add required fields: rationale (minLength 10), role/change_type enum
- Add optional fields: discovery_source, key_symbols
- Update all caller commands with new format instructions and success criteria
- Fix consumer code: Map-based dedup, getPath() helper, path extraction
- Fix frontend: f.rationale || f.reason backward-compatible fallback
This commit is contained in:
catlog22
2026-02-13 10:42:37 +08:00
parent 78f1d81516
commit e485f1d69b
16 changed files with 679 additions and 373 deletions

View File

@@ -248,7 +248,7 @@ function ContextContent({
<div className="space-y-0.5 pl-2 max-h-32 overflow-y-auto">
{ctx.relevant_files.map((f, i) => {
const filePath = typeof f === 'string' ? f : f.path;
const reason = typeof f === 'string' ? undefined : f.reason;
const reason = typeof f === 'string' ? undefined : (f.rationale || f.reason);
return (
<div key={i} className="group flex items-start gap-1 text-muted-foreground hover:bg-muted/30 rounded px-1 py-0.5">
<span className="text-primary/50 shrink-0">{i + 1}.</span>

View File

@@ -105,10 +105,11 @@ function extractString(val: unknown): string {
return String(val);
}
/** Extract a secondary description from an object (reason, description, etc.) */
/** Extract a secondary description from an object (rationale, reason, description, etc.) */
function extractReason(val: unknown): string | undefined {
if (!val || typeof val !== 'object') return undefined;
const obj = val as Record<string, unknown>;
if (typeof obj.rationale === 'string') return obj.rationale;
if (typeof obj.reason === 'string') return obj.reason;
if (typeof obj.description === 'string') return obj.description;
return undefined;