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] =
useState(false);
const [unsetAnthropicLoading, setUnsetAnthropicLoading] = useState(false);
const [showMoreAdapters, setShowMoreAdapters] = useState(false);
// Step 3
const [taskTitle, setTaskTitle] = useState("Create your CEO HEARTBEAT.md");
@@ -669,87 +670,127 @@ export function OnboardingWizard() {
icon: Code,
desc: "Local Codex agent",
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) => (
<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"
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 === "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 (!model.includes("/")) {
setModel("");
}
return;
if (nextType !== "codex_local") {
setModel("");
}
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">
Recommended
</span>
)}
<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
</span>
<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}
{opt.desc}
</span>
</button>
))}
</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>
{/* Conditional adapter fields */}