Files
multica/packages/views/onboarding/components/compact-runtime-row.tsx
Naiyuan Qing 7cc763bbfb fix(runtimes): show runtime aliases across user-facing surfaces (MUL-5248) (#5881)
Several UIs rendered the raw daemon name (runtime.name) and dropped the
user's custom_name alias: the Skills "Copy from runtime" selector, the
Skills list/detail source, the agent creation runtime chip, the agent
runtime filter, the agent overview, the skills/MCP runtime hints, the
runtime delete confirmations, the desktop runtime window title, the
onboarding runtime cards/hints, and the task transcript chip.

Route every user-visible runtime label through the shared display contract:
- runtimeDisplayLabel (alias + provider) for standalone labels
- runtimeDisplayName (alias only) where a provider icon/text sits beside it
- machine.title + runtimeRowLabel(runtime, machine.title) inside machine groups

The Skills "Copy from runtime" selector is now machine-grouped via the shared
buildRuntimeMachines/runtimeRowLabel helpers instead of a flat raw-name list;
runtime.name stays the source of identity for hostname parsing, grouping,
search, and protocol payloads only.

Add a conventions rule (en + zh) forbidding raw runtime.name in user-visible
JSX/i18n/Select labels/document titles.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-07-24 15:54:48 +08:00

60 lines
1.8 KiB
TypeScript

import { cn } from "@multica/ui/lib/utils";
import type { AgentRuntime } from "@multica/core/types";
import { runtimeDisplayName } from "@multica/core/runtimes";
import { ProviderLogo } from "../../runtimes/components/provider-logo";
import { useT } from "../../i18n";
/**
* One-line runtime row for Step 3's web CLI expand. Provider logo,
* name + subtitle, online indicator on the right. Selection state is
* driven by the caller (kept stateless so both StepPlatformFork and
* any future embedder can share it without duplicating the picker
* plumbing).
*/
export function CompactRuntimeRow({
runtime,
selected,
onSelect,
}: {
runtime: AgentRuntime;
selected: boolean;
onSelect: () => void;
}) {
const { t: tAgents } = useT("agents");
const online = runtime.status === "online";
return (
<div
role="button"
tabIndex={0}
onClick={onSelect}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
onSelect();
}
}}
className={cn(
"flex cursor-pointer flex-row items-center gap-3 rounded-lg border bg-card p-4 transition-colors",
selected
? "border-primary ring-1 ring-primary"
: "hover:border-foreground/20",
)}
>
<ProviderLogo provider={runtime.provider} className="h-5 w-5" />
<div className="min-w-0 flex-1">
<div className="truncate text-sm font-medium">
{runtimeDisplayName(runtime)}
</div>
<div className="text-xs text-muted-foreground">{runtime.provider}</div>
</div>
<span
className={cn(
"h-2 w-2 shrink-0 rounded-full",
online ? "bg-success" : "bg-muted-foreground/40",
)}
aria-label={online ? tAgents(($) => $.availability.online) : tAgents(($) => $.availability.offline)}
/>
</div>
);
}