Trim release UI: simpler Settings, mode menu, session subtitle

Mode menu offers Discuss/Ask for approval/Full access only.
Topbar subtitle is model-only and inert (persona page hidden this release).
This commit is contained in:
Rohit C Prasad
2026-07-23 07:43:24 -07:00
committed by Rohit P
parent 55ff8b76e9
commit 5a61873ae0
6 changed files with 28 additions and 78 deletions
+9 -13
View File
@@ -28,7 +28,7 @@ import {
type SurfaceVisibility,
} from "./api";
import type { ApprovalDecision, Attachment, Item, SessionInfo, TodoItem, WsEvent } from "./types";
import { isProjectScoped, shortPersonaName } from "./personaScope";
import { isProjectScoped } from "./personaScope";
import { baseName } from "./paths";
import { itemsFromMessages } from "./itemsFromMessages";
import { streamMode } from "./streamGate";
@@ -1076,9 +1076,7 @@ export function App() {
const pendingDirReq = [...items].reverse().find((i) => i.kind === "dirreq" && !i.resolved);
const pendingPlan = [...items].reverse().find((i) => i.kind === "planreq" && !i.resolved);
const pendingQuestion = [...items].reverse().find((i) => i.kind === "question" && !i.resolved);
// Topbar trim: the active persona's short display name (mock's "· SRE persona").
const personaName = shortPersonaName(personaOf(agent)?.name, agent);
// Facts subtitle (§22): the session's FIXED facts, not controls — persona · model (+ the
// Facts subtitle (§22): the session's FIXED facts, not controls — model (+ the
// workspace folder for project-scoped sessions). Renders only once the session has history;
// until then the model is still choosable in the composer, so there's no locked fact to state.
const hasHistory = items.length > 0;
@@ -1087,7 +1085,9 @@ export function App() {
const modelDisplay =
modelLabels[model]?.split(" · ")[0] ||
(model.includes(":") ? model.split(":").slice(1).join(":") : model);
const subtitleParts = [personaName, modelDisplay];
// Persona name dropped for this release (owner ask 2026-07-22): personas are hidden,
// so "Coworker" read as noise. The model (+ project folder) are the real fixed facts.
const subtitleParts = [modelDisplay];
if (isProjectScoped(personaOf(agent)) && workspace) subtitleParts.push(baseName(workspace));
const activeInfo = sessions.find((s) => s.session_id === sessionId);
const activeTitle = activeInfo?.title || "New session";
@@ -1343,16 +1343,12 @@ export function App() {
>
{activeTitle}
</span>
{/* Plain facts, no affordance: the persona page it used to open is hidden for
this release (owner ask 2026-07-22). */}
{hasHistory && (
<button
className="title-sub"
data-testid="session-subtitle"
onMouseDown={(e) => e.stopPropagation()}
onClick={agent !== "chat" ? () => openPersona(agent, "session") : undefined}
title={agent !== "chat" ? "About this coworker" : undefined}
>
<span className="title-sub" data-testid="session-subtitle">
{subtitleParts.join(" · ")}
</button>
</span>
)}
</div>
{/* Right: session-settings icon (§23) + panel toggle. Model/mode/persona chrome is
+4 -2
View File
@@ -15,12 +15,14 @@ import {
type DictationStatus,
} from "../tauri";
// Plan + Custom hidden for this release (owner ask 2026-07-22): Plan's approval flow isn't
// polished enough to ship, and Custom (config.toml auto-allow rules) is a power-user mode
// with no in-app explanation. The server still honors both — a session already in one of
// those modes keeps working; the picker just doesn't offer them.
const PERMISSION_OPTIONS: Option[] = [
{ value: "discuss", label: "Discuss", description: "Chat and explore — no edits or commands" },
{ value: "plan", label: "Plan", description: "Explore read-only, propose a plan for approval, then build" },
{ value: "interactive", label: "Ask for approval", description: "Ask before edits and commands" },
{ value: "auto", label: "Full access", description: "Run everything without asking" },
{ value: "custom", label: "Custom", description: "Use auto-allow rules from config.toml" },
];
// No hardcoded model fallback: until the server supplies the list (a few seconds after a
+2 -46
View File
@@ -1,14 +1,10 @@
import { useEffect, useState } from "react";
import {
CLOUD_CHANGED,
getCloudStatus,
getSettings,
setCloudTelemetry,
setOnboarded,
setPdfSettings,
setScratchBase,
setSessionsPeek,
type CloudStatus,
type ModelSettings,
type PdfSettings,
} from "../api";
@@ -428,8 +424,6 @@ function AppearanceSection() {
<FilesCard />
<TelemetryCard />
{desktop && (
<div className={CARD + " p-4"}>
<div className={FIELD_LABEL + " mb-2.5"}>Always-on</div>
@@ -524,46 +518,8 @@ function UpdateInline() {
);
}
// -- Telemetry (moved here from the retired Connectors-page cloud strip, §26) -----
function TelemetryCard() {
const [cloud, setCloud] = useState<CloudStatus | null>(null);
const [telemetry, setTelemetry] = useState<boolean | null>(null);
useEffect(() => {
const load = () => getCloudStatus().then(setCloud).catch(() => {});
load();
// Sign-in/out lands out-of-band (browser flow, account row) — refetch on the announce.
window.addEventListener(CLOUD_CHANGED, load);
return () => window.removeEventListener(CLOUD_CHANGED, load);
}, []);
// Signed out there is nothing to toggle — telemetry is a no-op without a cloud session.
if (!cloud?.signed_in) return null;
return (
<div className={CARD + " p-4 mb-4"}>
<div className={FIELD_LABEL + " mb-2.5"}>Privacy</div>
<label className="flex items-start gap-3 py-1 select-none">
<input
type="checkbox"
className="mt-0.5"
checked={telemetry ?? cloud.telemetry_enabled !== false}
data-testid="telemetry-toggle"
onChange={async (e) => {
setTelemetry(e.target.checked);
await setCloudTelemetry(e.target.checked);
}}
/>
<span>
<span className="block text-[13px] text-ink">Help improve OpenWorker</span>
<span className="block text-[12px] text-muted">
Which coworker type was started and when; never your prompts, files, or connector
data. Signed-out installs send nothing regardless.
</span>
</span>
</label>
</div>
);
}
// Telemetry/Privacy card removed for this release (owner ask 2026-07-22); the
// setCloudTelemetry API stays for a future opt-out surface.
// -- Sidebar density -------------------------------------------------------------
// -- Token savings (PDF attachments; owner ask, 2026-07-17) ---------------------