diff --git a/src/cli/orchestrator.ts b/src/cli/orchestrator.ts index ee3cf08..9fd50a0 100644 --- a/src/cli/orchestrator.ts +++ b/src/cli/orchestrator.ts @@ -121,6 +121,7 @@ function reportIssue(params: ReportIssueParams): void { ruleName, outputFormat, jsonFormatter, + analysis, suggestion, fix, scoreText, @@ -165,6 +166,7 @@ function reportIssue(params: ReportIssueParams): void { message: summary, rule: ruleName, match: match || "", + ...(analysis ? { analysis } : {}), ...(suggestion ? { suggestion } : {}), ...(fix ? { fix } : {}), }; @@ -209,7 +211,7 @@ function locateAndReportViolations(params: ProcessViolationsParams): { for (const v of violations) { if (!v) continue; - const rowSummary = (v.analysis || "").trim(); + const rowSummary = (v.message || "").trim(); try { const locWithMatch = locateQuotedText( @@ -274,6 +276,7 @@ function locateAndReportViolations(params: ProcessViolationsParams): { ruleName, outputFormat, jsonFormatter, + ...(v.analysis !== undefined && { analysis: v.analysis }), ...(v.suggestion !== undefined && { suggestion: v.suggestion }), ...(v.fix !== undefined && { fix: v.fix }), scoreText, diff --git a/src/cli/types.ts b/src/cli/types.ts index 902ea2f..31c4b6d 100644 --- a/src/cli/types.ts +++ b/src/cli/types.ts @@ -68,6 +68,7 @@ export interface ReportIssueParams { ruleName: string; outputFormat: OutputFormat; jsonFormatter: ValeJsonFormatter | JsonFormatter | RdJsonFormatter; + analysis?: string; suggestion?: string; fix?: string; scoreText?: string; @@ -80,6 +81,7 @@ export interface ProcessViolationsParams extends EvaluationContext { quoted_text?: string; context_before?: string; context_after?: string; + message?: string; analysis?: string; suggestion?: string; fix?: string; diff --git a/src/output/json-formatter.ts b/src/output/json-formatter.ts index 54a7a64..eeddac6 100644 --- a/src/output/json-formatter.ts +++ b/src/output/json-formatter.ts @@ -23,6 +23,7 @@ export interface Issue { message: string; rule: string; match: string; + analysis?: string; suggestion?: string; fix?: string; } diff --git a/src/prompts/directive-loader.ts b/src/prompts/directive-loader.ts index f4ed43b..13e28ca 100644 --- a/src/prompts/directive-loader.ts +++ b/src/prompts/directive-loader.ts @@ -77,6 +77,8 @@ filter can decide whether to surface it. Return valid JSON matching the required schema exactly. +The \`message\` field is shown directly to the user in the terminal and UI. Keep it under 15 words, with no rule references. The \`analysis\` field is your internal reasoning and is not shown in the UI. + ## Hard constraints - Do NOT invent evidence. Every quoted span must be copied exactly from the Input. - Use the provided line numbers. diff --git a/src/prompts/schema.ts b/src/prompts/schema.ts index f168bf6..26c137e 100644 --- a/src/prompts/schema.ts +++ b/src/prompts/schema.ts @@ -57,6 +57,11 @@ export function buildJudgeLLMSchema() { description: "A concise 1-2 sentence explanation of the specific issue.", }, + message: { + type: "string", + description: + "Under 15 words. State the issue directly to the user. No rule references.", + }, suggestion: { type: "string", description: "Suggest a fix in 15 words or less.", @@ -124,6 +129,7 @@ export function buildJudgeLLMSchema() { "context_after", "description", "analysis", + "message", "suggestion", "fix", "rule_quote", @@ -168,6 +174,11 @@ export function buildCheckLLMSchema() { description: "A concise 1-2 sentence explanation of the specific issue.", }, + message: { + type: "string", + description: + "Under 15 words. State the issue directly to the user. No rule references.", + }, suggestion: { type: "string", description: "Suggest a fix in 15 words or less.", @@ -235,6 +246,7 @@ export function buildCheckLLMSchema() { "context_after", "description", "analysis", + "message", "suggestion", "fix", "rule_quote", @@ -263,6 +275,7 @@ export type JudgeLLMResult = { context_after: string; description: string; analysis: string; + message: string; suggestion: string; fix: string; rule_quote: string; @@ -279,6 +292,7 @@ export type CheckLLMResult = { line: number; description: string; analysis: string; + message: string; suggestion: string; fix: string; quoted_text: string; @@ -309,6 +323,7 @@ export type JudgeResult = { context_after: string; description: string; analysis: string; + message: string; suggestion: string; fix: string; rule_quote: string; @@ -325,6 +340,7 @@ export type CheckItem = { line: number; description: string; analysis: string; + message?: string; suggestion?: string; fix?: string; quoted_text?: string; @@ -348,6 +364,7 @@ export type CheckResult = { violations: Array<{ line?: number; analysis: string; + message?: string; suggestion?: string; fix?: string; quoted_text?: string; diff --git a/tests/prompt-schema.test.ts b/tests/prompt-schema.test.ts index 43c6748..bf651a8 100644 --- a/tests/prompt-schema.test.ts +++ b/tests/prompt-schema.test.ts @@ -32,4 +32,40 @@ describe("prompt schema verbosity constraints", () => { description: "Suggest a fix in 15 words or less.", }); }); + + it("check schema violation includes message field with correct description", () => { + const schema = buildCheckLLMSchema(); + const violationProperties = + schema.schema.properties.violations.items.properties; + + expect(violationProperties.message).toEqual({ + type: "string", + description: "Under 15 words. State the issue directly to the user. No rule references.", + }); + }); + + it("judge schema violation includes message field with correct description", () => { + const schema = buildJudgeLLMSchema(); + const violationProperties = + schema.schema.properties.criteria.items.properties.violations.items + .properties; + + expect(violationProperties.message).toEqual({ + type: "string", + description: "Under 15 words. State the issue directly to the user. No rule references.", + }); + }); + + it("check schema violation required array includes message", () => { + const schema = buildCheckLLMSchema(); + const required = schema.schema.properties.violations.items.required; + expect(required).toContain("message"); + }); + + it("judge schema violation required array includes message", () => { + const schema = buildJudgeLLMSchema(); + const required = + schema.schema.properties.criteria.items.properties.violations.items.required; + expect(required).toContain("message"); + }); });