Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
9 changes: 5 additions & 4 deletions src/agent/persistence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,11 @@ impl SessionSelector {
let sessions = self.list_sessions();

// Try to parse as numeric index first
if let Ok(index) = identifier.parse::<usize>() {
if index > 0 && index <= sessions.len() {
return sessions.into_iter().nth(index - 1);
}
if let Ok(index) = identifier.parse::<usize>()
&& index > 0
&& index <= sessions.len()
{
return sessions.into_iter().nth(index - 1);
}

// Try to find by UUID or partial UUID
Expand Down
49 changes: 24 additions & 25 deletions src/agent/tools/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,30 @@ impl WebFetchTool {
let robots_url = format!("{}://{}/robots.txt", url.scheme(), url.authority());

// Try to fetch robots.txt (ignore errors - many sites don't have one)
if let Ok(response) = self.client().get(&robots_url).send().await {
if response.status().is_success() {
if let Ok(robots_content) = response.text().await {
let path = url.path();
for line in robots_content.lines() {
if let Some(disallowed) = line.strip_prefix("Disallow: ") {
let disallowed = disallowed.trim();
if !disallowed.is_empty() {
let disallowed = if !disallowed.starts_with('/') {
format!("/{}", disallowed)
} else {
disallowed.to_string()
};
let check_path = if !path.starts_with('/') {
format!("/{}", path)
} else {
path.to_string()
};
if check_path.starts_with(&disallowed) {
return Err(WebFetchError(format!(
"URL {} cannot be fetched due to robots.txt restrictions",
url
)));
}
}
if let Ok(response) = self.client().get(&robots_url).send().await
&& response.status().is_success()
&& let Ok(robots_content) = response.text().await
{
let path = url.path();
for line in robots_content.lines() {
if let Some(disallowed) = line.strip_prefix("Disallow: ") {
let disallowed = disallowed.trim();
if !disallowed.is_empty() {
let disallowed = if !disallowed.starts_with('/') {
format!("/{}", disallowed)
} else {
disallowed.to_string()
};
let check_path = if !path.starts_with('/') {
format!("/{}", path)
} else {
path.to_string()
};
if check_path.starts_with(&disallowed) {
return Err(WebFetchError(format!(
"URL {} cannot be fetched due to robots.txt restrictions",
url
)));
}
}
}
Expand Down
230 changes: 114 additions & 116 deletions src/agent/ui/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1193,47 +1193,47 @@ fn format_kubelint_result(
let mut lines = Vec::new();

// Check for parse errors first
if let Some(errors) = parse_errors {
if !errors.is_empty() {
lines.push(format!(
"{}☸ {} parse error{} (files could not be fully analyzed){}",
ansi::HIGH,
errors.len(),
if errors.len() == 1 { "" } else { "s" },
ansi::RESET
));
for (i, err) in errors.iter().take(3).enumerate() {
if let Some(err_str) = err.as_str() {
let truncated = if err_str.len() > 70 {
format!("{}...", &err_str[..67])
} else {
err_str.to_string()
};
lines.push(format!(
"{} {} {}{}",
ansi::HIGH,
if i == errors.len().min(3) - 1 {
"└"
} else {
"│"
},
truncated,
ansi::RESET
));
}
}
if errors.len() > 3 {
if let Some(errors) = parse_errors
&& !errors.is_empty()
{
lines.push(format!(
"{}☸ {} parse error{} (files could not be fully analyzed){}",
ansi::HIGH,
errors.len(),
if errors.len() == 1 { "" } else { "s" },
ansi::RESET
));
for (i, err) in errors.iter().take(3).enumerate() {
if let Some(err_str) = err.as_str() {
let truncated = if err_str.len() > 70 {
format!("{}...", &err_str[..67])
} else {
err_str.to_string()
};
lines.push(format!(
"{} +{} more errors{}",
ansi::GRAY,
errors.len() - 3,
"{} {} {}{}",
ansi::HIGH,
if i == errors.len().min(3) - 1 {
"└"
} else {
"│"
},
truncated,
ansi::RESET
));
}
// If we only have parse errors and no lint issues, return early
if total == 0 {
return (false, lines);
}
}
if errors.len() > 3 {
lines.push(format!(
"{} +{} more errors{}",
ansi::GRAY,
errors.len() - 3,
ansi::RESET
));
}
// If we only have parse errors and no lint issues, return early
if total == 0 {
return (false, lines);
}
}

Expand Down Expand Up @@ -1326,33 +1326,32 @@ fn format_kubelint_result(
}

// Then high priority
if shown < MAX_PREVIEW {
if let Some(high_issues) = action_plan
if shown < MAX_PREVIEW
&& let Some(high_issues) = action_plan
.and_then(|a| a.get("high"))
.and_then(|h| h.as_array())
{
for issue in high_issues.iter().take(MAX_PREVIEW - shown) {
lines.push(format_kubelint_issue(issue, "🟠", ansi::HIGH));
shown += 1;
}
{
for issue in high_issues.iter().take(MAX_PREVIEW - shown) {
lines.push(format_kubelint_issue(issue, "🟠", ansi::HIGH));
shown += 1;
}
}

// Show quick fix hint
if let Some(quick_fixes) = v.get("quick_fixes").and_then(|q| q.as_array()) {
if let Some(first_fix) = quick_fixes.first().and_then(|f| f.as_str()) {
let truncated = if first_fix.len() > 70 {
format!("{}...", &first_fix[..67])
} else {
first_fix.to_string()
};
lines.push(format!(
"{} → Fix: {}{}",
ansi::INFO_BLUE,
truncated,
ansi::RESET
));
}
if let Some(quick_fixes) = v.get("quick_fixes").and_then(|q| q.as_array())
&& let Some(first_fix) = quick_fixes.first().and_then(|f| f.as_str())
{
let truncated = if first_fix.len() > 70 {
format!("{}...", &first_fix[..67])
} else {
first_fix.to_string()
};
lines.push(format!(
"{} → Fix: {}{}",
ansi::INFO_BLUE,
truncated,
ansi::RESET
));
}

// Note about remaining issues
Expand Down Expand Up @@ -1429,47 +1428,47 @@ fn format_helmlint_result(
let mut lines = Vec::new();

// Check for parse errors first
if let Some(errors) = parse_errors {
if !errors.is_empty() {
lines.push(format!(
"{}⎈ {} parse error{} (chart could not be fully analyzed){}",
ansi::HIGH,
errors.len(),
if errors.len() == 1 { "" } else { "s" },
ansi::RESET
));
for (i, err) in errors.iter().take(3).enumerate() {
if let Some(err_str) = err.as_str() {
let truncated = if err_str.len() > 70 {
format!("{}...", &err_str[..67])
} else {
err_str.to_string()
};
lines.push(format!(
"{} {} {}{}",
ansi::HIGH,
if i == errors.len().min(3) - 1 {
"└"
} else {
"│"
},
truncated,
ansi::RESET
));
}
}
if errors.len() > 3 {
if let Some(errors) = parse_errors
&& !errors.is_empty()
{
lines.push(format!(
"{}⎈ {} parse error{} (chart could not be fully analyzed){}",
ansi::HIGH,
errors.len(),
if errors.len() == 1 { "" } else { "s" },
ansi::RESET
));
for (i, err) in errors.iter().take(3).enumerate() {
if let Some(err_str) = err.as_str() {
let truncated = if err_str.len() > 70 {
format!("{}...", &err_str[..67])
} else {
err_str.to_string()
};
lines.push(format!(
"{} +{} more errors{}",
ansi::GRAY,
errors.len() - 3,
"{} {} {}{}",
ansi::HIGH,
if i == errors.len().min(3) - 1 {
"└"
} else {
"│"
},
truncated,
ansi::RESET
));
}
// If we only have parse errors and no lint issues, return early
if total == 0 {
return (false, lines);
}
}
if errors.len() > 3 {
lines.push(format!(
"{} +{} more errors{}",
ansi::GRAY,
errors.len() - 3,
ansi::RESET
));
}
// If we only have parse errors and no lint issues, return early
if total == 0 {
return (false, lines);
}
}

Expand Down Expand Up @@ -1562,33 +1561,32 @@ fn format_helmlint_result(
}

// Then high priority
if shown < MAX_PREVIEW {
if let Some(high_issues) = action_plan
if shown < MAX_PREVIEW
&& let Some(high_issues) = action_plan
.and_then(|a| a.get("high"))
.and_then(|h| h.as_array())
{
for issue in high_issues.iter().take(MAX_PREVIEW - shown) {
lines.push(format_helmlint_issue(issue, "🟠", ansi::HIGH));
shown += 1;
}
{
for issue in high_issues.iter().take(MAX_PREVIEW - shown) {
lines.push(format_helmlint_issue(issue, "🟠", ansi::HIGH));
shown += 1;
}
}

// Show quick fix hint
if let Some(quick_fixes) = v.get("quick_fixes").and_then(|q| q.as_array()) {
if let Some(first_fix) = quick_fixes.first().and_then(|f| f.as_str()) {
let truncated = if first_fix.len() > 70 {
format!("{}...", &first_fix[..67])
} else {
first_fix.to_string()
};
lines.push(format!(
"{} → Fix: {}{}",
ansi::INFO_BLUE,
truncated,
ansi::RESET
));
}
if let Some(quick_fixes) = v.get("quick_fixes").and_then(|q| q.as_array())
&& let Some(first_fix) = quick_fixes.first().and_then(|f| f.as_str())
{
let truncated = if first_fix.len() > 70 {
format!("{}...", &first_fix[..67])
} else {
first_fix.to_string()
};
lines.push(format!(
"{} → Fix: {}{}",
ansi::INFO_BLUE,
truncated,
ansi::RESET
));
}

// Note about remaining issues
Expand Down
8 changes: 4 additions & 4 deletions src/analyzer/helmlint/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ fn collect_chart_files(path: &Path) -> HashSet<String> {
.into_iter()
.filter_map(|e| e.ok())
{
if entry.path().is_file() {
if let Ok(relative) = entry.path().strip_prefix(path) {
files.insert(relative.display().to_string());
}
if entry.path().is_file()
&& let Ok(relative) = entry.path().strip_prefix(path)
{
files.insert(relative.display().to_string());
}
}

Expand Down
19 changes: 9 additions & 10 deletions src/analyzer/helmlint/pragma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,18 @@ impl PragmaState {
}

// Check if the rule is ignored for this specific line
if let Some(ignores) = self.line_ignores.get(&line) {
if ignores.contains(code.as_str()) {
return true;
}
if let Some(ignores) = self.line_ignores.get(&line)
&& ignores.contains(code.as_str())
{
return true;
}

// Check if previous line has an ignore pragma for this line
if line > 1 {
if let Some(ignores) = self.line_ignores.get(&(line - 1)) {
if ignores.contains(code.as_str()) {
return true;
}
}
if line > 1
&& let Some(ignores) = self.line_ignores.get(&(line - 1))
&& ignores.contains(code.as_str())
{
return true;
}

false
Expand Down
Loading
Loading