Skip to content

Commit 3d41544

Browse files
Haofeiclaude
andcommitted
Add machine-readable diagnostic explanations for agents (review #10)
`rss check --explain <CODE> --json` now emits the explanation as JSON (code/title/explanation) so an AI agent gets structured repair guidance, not just human text. `DiagnosticExplanation` is now Serialize; the flag order is free-form. (Per-diagnostic `fixes` with applicability are already in `rss check --json`.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 4b677d4 commit 3d41544

2 files changed

Lines changed: 27 additions & 8 deletions

File tree

src/cli/check.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,20 @@ use rsscript::{
1010
use super::package::run_package_check;
1111
use super::{is_package_directory, print_usage, read_interface_sources, required_flag_value};
1212

13-
fn parse_explain_args(args: &[String]) -> Option<&str> {
14-
let [flag, code] = args else {
15-
return None;
16-
};
17-
(flag == "--explain").then_some(code.as_str())
13+
/// Parse `--explain <CODE>` (optionally with `--json`), in any order.
14+
fn parse_explain_args(args: &[String]) -> Option<(&str, bool)> {
15+
let mut saw_explain = false;
16+
let mut json = false;
17+
let mut code = None;
18+
for arg in args {
19+
match arg.as_str() {
20+
"--explain" => saw_explain = true,
21+
"--json" => json = true,
22+
other if !other.starts_with("--") => code = Some(other),
23+
_ => return None,
24+
}
25+
}
26+
saw_explain.then(|| code.map(|code| (code, json))).flatten()
1827
}
1928
#[derive(Debug)]
2029
pub(crate) struct CheckOptions<'a> {
@@ -74,12 +83,22 @@ fn package_check_option_error(options: &CheckOptions<'_>) -> Option<String> {
7483
None
7584
}
7685
pub(crate) fn run_check(args: &[String]) -> ExitCode {
77-
if let Some(code) = parse_explain_args(args) {
86+
if let Some((code, json)) = parse_explain_args(args) {
7887
let Some(explanation) = explain_diagnostic_code(code) else {
7988
eprintln!("unknown diagnostic code: {code}");
8089
return ExitCode::from(2);
8190
};
82-
print!("{}", format_diagnostic_explanation(explanation));
91+
if json {
92+
// Machine-readable explanation for agents. (Per-diagnostic `fixes`
93+
// with applicability are already in `rss check --json` output.)
94+
println!(
95+
"{}",
96+
serde_json::to_string(&explanation)
97+
.expect("diagnostic explanation serializes")
98+
);
99+
} else {
100+
print!("{}", format_diagnostic_explanation(explanation));
101+
}
83102
return ExitCode::SUCCESS;
84103
}
85104

src/diagnostic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub struct Diagnostic {
175175
pub fixes: Vec<Fix>,
176176
}
177177

178-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
179179
pub struct DiagnosticExplanation {
180180
pub code: &'static str,
181181
pub title: &'static str,

0 commit comments

Comments
 (0)