refactor(search): rename --after/--updated-after to --since/--updated-since
The --since naming is more intuitive (matches git log --since) and consistent with the list commands which already use --since. Renames the CLI flags, SearchCliFilters fields, SearchFilters fields, autocorrect registry, and robot-docs manifest. No behavioral change. Affected paths: - cli/mod.rs: SearchArgs field + clap attribute rename - cli/commands/search.rs: SearchCliFilters + run_search plumbing - search/filters.rs: SearchFilters struct + apply_filters logic - main.rs: handle_search + robot-docs JSON - cli/autocorrect.rs: COMMAND_FLAGS entry for search Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
69
src/main.rs
69
src/main.rs
@@ -52,7 +52,7 @@ async fn main() {
|
||||
|
||||
// Phase 1.5: Pre-clap arg correction for agent typo tolerance
|
||||
let raw_args: Vec<String> = std::env::args().collect();
|
||||
let correction_result = autocorrect::correct_args(raw_args);
|
||||
let correction_result = autocorrect::correct_args(raw_args, robot_mode_early);
|
||||
|
||||
// Emit correction warnings to stderr (before clap parsing, so they appear
|
||||
// even if clap still fails on something else)
|
||||
@@ -142,12 +142,17 @@ async fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
match cli.color.as_str() {
|
||||
"never" => console::set_colors_enabled(false),
|
||||
"always" => console::set_colors_enabled(true),
|
||||
"auto" => {}
|
||||
other => {
|
||||
eprintln!("Warning: unknown color mode '{}', using auto", other);
|
||||
// I1: Respect NO_COLOR convention (https://no-color.org/)
|
||||
if std::env::var("NO_COLOR").is_ok_and(|v| !v.is_empty()) {
|
||||
console::set_colors_enabled(false);
|
||||
} else {
|
||||
match cli.color.as_str() {
|
||||
"never" => console::set_colors_enabled(false),
|
||||
"always" => console::set_colors_enabled(true),
|
||||
"auto" => {}
|
||||
other => {
|
||||
eprintln!("Warning: unknown color mode '{}', using auto", other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,11 +456,13 @@ fn handle_clap_error(e: clap::Error, robot_mode: bool, corrections: &CorrectionR
|
||||
|
||||
if robot_mode {
|
||||
let error_code = map_clap_error_kind(e.kind());
|
||||
let message = e
|
||||
.to_string()
|
||||
let full_msg = e.to_string();
|
||||
let message = full_msg
|
||||
.lines()
|
||||
.next()
|
||||
.unwrap_or("Parse error")
|
||||
.take(3)
|
||||
.collect::<Vec<_>>()
|
||||
.join("; ")
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
let (suggestion, correction, valid_values) = match e.kind() {
|
||||
@@ -684,10 +691,11 @@ fn handle_issues(
|
||||
print_show_issue(&result);
|
||||
}
|
||||
} else {
|
||||
let state_normalized = args.state.as_deref().map(str::to_lowercase);
|
||||
let filters = ListFilters {
|
||||
limit: args.limit,
|
||||
project: args.project.as_deref(),
|
||||
state: args.state.as_deref(),
|
||||
state: state_normalized.as_deref(),
|
||||
author: args.author.as_deref(),
|
||||
assignee: args.assignee.as_deref(),
|
||||
labels: args.label.as_deref(),
|
||||
@@ -736,10 +744,11 @@ fn handle_mrs(
|
||||
print_show_mr(&result);
|
||||
}
|
||||
} else {
|
||||
let state_normalized = args.state.as_deref().map(str::to_lowercase);
|
||||
let filters = MrListFilters {
|
||||
limit: args.limit,
|
||||
project: args.project.as_deref(),
|
||||
state: args.state.as_deref(),
|
||||
state: state_normalized.as_deref(),
|
||||
author: args.author.as_deref(),
|
||||
assignee: args.assignee.as_deref(),
|
||||
reviewer: args.reviewer.as_deref(),
|
||||
@@ -1714,13 +1723,20 @@ async fn handle_search(
|
||||
project: args.project,
|
||||
labels: args.label,
|
||||
path: args.path,
|
||||
after: args.after,
|
||||
updated_after: args.updated_after,
|
||||
since: args.since,
|
||||
updated_since: args.updated_since,
|
||||
limit: args.limit,
|
||||
};
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
let response = run_search(&config, &args.query, cli_filters, fts_mode, explain)?;
|
||||
let response = run_search(
|
||||
&config,
|
||||
&args.query,
|
||||
cli_filters,
|
||||
fts_mode,
|
||||
&args.mode,
|
||||
explain,
|
||||
)?;
|
||||
let elapsed_ms = start.elapsed().as_millis() as u64;
|
||||
|
||||
if robot_mode {
|
||||
@@ -1895,6 +1911,8 @@ struct HealthData {
|
||||
db_found: bool,
|
||||
schema_current: bool,
|
||||
schema_version: i32,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
actions: Vec<String>,
|
||||
}
|
||||
|
||||
async fn handle_health(
|
||||
@@ -1929,6 +1947,17 @@ async fn handle_health(
|
||||
|
||||
let healthy = config_found && db_found && schema_current;
|
||||
|
||||
let mut actions = Vec::new();
|
||||
if !config_found {
|
||||
actions.push("lore init".to_string());
|
||||
}
|
||||
if !db_found && config_found {
|
||||
actions.push("lore sync".to_string());
|
||||
}
|
||||
if db_found && !schema_current {
|
||||
actions.push("lore migrate".to_string());
|
||||
}
|
||||
|
||||
if robot_mode {
|
||||
let output = HealthOutput {
|
||||
ok: true,
|
||||
@@ -1938,6 +1967,7 @@ async fn handle_health(
|
||||
db_found,
|
||||
schema_current,
|
||||
schema_version,
|
||||
actions,
|
||||
},
|
||||
meta: RobotMeta {
|
||||
elapsed_ms: start.elapsed().as_millis() as u64,
|
||||
@@ -2111,7 +2141,7 @@ fn handle_robot_docs(robot_mode: bool) -> Result<(), Box<dyn std::error::Error>>
|
||||
},
|
||||
"search": {
|
||||
"description": "Search indexed documents (lexical, hybrid, semantic)",
|
||||
"flags": ["<QUERY>", "--mode", "--type", "--author", "-p/--project", "--label", "--path", "--after", "--updated-after", "-n/--limit", "--explain", "--no-explain", "--fts-mode"],
|
||||
"flags": ["<QUERY>", "--mode", "--type", "--author", "-p/--project", "--label", "--path", "--since", "--updated-since", "-n/--limit", "--explain", "--no-explain", "--fts-mode"],
|
||||
"example": "lore --robot search 'authentication bug' --mode hybrid --limit 10",
|
||||
"response_schema": {
|
||||
"ok": "bool",
|
||||
@@ -2385,12 +2415,13 @@ async fn handle_list_compat(
|
||||
let start = std::time::Instant::now();
|
||||
let config = Config::load(config_override)?;
|
||||
|
||||
let state_normalized = state_filter.map(str::to_lowercase);
|
||||
match entity {
|
||||
"issues" => {
|
||||
let filters = ListFilters {
|
||||
limit,
|
||||
project: project_filter,
|
||||
state: state_filter,
|
||||
state: state_normalized.as_deref(),
|
||||
author: author_filter,
|
||||
assignee: assignee_filter,
|
||||
labels: label_filter,
|
||||
@@ -2418,7 +2449,7 @@ async fn handle_list_compat(
|
||||
let filters = MrListFilters {
|
||||
limit,
|
||||
project: project_filter,
|
||||
state: state_filter,
|
||||
state: state_normalized.as_deref(),
|
||||
author: author_filter,
|
||||
assignee: assignee_filter,
|
||||
reviewer: reviewer_filter,
|
||||
|
||||
Reference in New Issue
Block a user