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:
@@ -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 */}
|
||||||
|
|||||||
Reference in New Issue
Block a user