feat(app): add a checks display selector and name running services in the sidebar
Checks stopped being a toggle. Showing the icon without its word is a real third answer rather than half of "off" — the state stays on the row for a glance and a passing workspace stops paying a word for it on every line — so it left the boolean row-item record instead of widening it, and a stored `sidebarRowItems.checks === false` migrates to the new "none". The services item narrowed to actual services. It used to fall back to any running command, but a test watcher running says nothing about whether a workspace is up, and the item now says "Services" so drawing a terminal glyph under that label was a control lying about itself. It reports the name rather than the port because the name is what you called it. `health` was already on the wire and nothing in the sidebar read it, so a failed check now turns the whole item danger; where several services run, the failing one takes the single slot, since a healthy one is the unremarkable case and any of them says "this is up". That narrowing is why the rename went through the code and the persisted key rather than stopping at the label: the concept genuinely changed, and a UI saying "Services" over a `scripts` key is the synonym docs/glossary.md calls a design error. Both key migrations are tagged COMPAT. The rest is the sidebar row's geometry. The show-more and new-workspace rows each carried their own smaller, inset, less-rounded version of a workspace row — 24pt of left margin, a 14pt icon column, `borderRadius.md`, one fill for hover and press — which under a column of real rows reads as a mistake rather than a distinction. They now take the workspace row's geometry, and the show-more row asks its caller whether it is ending an indented list, because the two groupings disagree. Group spacing moved from margin to padding so a collapsed group gives it back instead of staying spaced for content that is gone. SPACING gained a 0.5 rung for the 2pt gap between rows.
This commit is contained in:
@@ -391,6 +391,29 @@ describe("appearance settings", () => {
|
||||
expect((await loadAppSettingsFromStorage(deps)).toolCallDetailLevel).toBe("overview");
|
||||
});
|
||||
|
||||
it("migrates a switched-off checks row item to the hidden checks display", async () => {
|
||||
const deps = makeDeps({
|
||||
storage: createInMemoryKeyValueStorage({
|
||||
[APP_SETTINGS_KEY]: JSON.stringify({ sidebarRowItems: { checks: false } }),
|
||||
}),
|
||||
});
|
||||
|
||||
expect((await loadAppSettingsFromStorage(deps)).sidebarChecksDisplay).toBe("none");
|
||||
});
|
||||
|
||||
it("lets a stored checks display win over the row item it replaced", async () => {
|
||||
const deps = makeDeps({
|
||||
storage: createInMemoryKeyValueStorage({
|
||||
[APP_SETTINGS_KEY]: JSON.stringify({
|
||||
sidebarChecksDisplay: "icon",
|
||||
sidebarRowItems: { checks: false },
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
expect((await loadAppSettingsFromStorage(deps)).sidebarChecksDisplay).toBe("icon");
|
||||
});
|
||||
|
||||
it("clamps the UI font size into range and rejects non-numeric values", async () => {
|
||||
const deps = makeDeps({
|
||||
storage: createInMemoryKeyValueStorage({
|
||||
|
||||
@@ -2,8 +2,14 @@ import { isSyntaxThemeId, type SyntaxThemeId } from "@getpaseo/highlight";
|
||||
import type { QueryClient } from "@tanstack/react-query";
|
||||
import type { DesktopSettings } from "@/desktop/settings/desktop-settings";
|
||||
import { parseAppLanguage, type AppLanguage } from "@/i18n/locales";
|
||||
import {
|
||||
DEFAULT_SIDEBAR_CHECKS_DISPLAY,
|
||||
parseSidebarChecksDisplay,
|
||||
type SidebarChecksDisplay,
|
||||
} from "@/components/sidebar/display-preferences/checks-display";
|
||||
import {
|
||||
DEFAULT_SIDEBAR_ROW_ITEMS,
|
||||
isChecksHiddenByLegacyRowItem,
|
||||
parseSidebarRowItems,
|
||||
type SidebarRowItems,
|
||||
} from "@/components/sidebar/display-preferences/row-items";
|
||||
@@ -56,6 +62,7 @@ export interface AppSettings {
|
||||
workspaceTitleSource: WorkspaceTitleSource;
|
||||
sidebarWorkspaceTrailing: SidebarWorkspaceTrailing;
|
||||
sidebarRowItems: SidebarRowItems;
|
||||
sidebarChecksDisplay: SidebarChecksDisplay;
|
||||
autoExpandReasoning: boolean;
|
||||
toolCallDetailLevel: ToolCallDetailLevel;
|
||||
chatOutlineEnabled: boolean;
|
||||
@@ -67,7 +74,14 @@ export interface Settings extends AppSettings {
|
||||
releaseChannel: ReleaseChannel;
|
||||
}
|
||||
|
||||
type StoredAppSettings = Partial<AppSettings> & { compactToolCalls?: unknown };
|
||||
/**
|
||||
* `sidebarRowItems` is widened back to `unknown` because it is still read for a value the
|
||||
* current shape no longer has — see `isChecksHiddenByLegacyRowItem`.
|
||||
*/
|
||||
type StoredAppSettings = Partial<Omit<AppSettings, "sidebarRowItems">> & {
|
||||
compactToolCalls?: unknown;
|
||||
sidebarRowItems?: unknown;
|
||||
};
|
||||
|
||||
export const DEFAULT_CLIENT_SETTINGS: AppSettings = {
|
||||
theme: "auto",
|
||||
@@ -84,6 +98,7 @@ export const DEFAULT_CLIENT_SETTINGS: AppSettings = {
|
||||
workspaceTitleSource: "title",
|
||||
sidebarWorkspaceTrailing: "diff",
|
||||
sidebarRowItems: DEFAULT_SIDEBAR_ROW_ITEMS,
|
||||
sidebarChecksDisplay: DEFAULT_SIDEBAR_CHECKS_DISPLAY,
|
||||
autoExpandReasoning: false,
|
||||
toolCallDetailLevel: "detailed",
|
||||
chatOutlineEnabled: true,
|
||||
@@ -208,6 +223,15 @@ function parseToolCallDetailLevel(stored: StoredAppSettings): ToolCallDetailLeve
|
||||
return null;
|
||||
}
|
||||
|
||||
function parseStoredSidebarChecksDisplay(stored: StoredAppSettings): SidebarChecksDisplay | null {
|
||||
const display = parseSidebarChecksDisplay(stored.sidebarChecksDisplay);
|
||||
if (display !== null) {
|
||||
return display;
|
||||
}
|
||||
// COMPAT(sidebarRowItemsChecks): migrated in v0.3.0, remove after 2027-08-05.
|
||||
return isChecksHiddenByLegacyRowItem(stored.sidebarRowItems) ? "none" : null;
|
||||
}
|
||||
|
||||
function pickBooleanAppSettings(stored: StoredAppSettings): Partial<AppSettings> {
|
||||
const result: Partial<AppSettings> = {};
|
||||
if (typeof stored.useLegacyTerminalRenderer === "boolean") {
|
||||
@@ -265,6 +289,10 @@ function pickAppSettings(stored: StoredAppSettings): Partial<AppSettings> {
|
||||
if (stored.sidebarRowItems !== undefined) {
|
||||
result.sidebarRowItems = parseSidebarRowItems(stored.sidebarRowItems);
|
||||
}
|
||||
const sidebarChecksDisplay = parseStoredSidebarChecksDisplay(stored);
|
||||
if (sidebarChecksDisplay !== null) {
|
||||
result.sidebarChecksDisplay = sidebarChecksDisplay;
|
||||
}
|
||||
const language = parseAppLanguage(stored.language);
|
||||
if (language !== null) {
|
||||
result.language = language;
|
||||
|
||||
Reference in New Issue
Block a user