mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
Improve install flow ordering, doctor diagnostics, and callback page
- Swap LLM providers and GitHub App steps so LLM setup comes first - List specific providers with connectivity issues in arc doctor warnings - Style the GitHub App callback page with a centered card and checkmark Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ac4fc4ea9
commit
4408a30adc
2 changed files with 63 additions and 39 deletions
|
|
@ -217,7 +217,7 @@ pub fn check_llm_providers(
|
|||
})
|
||||
.collect();
|
||||
|
||||
let mut has_live_error = false;
|
||||
let mut failed_providers: Vec<&Provider> = Vec::new();
|
||||
if let Some(results) = live_results {
|
||||
for (provider, result) in results {
|
||||
match result {
|
||||
|
|
@ -225,7 +225,7 @@ pub fn check_llm_providers(
|
|||
text: format!("{provider} connectivity: OK"),
|
||||
}),
|
||||
Err(e) => {
|
||||
has_live_error = true;
|
||||
failed_providers.push(provider);
|
||||
details.push(CheckDetail {
|
||||
text: format!("{provider} connectivity: {e}"),
|
||||
});
|
||||
|
|
@ -242,13 +242,14 @@ pub fn check_llm_providers(
|
|||
details,
|
||||
remediation: Some("Set at least one provider API key".to_string()),
|
||||
}
|
||||
} else if has_live_error {
|
||||
} else if !failed_providers.is_empty() {
|
||||
let names: Vec<_> = failed_providers.iter().map(|p| p.to_string()).collect();
|
||||
CheckResult {
|
||||
name: "LLM providers".to_string(),
|
||||
status: CheckStatus::Warning,
|
||||
summary: format!("{count} of {total} configured (connectivity issues)"),
|
||||
details,
|
||||
remediation: Some("Check provider API keys and network connectivity".to_string()),
|
||||
remediation: Some(format!("Connectivity issues with: {}", names.join(", "))),
|
||||
}
|
||||
} else {
|
||||
CheckResult {
|
||||
|
|
@ -1271,6 +1272,11 @@ mod tests {
|
|||
let result = check_llm_providers(&statuses, Some(&live));
|
||||
assert_eq!(result.status, CheckStatus::Warning);
|
||||
assert!(result.details.iter().any(|d| d.text.contains("timeout")));
|
||||
let rem = result.remediation.unwrap();
|
||||
assert!(
|
||||
rem.contains("anthropic"),
|
||||
"remediation should name the failing provider: {rem}"
|
||||
);
|
||||
}
|
||||
|
||||
// -- check_brave_search --
|
||||
|
|
|
|||
|
|
@ -378,9 +378,27 @@ async fn setup_github_app(arc_dir: &Path) -> Result<Vec<(String, String)>> {
|
|||
if let Some(tx) = shutdown_tx.lock().unwrap().take() {
|
||||
let _ = tx.send(());
|
||||
}
|
||||
Html(
|
||||
"<!DOCTYPE html><html><body><p>GitHub App created! You can close this tab.</p></body></html>".to_string(),
|
||||
)
|
||||
Html(r#"<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Arc Setup</title>
|
||||
<style>
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #f6f8fa; color: #1f2328; }
|
||||
.card { text-align: center; background: #fff; border: 1px solid #d1d9e0; border-radius: 12px; padding: 48px; max-width: 420px; }
|
||||
.check { font-size: 48px; margin-bottom: 16px; }
|
||||
h1 { font-size: 20px; font-weight: 600; margin: 0 0 8px; }
|
||||
p { font-size: 14px; color: #59636e; margin: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="check">✓</div>
|
||||
<h1>GitHub App created</h1>
|
||||
<p>You can close this tab and return to your terminal.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>"#.to_string())
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -541,8 +559,38 @@ pub async fn run_install() -> Result<()> {
|
|||
eprintln!();
|
||||
}
|
||||
|
||||
// Step 1: GitHub App setup
|
||||
eprintln!("[Step 1/4] GitHub App");
|
||||
// Step 1: LLM providers
|
||||
eprintln!("[Step 1/4] LLM providers");
|
||||
let provider_labels: Vec<String> = Provider::ALL
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let env_vars = p.api_key_env_vars().join(" / ");
|
||||
format!("{} ({})", provider_display_name(*p), env_vars)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let selected_indices: Vec<usize> = tokio::task::spawn_blocking({
|
||||
let labels = provider_labels.clone();
|
||||
move || prompt_multiselect("Which LLM providers do you want to configure?", &labels)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let mut env_pairs: Vec<(String, String)> = Vec::new();
|
||||
for idx in selected_indices {
|
||||
let provider = Provider::ALL[idx];
|
||||
let env_var = provider.api_key_env_vars()[0];
|
||||
let url = provider_key_url(provider);
|
||||
eprintln!(" Get your API key at: {url}");
|
||||
|
||||
let prompt = env_var.to_string();
|
||||
let key: String = tokio::task::spawn_blocking(move || prompt_input(&prompt)).await??;
|
||||
|
||||
env_pairs.push((env_var.to_string(), key));
|
||||
}
|
||||
eprintln!();
|
||||
|
||||
// Step 2: GitHub App setup
|
||||
eprintln!("[Step 2/4] GitHub App");
|
||||
let mut github_env_pairs: Vec<(String, String)> = Vec::new();
|
||||
{
|
||||
let setup_github = tokio::task::spawn_blocking(|| {
|
||||
|
|
@ -611,36 +659,6 @@ pub async fn run_install() -> Result<()> {
|
|||
eprintln!();
|
||||
}
|
||||
|
||||
// Step 2: LLM providers
|
||||
eprintln!("[Step 2/4] LLM providers");
|
||||
let provider_labels: Vec<String> = Provider::ALL
|
||||
.iter()
|
||||
.map(|p| {
|
||||
let env_vars = p.api_key_env_vars().join(" / ");
|
||||
format!("{} ({})", provider_display_name(*p), env_vars)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let selected_indices: Vec<usize> = tokio::task::spawn_blocking({
|
||||
let labels = provider_labels.clone();
|
||||
move || prompt_multiselect("Which LLM providers do you want to configure?", &labels)
|
||||
})
|
||||
.await??;
|
||||
|
||||
let mut env_pairs: Vec<(String, String)> = Vec::new();
|
||||
for idx in selected_indices {
|
||||
let provider = Provider::ALL[idx];
|
||||
let env_var = provider.api_key_env_vars()[0];
|
||||
let url = provider_key_url(provider);
|
||||
eprintln!(" Get your API key at: {url}");
|
||||
|
||||
let prompt = env_var.to_string();
|
||||
let key: String = tokio::task::spawn_blocking(move || prompt_input(&prompt)).await??;
|
||||
|
||||
env_pairs.push((env_var.to_string(), key));
|
||||
}
|
||||
eprintln!();
|
||||
|
||||
// Step 3: Writing ~/.arc/.env
|
||||
eprintln!("[Step 3/4] Writing ~/.arc/.env");
|
||||
let env_path = arc_dir.join(".env");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue