fix: strip front matter from show command, display useful metadata inline
Strips the YAML front matter block and shows useful fields (depends_on, agent, blocked, retries) as a summary line at the top. Eliminates the duplicate title problem. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,62 @@
|
|||||||
|
|
||||||
use super::CommandContext;
|
use super::CommandContext;
|
||||||
|
|
||||||
|
/// Strip YAML front matter and return a summary of useful fields + the remaining body.
|
||||||
|
fn strip_front_matter(text: &str) -> (String, String) {
|
||||||
|
let trimmed = text.trim_start();
|
||||||
|
if !trimmed.starts_with("---") {
|
||||||
|
return (String::new(), text.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the closing ---
|
||||||
|
if let Some(end) = trimmed[3..].find("\n---") {
|
||||||
|
let yaml_block = &trimmed[3..3 + end].trim();
|
||||||
|
let body = &trimmed[3 + end + 4..]; // skip past closing ---
|
||||||
|
|
||||||
|
// Extract useful fields from YAML (simple line-based parsing)
|
||||||
|
let mut parts = Vec::new();
|
||||||
|
for line in yaml_block.lines() {
|
||||||
|
let line = line.trim();
|
||||||
|
if line.starts_with("depends_on:") {
|
||||||
|
let val = line.trim_start_matches("depends_on:").trim();
|
||||||
|
if !val.is_empty() && val != "[]" {
|
||||||
|
parts.push(format!("**Depends on:** {val}"));
|
||||||
|
}
|
||||||
|
} else if line.starts_with("agent:") {
|
||||||
|
let val = line.trim_start_matches("agent:").trim().trim_matches('"');
|
||||||
|
if !val.is_empty() {
|
||||||
|
parts.push(format!("**Agent:** {val}"));
|
||||||
|
}
|
||||||
|
} else if line.starts_with("blocked:") {
|
||||||
|
let val = line.trim_start_matches("blocked:").trim();
|
||||||
|
if val == "true" {
|
||||||
|
parts.push("**Blocked:** yes".to_string());
|
||||||
|
}
|
||||||
|
} else if line.starts_with("retry_count:") {
|
||||||
|
let val = line.trim_start_matches("retry_count:").trim();
|
||||||
|
if val != "0" && !val.is_empty() {
|
||||||
|
parts.push(format!("**Retries:** {val}"));
|
||||||
|
}
|
||||||
|
} else if line.starts_with("qa:") {
|
||||||
|
let val = line.trim_start_matches("qa:").trim().trim_matches('"');
|
||||||
|
if val == "human" {
|
||||||
|
parts.push("**QA:** human review required".to_string());
|
||||||
|
}
|
||||||
|
} else if line.starts_with("merge_failure:") {
|
||||||
|
let val = line.trim_start_matches("merge_failure:").trim().trim_matches('"');
|
||||||
|
if !val.is_empty() {
|
||||||
|
parts.push(format!("**Merge failure:** {val}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(parts.join(" · "), body.to_string())
|
||||||
|
} else {
|
||||||
|
// No closing ---, return as-is
|
||||||
|
(String::new(), text.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Display the full markdown text of a work item identified by its numeric ID.
|
/// Display the full markdown text of a work item identified by its numeric ID.
|
||||||
///
|
///
|
||||||
/// Lookup priority: CRDT → content store → filesystem (Story 512).
|
/// Lookup priority: CRDT → content store → filesystem (Story 512).
|
||||||
@@ -38,10 +94,13 @@ pub(super) fn handle_show(ctx: &CommandContext) -> Option<String> {
|
|||||||
format!("Story {story_id} found in pipeline but its content is unavailable.")
|
format!("Story {story_id} found in pipeline but its content is unavailable.")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Strip front matter block and extract useful metadata to show inline.
|
||||||
|
let (front_matter_summary, body) = strip_front_matter(&text);
|
||||||
|
|
||||||
// Convert markdown headings to bold text for consistent rendering across
|
// Convert markdown headings to bold text for consistent rendering across
|
||||||
// Matrix clients. Element X doesn't style <h2> tags distinctly, but bold
|
// Matrix clients. Element X doesn't style <h2> tags distinctly, but bold
|
||||||
// text renders consistently everywhere.
|
// text renders consistently everywhere.
|
||||||
let formatted = text
|
let formatted = body
|
||||||
.lines()
|
.lines()
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
let trimmed = line.trim_start();
|
let trimmed = line.trim_start();
|
||||||
@@ -58,7 +117,11 @@ pub(super) fn handle_show(ctx: &CommandContext) -> Option<String> {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
|
|
||||||
Some(formatted)
|
if front_matter_summary.is_empty() {
|
||||||
|
Some(formatted.trim().to_string())
|
||||||
|
} else {
|
||||||
|
Some(format!("{front_matter_summary}\n{}", formatted.trim()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user