feat(cli): status display/filtering, expanded --fields, and robot-docs --brief

Work item status integration across all CLI output:

Issue listing (lore list issues):
- New Status column appears when any issue has status data, with
  hex-color rendering using ANSI 256-color approximation
- New --status flag for case-insensitive filtering (OR logic for
  multiple values): lore issues --status "In progress" --status "To do"
- Status fields (name, category, color, icon_name, synced_at) in issue
  list query and JSON output with conditional serialization

Issue detail (lore show issue):
- Displays "Status: In progress (in_progress)" with color-coded output
  using ANSI 256-color approximation from hex color values
- Status fields included in robot mode JSON with ISO timestamps
- IssueRow, IssueDetail, IssueDetailJson all carry status columns

Robot mode field selection expanded to new commands:
- search: --fields with "minimal" preset (document_id, title, source_type, score)
- timeline: --fields with "minimal" preset (timestamp, type, entity_iid, detail)
- who: --fields with per-mode presets (expert_minimal, workload_minimal, etc.)
- robot-docs: new --brief flag strips response_schema from output (~60% smaller)
- strip_schemas() utility in robot.rs for --brief mode
- expand_fields_preset() extended for search, timeline, and all who modes

Robot-docs manifest updated with --status flag documentation, --fields
flags for search/timeline/who, fields_presets sections, and corrected
search response schema field names.

Note: replaces empty commit dcfd449 which lost staging during hook execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Taylor Eernisse
2026-02-11 08:13:37 -05:00
parent f5967a8e52
commit d9f99ef21d
9 changed files with 335 additions and 39 deletions

View File

@@ -2201,12 +2201,28 @@ pub fn print_who_json(run: &WhoRun, args: &WhoArgs, elapsed_ms: u64) {
meta: RobotMeta { elapsed_ms },
};
println!(
"{}",
serde_json::to_string(&output).unwrap_or_else(|e| {
format!(r#"{{"ok":false,"error":{{"code":"INTERNAL_ERROR","message":"JSON serialization failed: {e}"}}}}"#)
})
);
let mut value = serde_json::to_value(&output).unwrap_or_else(|e| {
serde_json::json!({"ok":false,"error":{"code":"INTERNAL_ERROR","message":format!("JSON serialization failed: {e}")}})
});
if let Some(f) = &args.fields {
let preset_key = format!("who_{mode}");
let expanded = crate::cli::robot::expand_fields_preset(f, &preset_key);
// Each who mode uses a different array key; try all possible keys
for key in &[
"experts",
"assigned_issues",
"authored_mrs",
"review_mrs",
"categories",
"discussions",
"users",
] {
crate::cli::robot::filter_fields(&mut value, key, &expanded);
}
}
println!("{}", serde_json::to_string(&value).unwrap());
}
#[derive(Serialize)]
@@ -2577,6 +2593,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Expert { .. }
@@ -2595,6 +2612,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Workload { .. }
@@ -2613,6 +2631,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Workload { .. }
@@ -2631,6 +2650,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Reviews { .. }
@@ -2649,6 +2669,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Expert { .. }
@@ -2667,6 +2688,7 @@ mod tests {
limit: 20,
detail: false,
no_detail: false,
fields: None,
})
.unwrap(),
WhoMode::Expert { .. }
@@ -2686,6 +2708,7 @@ mod tests {
limit: 20,
detail: true,
no_detail: false,
fields: None,
};
let mode = resolve_mode(&args).unwrap();
let err = validate_mode_flags(&mode, &args).unwrap_err();
@@ -2709,6 +2732,7 @@ mod tests {
limit: 20,
detail: true,
no_detail: false,
fields: None,
};
let mode = resolve_mode(&args).unwrap();
assert!(validate_mode_flags(&mode, &args).is_ok());