Skip to content

Commit 0bcd1c2

Browse files
Alex HolmbergAlex Holmberg
authored andcommitted
small fixes
1 parent 457a570 commit 0bcd1c2

25 files changed

Lines changed: 679 additions & 298 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# will have compiled files and executables
33
debug/
44
target/
5+
test-results/
6+
tmp/
57

68
node_modules/
79
*.vsix
@@ -14,6 +16,9 @@ node_modules/
1416
.qoder/*
1517
.qoder/**/*
1618

19+
# Planning documents (local only, not shared)
20+
.planning/
21+
1722
# MSVC Windows builds of rustc generate these, which store debugging information
1823
*.pdb
1924
# Ignore docs except specific tracked files

.rustfmt.toml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,4 @@ remove_nested_parens = true
99
merge_derives = true
1010
use_try_shorthand = true
1111
use_field_init_shorthand = true
12-
force_explicit_abi = true
13-
empty_item_single_line = true
14-
struct_lit_single_line = true
15-
fn_single_line = false
16-
where_single_line = false
17-
imports_layout = "Vertical"
18-
imports_granularity = "Crate"
12+
force_explicit_abi = true

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ license = "GPL-3.0"
88
repository = "https://github.com/syncable-dev/syncable-cli"
99
keywords = [
1010
"cli",
11-
"ai",
12-
"devops",
13-
"iac",
1411
"docker",
12+
"kubernetes",
13+
"terraform",
14+
"devops",
1515
]
1616
categories = ["command-line-utilities", "development-tools"]
1717
readme = "README.md"

src/agent/tools/background.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,11 @@ impl BackgroundProcessManager {
127127
// Check if already running
128128
{
129129
let processes = self.processes.lock().await;
130-
if processes.contains_key(id) {
131-
if let Some(proc) = processes.get(id) {
132-
if let Some(port) = proc.local_port {
133-
return Ok(port);
134-
}
135-
}
130+
if processes.contains_key(id)
131+
&& let Some(proc) = processes.get(id)
132+
&& let Some(port) = proc.local_port
133+
{
134+
return Ok(port);
136135
}
137136
}
138137

@@ -178,19 +177,18 @@ impl BackgroundProcessManager {
178177
{
179178
Ok(Ok(Some(line))) => {
180179
// Parse port from "Forwarding from 127.0.0.1:XXXXX -> 9090"
181-
if line.contains("Forwarding from") {
182-
if let Some(port_str) = line
180+
if line.contains("Forwarding from")
181+
&& let Some(port_str) = line
183182
.split(':')
184183
.nth(1)
185184
.and_then(|s| s.split_whitespace().next())
186-
{
187-
port = port_str.parse().ok();
188-
// Keep draining stdout in background to prevent SIGPIPE
189-
tokio::spawn(async move {
190-
while let Ok(Some(_)) = reader.next_line().await {}
191-
});
192-
break;
193-
}
185+
{
186+
port = port_str.parse().ok();
187+
// Keep draining stdout in background to prevent SIGPIPE
188+
tokio::spawn(async move {
189+
while let Ok(Some(_)) = reader.next_line().await {}
190+
});
191+
break;
194192
}
195193
}
196194
Ok(Ok(None)) => break, // EOF

src/agent/tools/compression.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,11 @@ fn extract_issues(output: &Value) -> Vec<Value> {
266266
// Try nested structures
267267
if let Some(obj) = output.as_object() {
268268
for (_, v) in obj {
269-
if let Some(arr) = v.as_array() {
270-
if !arr.is_empty() && is_issue_like(&arr[0]) {
271-
return arr.clone();
272-
}
269+
if let Some(arr) = v.as_array()
270+
&& !arr.is_empty()
271+
&& is_issue_like(&arr[0])
272+
{
273+
return arr.clone();
273274
}
274275
}
275276
}
@@ -367,10 +368,10 @@ fn get_issue_file(issue: &Value) -> Option<String> {
367368
return Some(s.to_string());
368369
}
369370
// Handle nested location objects
370-
if let Some(loc) = issue.get(field).and_then(|v| v.as_object()) {
371-
if let Some(f) = loc.get("file").and_then(|v| v.as_str()) {
372-
return Some(f.to_string());
373-
}
371+
if let Some(loc) = issue.get(field).and_then(|v| v.as_object())
372+
&& let Some(f) = loc.get("file").and_then(|v| v.as_str())
373+
{
374+
return Some(f.to_string());
374375
}
375376
}
376377

@@ -492,7 +493,8 @@ pub fn compress_analysis_output(output: &Value, config: &CompressionConfig) -> S
492493

493494
// Detect output type and extract accordingly
494495
let is_monorepo = output.get("projects").is_some() || output.get("is_monorepo").is_some();
495-
let is_project_analysis = output.get("languages").is_some() && output.get("analysis_metadata").is_some();
496+
let is_project_analysis =
497+
output.get("languages").is_some() && output.get("analysis_metadata").is_some();
496498

497499
if is_monorepo {
498500
// MonorepoAnalysis structure
@@ -517,19 +519,19 @@ pub fn compress_analysis_output(output: &Value, config: &CompressionConfig) -> S
517519
if let Some(analysis) = project.get("analysis") {
518520
if let Some(langs) = analysis.get("languages").and_then(|v| v.as_array()) {
519521
for lang in langs {
520-
if let Some(name) = lang.get("name").and_then(|v| v.as_str()) {
521-
if !all_languages.contains(&name.to_string()) {
522-
all_languages.push(name.to_string());
523-
}
522+
if let Some(name) = lang.get("name").and_then(|v| v.as_str())
523+
&& !all_languages.contains(&name.to_string())
524+
{
525+
all_languages.push(name.to_string());
524526
}
525527
}
526528
}
527529
if let Some(fws) = analysis.get("frameworks").and_then(|v| v.as_array()) {
528530
for fw in fws {
529-
if let Some(name) = fw.get("name").and_then(|v| v.as_str()) {
530-
if !all_frameworks.contains(&name.to_string()) {
531-
all_frameworks.push(name.to_string());
532-
}
531+
if let Some(name) = fw.get("name").and_then(|v| v.as_str())
532+
&& !all_frameworks.contains(&name.to_string())
533+
{
534+
all_frameworks.push(name.to_string());
533535
}
534536
}
535537
}

src/agent/tools/output_store.rs

Lines changed: 80 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ fn matches_filter(issue: &Value, filter_type: &str, filter_value: &str) -> bool
353353
.to_lowercase()
354354
.contains(&filter_value.to_lowercase())
355355
}
356-
"any" | _ => {
356+
_ => {
357357
// Search in all string values
358358
let issue_str = serde_json::to_string(issue).unwrap_or_default();
359359
issue_str
@@ -466,12 +466,18 @@ fn extract_summary(data: &Value) -> Value {
466466
summary.insert("project_root".to_string(), Value::String(root.to_string()));
467467
}
468468
if let Some(arch) = data.get("architecture_type").and_then(|v| v.as_str()) {
469-
summary.insert("architecture_type".to_string(), Value::String(arch.to_string()));
469+
summary.insert(
470+
"architecture_type".to_string(),
471+
Value::String(arch.to_string()),
472+
);
470473
}
471474

472475
// Count projects (MonorepoAnalysis)
473476
if let Some(projects) = data.get("projects").and_then(|v| v.as_array()) {
474-
summary.insert("project_count".to_string(), Value::Number(projects.len().into()));
477+
summary.insert(
478+
"project_count".to_string(),
479+
Value::Number(projects.len().into()),
480+
);
475481

476482
// Extract project names
477483
let names: Vec<Value> = projects
@@ -504,7 +510,10 @@ fn extract_summary(data: &Value) -> Value {
504510

505511
// Extract services (ProjectAnalysis flat structure) - include names, not just count
506512
if let Some(services) = data.get("services").and_then(|v| v.as_array()) {
507-
summary.insert("services_count".to_string(), Value::Number(services.len().into()));
513+
summary.insert(
514+
"services_count".to_string(),
515+
Value::Number(services.len().into()),
516+
);
508517
// Include service names so agent knows what microservices exist
509518
let service_names: Vec<Value> = services
510519
.iter()
@@ -591,15 +600,14 @@ fn extract_service_by_name(data: &Value, name: &str) -> Option<Value> {
591600
.get("analysis")
592601
.and_then(|a| a.get("services"))
593602
.and_then(|s| s.as_array())
594-
{
595-
if let Some(service) = services.iter().find(|s| {
603+
&& let Some(service) = services.iter().find(|s| {
596604
s.get("name")
597605
.and_then(|n| n.as_str())
598606
.map(|n| n.to_lowercase().contains(&name.to_lowercase()))
599607
.unwrap_or(false)
600-
}) {
601-
return Some(service.clone());
602-
}
608+
})
609+
{
610+
return Some(service.clone());
603611
}
604612
}
605613
None
@@ -616,15 +624,26 @@ fn extract_language_details(data: &Value, lang_name: &str) -> Option<Value> {
616624
if lang_name == "*" || name.to_lowercase().contains(&lang_name.to_lowercase()) {
617625
let mut compact_lang = serde_json::Map::new();
618626
if !proj_name.is_empty() {
619-
compact_lang.insert("project".to_string(), Value::String(proj_name.to_string()));
627+
compact_lang
628+
.insert("project".to_string(), Value::String(proj_name.to_string()));
620629
}
621-
compact_lang.insert("name".to_string(), lang.get("name").cloned().unwrap_or(Value::Null));
622-
compact_lang.insert("version".to_string(), lang.get("version").cloned().unwrap_or(Value::Null));
623-
compact_lang.insert("confidence".to_string(), lang.get("confidence").cloned().unwrap_or(Value::Null));
630+
compact_lang.insert(
631+
"name".to_string(),
632+
lang.get("name").cloned().unwrap_or(Value::Null),
633+
);
634+
compact_lang.insert(
635+
"version".to_string(),
636+
lang.get("version").cloned().unwrap_or(Value::Null),
637+
);
638+
compact_lang.insert(
639+
"confidence".to_string(),
640+
lang.get("confidence").cloned().unwrap_or(Value::Null),
641+
);
624642

625643
// Replace file array with count
626644
if let Some(files) = lang.get("files").and_then(|f| f.as_array()) {
627-
compact_lang.insert("file_count".to_string(), Value::Number(files.len().into()));
645+
compact_lang
646+
.insert("file_count".to_string(), Value::Number(files.len().into()));
628647
}
629648

630649
results.push(Value::Object(compact_lang));
@@ -756,7 +775,7 @@ fn compact_analyze_output(data: &Value) -> Value {
756775

757776
// Compact projects (MonorepoAnalysis)
758777
if let Some(projects) = data.get("projects").and_then(|v| v.as_array()) {
759-
let compacted: Vec<Value> = projects.iter().map(|p| compact_project(p)).collect();
778+
let compacted: Vec<Value> = projects.iter().map(compact_project).collect();
760779
result.insert("projects".to_string(), Value::Array(compacted));
761780
return Value::Object(result);
762781
}
@@ -785,7 +804,8 @@ fn compact_analyze_output(data: &Value) -> Value {
785804
}
786805
// Replace files array with count
787806
if let Some(files) = lang.get("files").and_then(|f| f.as_array()) {
788-
compact_lang.insert("file_count".to_string(), Value::Number(files.len().into()));
807+
compact_lang
808+
.insert("file_count".to_string(), Value::Number(files.len().into()));
789809
}
790810
Value::Object(compact_lang)
791811
})
@@ -856,7 +876,8 @@ fn compact_project(project: &Value) -> Value {
856876
}
857877
// Replace files array with count
858878
if let Some(files) = lang.get("files").and_then(|f| f.as_array()) {
859-
compact_lang.insert("file_count".to_string(), Value::Number(files.len().into()));
879+
compact_lang
880+
.insert("file_count".to_string(), Value::Number(files.len().into()));
860881
}
861882
Value::Object(compact_lang)
862883
})
@@ -865,7 +886,13 @@ fn compact_project(project: &Value) -> Value {
865886
}
866887

867888
// Copy frameworks, databases, services as-is (usually not huge)
868-
for key in &["frameworks", "databases", "services", "build_tools", "package_managers"] {
889+
for key in &[
890+
"frameworks",
891+
"databases",
892+
"services",
893+
"build_tools",
894+
"package_managers",
895+
] {
869896
if let Some(v) = analysis.get(*key) {
870897
compact_analysis.insert(key.to_string(), v.clone());
871898
}
@@ -888,32 +915,32 @@ pub fn list_outputs() -> Vec<OutputInfo> {
888915

889916
if let Ok(entries) = fs::read_dir(&dir) {
890917
for entry in entries.flatten() {
891-
if let Some(filename) = entry.file_name().to_str() {
892-
if filename.ends_with(".json") {
893-
let ref_id = filename.trim_end_matches(".json").to_string();
894-
895-
// Read metadata
896-
if let Ok(content) = fs::read_to_string(entry.path()) {
897-
if let Ok(stored) = serde_json::from_str::<Value>(&content) {
898-
let tool = stored
899-
.get("tool")
900-
.and_then(|v| v.as_str())
901-
.unwrap_or("unknown")
902-
.to_string();
903-
let timestamp = stored
904-
.get("timestamp")
905-
.and_then(|v| v.as_u64())
906-
.unwrap_or(0);
907-
let size = content.len();
908-
909-
outputs.push(OutputInfo {
910-
ref_id,
911-
tool,
912-
timestamp,
913-
size_bytes: size,
914-
});
915-
}
916-
}
918+
if let Some(filename) = entry.file_name().to_str()
919+
&& filename.ends_with(".json")
920+
{
921+
let ref_id = filename.trim_end_matches(".json").to_string();
922+
923+
// Read metadata
924+
if let Ok(content) = fs::read_to_string(entry.path())
925+
&& let Ok(stored) = serde_json::from_str::<Value>(&content)
926+
{
927+
let tool = stored
928+
.get("tool")
929+
.and_then(|v| v.as_str())
930+
.unwrap_or("unknown")
931+
.to_string();
932+
let timestamp = stored
933+
.get("timestamp")
934+
.and_then(|v| v.as_u64())
935+
.unwrap_or(0);
936+
let size = content.len();
937+
938+
outputs.push(OutputInfo {
939+
ref_id,
940+
tool,
941+
timestamp,
942+
size_bytes: size,
943+
});
917944
}
918945
}
919946
}
@@ -947,16 +974,16 @@ pub fn cleanup_old_outputs() {
947974

948975
if let Ok(entries) = fs::read_dir(&dir) {
949976
for entry in entries.flatten() {
950-
if let Ok(content) = fs::read_to_string(entry.path()) {
951-
if let Ok(stored) = serde_json::from_str::<Value>(&content) {
952-
let timestamp = stored
953-
.get("timestamp")
954-
.and_then(|v| v.as_u64())
955-
.unwrap_or(0);
977+
if let Ok(content) = fs::read_to_string(entry.path())
978+
&& let Ok(stored) = serde_json::from_str::<Value>(&content)
979+
{
980+
let timestamp = stored
981+
.get("timestamp")
982+
.and_then(|v| v.as_u64())
983+
.unwrap_or(0);
956984

957-
if now - timestamp > MAX_AGE_SECS {
958-
let _ = fs::remove_file(entry.path());
959-
}
985+
if now - timestamp > MAX_AGE_SECS {
986+
let _ = fs::remove_file(entry.path());
960987
}
961988
}
962989
}

0 commit comments

Comments
 (0)