Show Claude Code and Codex as recommended, collapse other adapter types

In the onboarding wizard step 2 ("Create your first agent"), Claude Code and
Codex are now shown prominently as recommended options. Other adapter types
(OpenCode, Pi, Cursor, OpenClaw Gateway) are hidden behind a collapsible
"More Agent Adapter Types" toggle to reduce visual noise for new users.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta
2026-03-11 13:58:52 -05:00
parent 7e6a5682fa
commit 7df74b170d

View File

@@ -101,6 +101,7 @@ export function OnboardingWizard() {
const [forceUnsetAnthropicApiKey, setForceUnsetAnthropicApiKey] = const [forceUnsetAnthropicApiKey, setForceUnsetAnthropicApiKey] =
useState(false); useState(false);
const [unsetAnthropicLoading, setUnsetAnthropicLoading] = useState(false); const [unsetAnthropicLoading, setUnsetAnthropicLoading] = useState(false);
const [showMoreAdapters, setShowMoreAdapters] = useState(false);
// Step 3 // Step 3
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md"); const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
@@ -669,87 +670,127 @@ export function OnboardingWizard() {
icon: Code, icon: Code,
desc: "Local Codex agent", desc: "Local Codex agent",
recommended: true recommended: true
},
{
value: "gemini_local" as const,
label: "Gemini CLI",
icon: Gem,
desc: "Local Gemini agent"
},
{
value: "opencode_local" as const,
label: "OpenCode",
icon: OpenCodeLogoIcon,
desc: "Local multi-provider agent"
},
{
value: "pi_local" as const,
label: "Pi",
icon: Terminal,
desc: "Local Pi agent"
},
{
value: "openclaw_gateway" as const,
label: "OpenClaw Gateway",
icon: Bot,
desc: "Invoke OpenClaw via gateway protocol",
comingSoon: true,
disabledLabel: "Configure OpenClaw within the App"
},
{
value: "cursor" as const,
label: "Cursor",
icon: MousePointer2,
desc: "Local Cursor agent"
} }
].map((opt) => ( ].map((opt) => (
<button <button
key={opt.value} key={opt.value}
disabled={!!opt.comingSoon}
className={cn( className={cn(
"flex flex-col items-center gap-1.5 rounded-md border p-3 text-xs transition-colors relative", "flex flex-col items-center gap-1.5 rounded-md border p-3 text-xs transition-colors relative",
opt.comingSoon adapterType === opt.value
? "border-border opacity-40 cursor-not-allowed" ? "border-foreground bg-accent"
: adapterType === opt.value : "border-border hover:bg-accent/50"
? "border-foreground bg-accent"
: "border-border hover:bg-accent/50"
)} )}
onClick={() => { onClick={() => {
if (opt.comingSoon) return;
const nextType = opt.value as AdapterType; const nextType = opt.value as AdapterType;
setAdapterType(nextType); setAdapterType(nextType);
if (nextType === "codex_local" && !model) { if (nextType === "codex_local" && !model) {
setModel(DEFAULT_CODEX_LOCAL_MODEL); setModel(DEFAULT_CODEX_LOCAL_MODEL);
} else if (nextType === "gemini_local" && !model) {
setModel(DEFAULT_GEMINI_LOCAL_MODEL);
} else if (nextType === "cursor" && !model) {
setModel(DEFAULT_CURSOR_LOCAL_MODEL);
} }
if (nextType === "opencode_local") { if (nextType !== "codex_local") {
if (!model.includes("/")) { setModel("");
setModel("");
}
return;
} }
setModel("");
}} }}
> >
{opt.recommended && ( <span className="absolute -top-1.5 right-1.5 bg-green-500 text-white text-[9px] font-semibold px-1.5 py-0.5 rounded-full leading-none">
<span className="absolute -top-1.5 right-1.5 bg-green-500 text-white text-[9px] font-semibold px-1.5 py-0.5 rounded-full leading-none"> Recommended
Recommended </span>
</span>
)}
<opt.icon className="h-4 w-4" /> <opt.icon className="h-4 w-4" />
<span className="font-medium">{opt.label}</span> <span className="font-medium">{opt.label}</span>
<span className="text-muted-foreground text-[10px]"> <span className="text-muted-foreground text-[10px]">
{opt.comingSoon {opt.desc}
? (opt as { disabledLabel?: string }).disabledLabel ??
"Coming soon"
: opt.desc}
</span> </span>
</button> </button>
))} ))}
</div> </div>
<button
className="flex items-center gap-1.5 mt-3 text-xs text-muted-foreground hover:text-foreground transition-colors"
onClick={() => setShowMoreAdapters((v) => !v)}
>
<ChevronDown className={cn("h-3 w-3 transition-transform", showMoreAdapters ? "rotate-0" : "-rotate-90")} />
More Agent Adapter Types
</button>
{showMoreAdapters && (
<div className="grid grid-cols-2 gap-2 mt-2">
{[
{
value: "gemini_local" as const,
label: "Gemini CLI",
icon: Gem,
desc: "Local Gemini agent"
},
{
value: "opencode_local" as const,
label: "OpenCode",
icon: OpenCodeLogoIcon,
desc: "Local multi-provider agent"
},
{
value: "pi_local" as const,
label: "Pi",
icon: Terminal,
desc: "Local Pi agent"
},
{
value: "cursor" as const,
label: "Cursor",
icon: MousePointer2,
desc: "Local Cursor agent"
},
{
value: "openclaw_gateway" as const,
label: "OpenClaw Gateway",
icon: Bot,
desc: "Invoke OpenClaw via gateway protocol",
comingSoon: true,
disabledLabel: "Configure OpenClaw within the App"
}
].map((opt) => (
<button
key={opt.value}
disabled={!!opt.comingSoon}
className={cn(
"flex flex-col items-center gap-1.5 rounded-md border p-3 text-xs transition-colors relative",
opt.comingSoon
? "border-border opacity-40 cursor-not-allowed"
: adapterType === opt.value
? "border-foreground bg-accent"
: "border-border hover:bg-accent/50"
)}
onClick={() => {
if (opt.comingSoon) return;
const nextType = opt.value as AdapterType;
setAdapterType(nextType);
if (nextType === "gemini_local" && !model) {
setModel(DEFAULT_GEMINI_LOCAL_MODEL);
return;
}
if (nextType === "cursor" && !model) {
setModel(DEFAULT_CURSOR_LOCAL_MODEL);
return;
}
if (nextType === "opencode_local") {
if (!model.includes("/")) {
setModel("");
}
return;
}
setModel("");
}}
>
<opt.icon className="h-4 w-4" />
<span className="font-medium">{opt.label}</span>
<span className="text-muted-foreground text-[10px]">
{opt.comingSoon
? (opt as { disabledLabel?: string }).disabledLabel ??
"Coming soon"
: opt.desc}
</span>
</button>
))}
</div>
)}
</div> </div>
{/* Conditional adapter fields */} {/* Conditional adapter fields */}