diff --git a/packages/views/agents/components/runtime-picker.tsx b/packages/views/agents/components/runtime-picker.tsx
index 0bba620768..9893b38b8c 100644
--- a/packages/views/agents/components/runtime-picker.tsx
+++ b/packages/views/agents/components/runtime-picker.tsx
@@ -72,7 +72,6 @@ export function RuntimePicker({
}, [filteredRuntimes, search, currentUserId]);
const showSearch = runtimes.length > SEARCH_THRESHOLD;
- const showGroupHeaders = machines.length > 1;
const selectedRuntime =
runtimes.find((d) => d.id === selectedRuntimeId) ?? null;
@@ -210,17 +209,19 @@ export function RuntimePicker({
) : (
machines.map((machine) => (
- {showGroupHeaders && (
-
- {machine.title}
-
- {t(($) => $.create_dialog.runtime_group_online, {
- online: machine.onlineCount,
- total: machine.runtimes.length,
- })}
-
-
- )}
+ {/* Always show the machine header — even when a search or a
+ single-machine workspace narrows it to one group — so the
+ grouping stays consistent instead of collapsing to a flat
+ list. */}
+
+ {machine.title}
+
+ {t(($) => $.create_dialog.runtime_group_online, {
+ online: machine.onlineCount,
+ total: machine.runtimes.length,
+ })}
+
+
{machine.runtimes.map((device) => {
const ownerMember = getOwnerMember(device.owner_id);
const disabled = !isRuntimeUsableForUser(
diff --git a/packages/views/runtimes/components/runtime-machines.test.ts b/packages/views/runtimes/components/runtime-machines.test.ts
index 0218822222..b2887f338f 100644
--- a/packages/views/runtimes/components/runtime-machines.test.ts
+++ b/packages/views/runtimes/components/runtime-machines.test.ts
@@ -4,6 +4,7 @@ import {
buildRuntimeMachines,
filterRuntimeMachines,
runtimeMachineCounts,
+ sharedCustomName,
splitRuntimeName,
} from "./runtime-machines";
@@ -349,3 +350,33 @@ describe("splitRuntimeName", () => {
});
});
});
+
+describe("sharedCustomName", () => {
+ it("returns the name when every runtime shares one non-empty custom_name", () => {
+ expect(
+ sharedCustomName([
+ makeRuntime({ id: "a", custom_name: "Bohan's MacBook" }),
+ makeRuntime({ id: "b", custom_name: "Bohan's MacBook" }),
+ ]),
+ ).toBe("Bohan's MacBook");
+ });
+
+ it("returns null when only some runtimes are named (a lone per-runtime name is not the machine name)", () => {
+ expect(
+ sharedCustomName([
+ makeRuntime({ id: "a", custom_name: "just this one" }),
+ makeRuntime({ id: "b", custom_name: null }),
+ ]),
+ ).toBeNull();
+ });
+
+ it("returns null when the names disagree, or the set is empty", () => {
+ expect(
+ sharedCustomName([
+ makeRuntime({ id: "a", custom_name: "Air" }),
+ makeRuntime({ id: "b", custom_name: "Pro" }),
+ ]),
+ ).toBeNull();
+ expect(sharedCustomName([])).toBeNull();
+ });
+});
diff --git a/packages/views/runtimes/components/runtime-machines.ts b/packages/views/runtimes/components/runtime-machines.ts
index dcc1cc2463..bd123bac8b 100644
--- a/packages/views/runtimes/components/runtime-machines.ts
+++ b/packages/views/runtimes/components/runtime-machines.ts
@@ -274,7 +274,7 @@ function runtimeDeviceName(runtime: AgentRuntime): string | null {
// daemon, so a name shared by all of them is the machine's label. A one-off
// per-runtime rename (not shared) is deliberately ignored here so it can't
// masquerade as the whole machine's name.
-function sharedCustomName(runtimes: AgentRuntime[]): string | null {
+export function sharedCustomName(runtimes: AgentRuntime[]): string | null {
if (runtimes.length === 0) return null;
const names = runtimes.map((r) => r.custom_name?.trim() ?? "");
const first = names[0];
diff --git a/packages/views/runtimes/components/runtimes-page.tsx b/packages/views/runtimes/components/runtimes-page.tsx
index e234c7978b..acff03dfed 100644
--- a/packages/views/runtimes/components/runtimes-page.tsx
+++ b/packages/views/runtimes/components/runtimes-page.tsx
@@ -44,6 +44,7 @@ import {
buildRuntimeMachines,
filterRuntimeMachines,
runtimeMachineCounts,
+ sharedCustomName,
type RuntimeMachine,
type RuntimeMachineFilter,
} from "./runtime-machines";
@@ -254,8 +255,10 @@ export function RuntimesPage({
? m.runtimes[0]
: m.runtimes.find((r) => r.owner_id === currentUserId);
if (!editable) return null;
- const currentName =
- m.runtimes.find((r) => r.custom_name?.trim())?.custom_name?.trim() ?? "";
+ // Pre-fill only a real machine name — the same rule the machine title uses
+ // (every runtime shares one non-empty custom_name). A lone per-runtime
+ // custom name must NOT masquerade as the machine's current name.
+ const currentName = sharedCustomName(m.runtimes) ?? "";
return { runtimeId: editable.id, currentName };
}, [selectedMachine, canManageProfiles, currentUserId]);