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
64 changes: 57 additions & 7 deletions crates/buzz-acp/src/setup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub(crate) enum RequirementPayload {
/// One-line stderr excerpt identifying the parse error.
diagnostic: String,
},
/// Git for Windows is missing; open Doctor for the installation guide.
/// Git for Windows is missing; open Agent runtimes for the installation guide.
GitBash,
}

Expand All @@ -139,7 +139,7 @@ impl RequirementPayload {
.map(String::as_str)
.unwrap_or("the agent");
format!(
"install the {} ACP adapter (open Doctor in Settings to diagnose)",
"install the {} ACP adapter (open Agent runtimes in Settings to diagnose)",
harness
)
}
Expand All @@ -149,7 +149,7 @@ impl RequirementPayload {
.map(String::as_str)
.unwrap_or("the agent");
format!(
"reinstall the {} ACP adapter — the installed version is outdated (open Doctor in Settings to diagnose)",
"reinstall the {} ACP adapter — the installed version is outdated (open Agent runtimes in Settings to diagnose)",
harness
)
}
Expand All @@ -159,7 +159,7 @@ impl RequirementPayload {
.map(String::as_str)
.unwrap_or("the agent");
format!(
"install {} CLI (open Doctor in Settings to diagnose)",
"install {} CLI (open Agent runtimes in Settings to diagnose)",
harness
)
}
Expand All @@ -168,7 +168,10 @@ impl RequirementPayload {
.first()
.map(String::as_str)
.unwrap_or("the agent");
format!("install {} (open Doctor in Settings to diagnose)", harness)
format!(
"install {} (open Agent runtimes in Settings to diagnose)",
harness
)
}
},
RequirementPayload::CliConfigInvalid {
Expand All @@ -184,7 +187,7 @@ impl RequirementPayload {
)
}
RequirementPayload::GitBash => {
"install Git for Windows (open Doctor in Settings to diagnose)".to_string()
"install Git for Windows (open Agent runtimes in Settings to diagnose)".to_string()
}
}
}
Expand Down Expand Up @@ -264,7 +267,7 @@ impl SetupPayload {
.any(|r| matches!(r, RequirementPayload::CliConfigInvalid { .. }));

let footer = if has_doctor_requirement {
"Open Doctor in the Buzz app, install Git for Windows, then re-check and restart the agent.".to_string()
"Open Agent runtimes in Settings, install Git for Windows, then re-check and restart the agent.".to_string()
} else if all_external {
// All requirements are external config files — Edit Agent cannot
// help. Don't send the user there.
Expand Down Expand Up @@ -743,6 +746,53 @@ mod tests {
);
}

#[test]
fn nudge_body_runtime_install_copy_points_to_agent_runtimes() {
for availability in [
AcpAvailabilityStatus::AdapterMissing,
AcpAvailabilityStatus::AdapterOutdated,
AcpAvailabilityStatus::CliMissing,
AcpAvailabilityStatus::NotInstalled,
] {
let payload = SetupPayload {
agent_name: "Codex".to_string(),
agent_pubkey: "test".to_string(),
requirements: vec![RequirementPayload::CliLogin {
probe_args: vec!["codex".to_string()],
setup_copy: "run `codex login`".to_string(),
availability,
}],
};
let body = payload.nudge_body();
assert!(
body.contains("Agent runtimes in Settings"),
"runtime install nudge must point to Agent runtimes; got: {body:?}"
);
assert!(
!body.contains("Doctor"),
"runtime install nudge must not point to the removed Doctor section; got: {body:?}"
);
}
}

#[test]
fn nudge_body_git_bash_copy_points_to_agent_runtimes() {
let payload = SetupPayload {
agent_name: "Buzz Agent".to_string(),
agent_pubkey: "test".to_string(),
requirements: vec![RequirementPayload::GitBash],
};
let body = payload.nudge_body();
assert!(
body.contains("Open Agent runtimes in Settings"),
"Git Bash nudge must point to Agent runtimes; got: {body:?}"
);
assert!(
!body.contains("Doctor"),
"Git Bash nudge must not point to the removed Doctor section; got: {body:?}"
);
}

#[test]
fn nudge_body_empty_requirements_falls_back_to_generic() {
let payload = SetupPayload {
Expand Down
Binary file added desktop/public/runtime-icons/claude.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added desktop/public/runtime-icons/codex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions desktop/public/runtime-icons/goose.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion desktop/src/app/AppShellContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type AppShellContextValue = {
feedItemState: FeedItemState;
// Open the Settings panel at the given section. Available on all surfaces
// that render under AppShell (channel, home, projects, pulse, agents).
// Used by config-nudge cards to deep-link to Settings → Doctor.
// Used by config-nudge cards to deep-link to Settings → Agents.
onOpenSettings: ((section: SettingsSection) => void) | null;
};

Expand Down
4 changes: 4 additions & 0 deletions desktop/src/app/routes/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ type SettingsRouteSearch = {
function validateSettingsSearch(
search: Record<string, unknown>,
): SettingsRouteSearch {
if (search.section === "doctor") {
return { section: "agents" };
}

return {
section: isSettingsSection(search.section) ? search.section : undefined,
};
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/features/agents/ui/AgentDefinitionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ export function AgentDefinitionDialog({
: selectedRuntime.availability === "cli_missing"
? `${selectedRuntime.label} ACP adapter is installed but the CLI is missing.`
: `${selectedRuntime.label} is not installed.`}{" "}
Visit Settings &gt; Doctor to set it up.
Visit Settings &gt; Agents to set it up.
</p>
) : null;
const advancedFieldsTransition = shouldReduceMotion
Expand Down
4 changes: 2 additions & 2 deletions desktop/src/features/onboarding/ui/SetupStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -815,8 +815,8 @@ function RuntimeProvidersSection({
className="max-w-[560px] rounded-2xl bg-white/70 px-6 py-6 text-sm text-muted-foreground"
data-testid="onboarding-acp-empty"
>
No compatible ACP runtimes detected yet. You can finish setup now
and come back later in Settings &gt; Doctor.
No compatible agent runtimes detected yet. You can finish setup now
and come back later in Settings &gt; Agents.
</p>
)}

Expand Down
4 changes: 3 additions & 1 deletion desktop/src/features/profile/ui/ProfileAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type ProfileAvatarProps = {
label: string;
className?: string;
iconClassName?: string;
imageClassName?: string;
plain?: boolean;
testId?: string;
};
Expand All @@ -23,6 +24,7 @@ export function ProfileAvatar({
label,
className,
iconClassName,
imageClassName,
plain = false,
testId,
}: ProfileAvatarProps) {
Expand Down Expand Up @@ -67,7 +69,7 @@ export function ProfileAvatar({
{src !== undefined ? (
<AvatarImage
alt={`${label} avatar`}
className="object-cover"
className={cn("object-cover", imageClassName)}
data-testid={testId ? `${testId}-image` : undefined}
onLoadingStatusChange={(status) => {
if (status === "error") setFailedSrc(liveSrc);
Expand Down
Loading
Loading