diff --git a/.changeset/terminal-title-status.md b/.changeset/terminal-title-status.md index 942b3de15f..4234657571 100644 --- a/.changeset/terminal-title-status.md +++ b/.changeset/terminal-title-status.md @@ -1,5 +1,6 @@ --- -"@kilocode/cli": patch +"@kilocode/cli": minor +"@kilocode/sdk": minor --- -Show terminal title status indicators when sessions are working, need attention, or have finished. +Add opt-in Unicode or emoji terminal title indicators for sessions that are working, need attention, or have finished. diff --git a/packages/kilo-console/src/routes/config/CliNotificationsRoute.tsx b/packages/kilo-console/src/routes/config/CliNotificationsRoute.tsx index e8621cffc9..84b48020eb 100644 --- a/packages/kilo-console/src/routes/config/CliNotificationsRoute.tsx +++ b/packages/kilo-console/src/routes/config/CliNotificationsRoute.tsx @@ -1,7 +1,14 @@ import { Button } from "@kilocode/kilo-web-ui/button" import { Card } from "@kilocode/kilo-web-ui/card" +import { CustomSelect, type SelectOption } from "../../components/CustomSelect" import { ConfigPage, ConfigTag as Tag } from "./ConfigPage" -import { useTuiNotificationSettings } from "./state/ui" +import { type TitleIcon, useTuiNotificationSettings } from "./state/ui" + +const icons = [ + { value: "none", label: "None" }, + { value: "unicode", label: "Unicode" }, + { value: "emojis", label: "Emojis" }, +] satisfies SelectOption[] function Toggle(props: { label: string @@ -34,57 +41,82 @@ export function CliNotificationsRoute() { return ( Save } > - -
-
-

Attention

-

Control when the TUI asks for attention and how it notifies you.

+
+ +
+
+

Terminal title

+

Choose how session status appears in the terminal tab title.

+
+
+
+
+ Title Icon + + None hides status icons. Unicode and Emojis show working, attention, and finished states. +
-
-
- state.setAlert(!state.alert())} - /> - state.setNotify(!state.notify())} - /> - state.setSound(!state.sound())} - /> -
+
+
) } diff --git a/packages/kilo-console/src/routes/config/state/ui.ts b/packages/kilo-console/src/routes/config/state/ui.ts index fa70ff062a..7f94285bf8 100644 --- a/packages/kilo-console/src/routes/config/state/ui.ts +++ b/packages/kilo-console/src/routes/config/state/ui.ts @@ -10,6 +10,7 @@ export type Theme = { } type Diff = "auto" | "stacked" +export type TitleIcon = NonNullable const fallback = ["#0c0a09", "#fafaf9", "#f9f76f", "#a6a09b", "#3794ff", "#44403b"] @@ -204,15 +205,18 @@ export function useTuiNotificationSettings() { const [notify, setNotify] = createSignal(true) const [sound, setSound] = createSignal(true) const [volume, setVolume] = createSignal("0.4") + const [icon, setIcon] = createSignal("none") const [dirty, setDirty] = createSignal(false) createEffect(() => { if (dirty()) return - const cfg = ctx.data()?.tui.attention + const tui = ctx.data()?.tui + const cfg = tui?.attention setAlert(bool(cfg?.enabled, false)) setNotify(bool(cfg?.notifications, true)) setSound(bool(cfg?.sound, true)) setVolume(String(cfg?.volume ?? 0.4)) + setIcon(tui?.title_icon ?? "none") }) function change(run: () => void) { @@ -228,6 +232,7 @@ export function useTuiNotificationSettings() { } ctx.tui({ + title_icon: icon(), attention: { enabled: alert(), notifications: notify(), @@ -248,6 +253,8 @@ export function useTuiNotificationSettings() { setSound: (value: boolean) => change(() => setSound(value)), volume, setVolume: (value: string) => change(() => setVolume(value)), + icon, + setIcon: (value: TitleIcon) => change(() => setIcon(value)), dirty, save, } diff --git a/packages/kilo-console/src/styles/cli-ui.css b/packages/kilo-console/src/styles/cli-ui.css index 89c066f803..c32380c9b4 100644 --- a/packages/kilo-console/src/styles/cli-ui.css +++ b/packages/kilo-console/src/styles/cli-ui.css @@ -8,17 +8,20 @@ background: var(--card); } -.kilo-console .ui-card:has(.console-diff-select[open]) { +.kilo-console .ui-card:has(.console-diff-select[open]), +.kilo-console .ui-card:has(.title-icon-select[open]) { position: relative; z-index: 40; overflow: visible; } -.kilo-console .console-diff-select[open] { +.kilo-console .console-diff-select[open], +.kilo-console .title-icon-select[open] { z-index: 41; } -.kilo-console .console-diff-select .models-select-menu { +.kilo-console .console-diff-select .models-select-menu, +.kilo-console .title-icon-select .models-select-menu { z-index: 42; } diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index ac08acacf0..98c8f1f0cd 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -371,6 +371,7 @@ function App(props: { onSnapshot?: () => Promise }) { base: titleDefault, sync, done: untrack(done), + icon: tuiConfig.title_icon, }) if (kiloTitle) { const id = kiloTitle.id diff --git a/packages/opencode/src/cli/cmd/tui/config/tui-schema.ts b/packages/opencode/src/cli/cmd/tui/config/tui-schema.ts index 1eec1e7a68..41864d80de 100644 --- a/packages/opencode/src/cli/cmd/tui/config/tui-schema.ts +++ b/packages/opencode/src/cli/cmd/tui/config/tui-schema.ts @@ -4,6 +4,7 @@ import { Schema } from "effect" import { isRecord } from "@/util/record" import { Filesystem } from "@/util/filesystem" import { TuiAttentionSoundNames, type TuiAttentionSoundName } from "@kilocode/plugin/tui" +import { KiloTitleIcon } from "@/kilocode/cli/cmd/tui/title-icon" // kilocode_change export type TuiAttentionSoundPaths = Partial> @@ -69,6 +70,7 @@ export const TuiInfo = Schema.Struct({ plugin_enabled: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)), leader_timeout: Schema.optional(KeymapLeaderTimeout), attention: Schema.optional(Attention), + title_icon: Schema.optional(KiloTitleIcon.Value), // kilocode_change scroll_speed: Schema.optional(ScrollSpeed).annotate({ description: "TUI scroll speed", }), diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx index 1dd6f89a87..58cf34b274 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/app.tsx @@ -25,6 +25,7 @@ import { initializeTUIDependencies } from "@kilocode/kilo-gateway/tui" import { DialogProcessList } from "@/kilocode/cli/cmd/tui/component/dialog-process-list" import { useIndexingWarnings } from "@/kilocode/cli/cmd/tui/indexing-warning" import { KiloTerminalTitle } from "./terminal-title" +import type { KiloTitleIcon } from "./title-icon" import { Session as SessionApi } from "@/session/session" // Re-export so upstream can render the route without importing directly @@ -122,10 +123,11 @@ export function getTerminalTitle(input: { base: string sync: ReturnType done: Record + icon?: KiloTitleIcon.Value }): KiloTerminalTitle.Result | undefined { if (input.route.data.type === "home") { return { - title: KiloTerminalTitle.format({ base: input.base, indicator: "none" }), + title: KiloTerminalTitle.format({ base: input.base, indicator: "none", icon: input.icon }), active: false, indicator: "none", } @@ -137,18 +139,24 @@ export function getTerminalTitle(input: { id: input.route.data.sessionID, data: input.sync.data, done: input.done, + icon: input.icon, }) const session = input.sync.session.get(input.route.data.sessionID) const title = !session || SessionApi.isDefaultTitle(session.title) ? undefined : session.title return { ...state, - title: KiloTerminalTitle.format({ base: input.base, title, indicator: state.indicator }), + title: KiloTerminalTitle.format({ base: input.base, title, indicator: state.indicator, icon: input.icon }), } } if (input.route.data.type === "plugin") { return { - title: KiloTerminalTitle.format({ base: input.base, title: input.route.data.id, indicator: "none" }), + title: KiloTerminalTitle.format({ + base: input.base, + title: input.route.data.id, + indicator: "none", + icon: input.icon, + }), active: false, indicator: "none", } @@ -156,7 +164,7 @@ export function getTerminalTitle(input: { if (input.route.data.type === "kiloclaw") { return { - title: KiloTerminalTitle.format({ base: input.base, title: "KiloClaw", indicator: "none" }), + title: KiloTerminalTitle.format({ base: input.base, title: "KiloClaw", indicator: "none", icon: input.icon }), active: false, indicator: "none", } diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx index bb9ac401c6..654efa6d99 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx +++ b/packages/opencode/src/kilocode/cli/cmd/tui/context/tui-config.tsx @@ -11,6 +11,7 @@ import { TuiConfig } from "@/cli/cmd/tui/config/tui" import { TuiKeybind } from "@/cli/cmd/tui/config/keybind" import { KeymapLeaderTimeoutDefault } from "@/cli/cmd/tui/config/tui-schema" import { createBindingLookup } from "@opentui/keymap/extras" +import { KiloTitleIcon } from "@/kilocode/cli/cmd/tui/title-icon" export type SetTuiConfig = (next: TuiConfig.Info) => void @@ -25,6 +26,7 @@ export namespace KiloTuiConfig { const keybinds = TuiKeybind.parse(next.keybinds ?? {}) const config: TuiConfig.Resolved = { ...next, + title_icon: next.title_icon ?? KiloTitleIcon.Default, attention: { enabled: next.attention?.enabled ?? false, notifications: next.attention?.notifications ?? true, diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/terminal-title.ts b/packages/opencode/src/kilocode/cli/cmd/tui/terminal-title.ts index 6a44e82c61..8a3959ce86 100644 --- a/packages/opencode/src/kilocode/cli/cmd/tui/terminal-title.ts +++ b/packages/opencode/src/kilocode/cli/cmd/tui/terminal-title.ts @@ -1,3 +1,5 @@ +import { KiloTitleIcon } from "./title-icon" + type Session = { id: string title: string @@ -44,28 +46,48 @@ export namespace KiloTerminalTitle { indicator: Indicator } - const icon = { - none: "", - working: "◔", - attention: "⚠", - finished: "✓", - } satisfies Record + const icons = { + none: { + none: "", + working: "", + attention: "", + finished: "", + }, + unicode: { + none: "", + working: "◔", + attention: "⚠", + finished: "✓", + }, + emojis: { + none: "", + working: "💭", + attention: "🔶", + finished: "✅", + }, + } satisfies Record> - export function format(input: { base: string; title?: string; indicator: Indicator }) { + export function format(input: { base: string; title?: string; indicator: Indicator; icon?: KiloTitleIcon.Value }) { const text = input.title ? `${input.base} | ${truncate(input.title)}` : input.base - const prefix = icon[input.indicator] + const prefix = icons[input.icon ?? KiloTitleIcon.Default][input.indicator] if (!prefix) return text return `${prefix} ${text}` } - export function session(input: { base: string; id: string; data: Data; done: Record }): Result { + export function session(input: { + base: string + id: string + data: Data + done: Record + icon?: KiloTitleIcon.Value + }): Result { const info = input.data.session.find((item) => item.id === input.id) const id = root(input.data.session, input.id) const ids = family(input.data.session, id) const indicator = state({ data: input.data, ids, done: input.done[id] === true }) return { - title: format({ base: input.base, title: info?.title, indicator }), + title: format({ base: input.base, title: info?.title, indicator, icon: input.icon }), id, active: indicator === "working" || indicator === "attention", indicator, diff --git a/packages/opencode/src/kilocode/cli/cmd/tui/title-icon.ts b/packages/opencode/src/kilocode/cli/cmd/tui/title-icon.ts new file mode 100644 index 0000000000..fc5f07b616 --- /dev/null +++ b/packages/opencode/src/kilocode/cli/cmd/tui/title-icon.ts @@ -0,0 +1,9 @@ +import { Schema } from "effect" + +export namespace KiloTitleIcon { + export const Value = Schema.Literals(["none", "unicode", "emojis"]).annotate({ + description: "Status icon style shown in terminal titles", + }) + export type Value = Schema.Schema.Type + export const Default = "none" satisfies Value +} diff --git a/packages/opencode/src/kilocode/server/httpapi/groups/config-console.ts b/packages/opencode/src/kilocode/server/httpapi/groups/config-console.ts index 97713e967b..be9dad2d42 100644 --- a/packages/opencode/src/kilocode/server/httpapi/groups/config-console.ts +++ b/packages/opencode/src/kilocode/server/httpapi/groups/config-console.ts @@ -1,6 +1,7 @@ import { Config } from "@/config/config" import { ConfigPlugin } from "@/config/plugin" import { KilocodeKeybinds } from "@/kilocode/tui/keybinds" +import { KiloTitleIcon } from "@/kilocode/cli/cmd/tui/title-icon" import { Authorization } from "@/server/routes/instance/httpapi/middleware/authorization" import { InstanceContextMiddleware } from "@/server/routes/instance/httpapi/middleware/instance-context" import { @@ -108,6 +109,7 @@ const TuiConfigShape = { keybinds: Schema.optional(Schema.Record(Schema.String, Schema.String)), plugin: Schema.optional(Schema.Array(ConfigPlugin.Spec)), plugin_enabled: Schema.optional(Schema.Record(Schema.String, Schema.Boolean)), + title_icon: Schema.optional(KiloTitleIcon.Value), scroll_speed: Schema.optional(Schema.Number), scroll_acceleration: Schema.optional(Schema.Struct({ enabled: Schema.Boolean })), diff_style: Schema.optional(Schema.Literals(["auto", "stacked"])), diff --git a/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts b/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts index 80f7c9d7dd..a17222163a 100644 --- a/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts +++ b/packages/opencode/test/kilocode/cli/cmd/tui/context/tui-config.test.ts @@ -9,6 +9,7 @@ import { createBindingLookup } from "@opentui/keymap/extras" import { TuiKeybind } from "@/cli/cmd/tui/config/keybind" import { TuiConfig } from "@/cli/cmd/tui/config/tui" import { KiloTuiConfig } from "@/kilocode/cli/cmd/tui/context/tui-config" +import { KiloTerminalTitle } from "@/kilocode/cli/cmd/tui/terminal-title" function cfg(input: Partial): TuiConfig.Info { return input as TuiConfig.Info @@ -18,6 +19,7 @@ function resolve(input: TuiConfig.Info): TuiConfig.Resolved { const keybinds = TuiKeybind.parse(input.keybinds ?? {}) return { ...input, + title_icon: input.title_icon ?? "none", attention: { enabled: input.attention?.enabled ?? false, notifications: input.attention?.notifications ?? true, @@ -40,31 +42,52 @@ describe("KiloTuiConfig.makeStore", () => { const exits: Array = [] const themes: Array = [] + const icons: Array = [] + const titles: string[] = [] let dispose!: () => void createRoot((d) => { dispose = d createEffect(() => exits.push(store.config.keybinds.get("app.exit")[0]?.key as string | undefined)) createEffect(() => themes.push(store.config.theme)) + createEffect(() => icons.push(store.config.title_icon)) + createEffect(() => + titles.push( + KiloTerminalTitle.format({ base: "Kilo CLI", indicator: "working", icon: store.config.title_icon }), + ), + ) }) // Initial tracked reads. expect(exits).toEqual(["ctrl+c"]) expect(themes).toEqual(["kilo"]) + expect(icons).toEqual(["none"]) + expect(titles).toEqual(["Kilo CLI"]) - store.set(cfg({ keybinds: { app_exit: "ctrl+q", leader: "ctrl+x" }, theme: "nord" })) + store.set(cfg({ keybinds: { app_exit: "ctrl+q", leader: "ctrl+x" }, theme: "nord", title_icon: "emojis" })) // Direct store reads reflect the update synchronously. expect(store.config.keybinds.get("app.exit")[0]?.key).toBe("ctrl+q") expect(store.config.keybinds.get("leader")[0]?.key).toBe("ctrl+x") expect(store.config.theme).toBe("nord") + expect(store.config.title_icon).toBe("emojis") // Tracked reactive reads re-ran with the new values (the hot-reload contract). expect(exits).toEqual(["ctrl+c", "ctrl+q"]) expect(themes).toEqual(["kilo", "nord"]) + expect(icons).toEqual(["none", "emojis"]) + expect(titles).toEqual(["Kilo CLI", "💭 Kilo CLI"]) dispose() }) + test("set() restores the default title icon when the setting is removed", () => { + const store = KiloTuiConfig.makeStore(resolve(cfg({ title_icon: "unicode" }))) + + store.set(cfg({})) + + expect(store.config.title_icon).toBe("none") + }) + test("set() does not re-notify a tracked read when its value is unchanged", () => { const store = KiloTuiConfig.makeStore(resolve(cfg({ keybinds: { app_exit: "ctrl+c" }, theme: "kilo" }))) diff --git a/packages/opencode/test/kilocode/server/tui-config.test.ts b/packages/opencode/test/kilocode/server/tui-config.test.ts index 638d2f6dd9..2bba0a2f92 100644 --- a/packages/opencode/test/kilocode/server/tui-config.test.ts +++ b/packages/opencode/test/kilocode/server/tui-config.test.ts @@ -74,15 +74,16 @@ describe("TUI config routes", () => { "content-type": "application/json", "x-kilo-directory": tmp.path, }, - body: JSON.stringify({ theme: "nord" }), + body: JSON.stringify({ theme: "nord", title_icon: "emojis" }), }) expect(response.status).toBe(200) - const body = (await response.json()) as { theme?: string } + const body = (await response.json()) as { theme?: string; title_icon?: string } expect(body.theme).toBe("nord") + expect(body.title_icon).toBe("emojis") const saved = await Bun.file(path.join(tmp.path, ".kilo", "tui.json")).json() - expect(saved).toEqual({ theme: "nord" }) + expect(saved).toEqual({ theme: "nord", title_icon: "emojis" }) }) test("patches attention config without dropping advanced notification settings", async () => { diff --git a/packages/opencode/test/kilocode/terminal-title.test.ts b/packages/opencode/test/kilocode/terminal-title.test.ts index 9e103df7d6..8fef983555 100644 --- a/packages/opencode/test/kilocode/terminal-title.test.ts +++ b/packages/opencode/test/kilocode/terminal-title.test.ts @@ -18,26 +18,26 @@ function data(input: Partial = {}): KiloTerminalTitle.Da } describe("KiloTerminalTitle", () => { - test("format_noIndicator_returnsBaseTitle", () => { - expect(KiloTerminalTitle.format({ base, indicator: "none" })).toBe("Kilo CLI") - }) - - test("format_workingPrefix_prependsThinkingIcon", () => { + test("format_noneStyle_hidesStatusIcon", () => { expect(KiloTerminalTitle.format({ base, title: "Build status", indicator: "working" })).toBe( - "◔ Kilo CLI | Build status", + "Kilo CLI | Build status", ) }) - test("format_attentionPrefix_prependsWarningIcon", () => { - expect(KiloTerminalTitle.format({ base, title: "Build status", indicator: "attention" })).toBe( - "⚠ Kilo CLI | Build status", - ) + test("format_noIndicator_returnsBaseTitle", () => { + expect(KiloTerminalTitle.format({ base, indicator: "none", icon: "unicode" })).toBe("Kilo CLI") }) - test("format_finishedPrefix_prependsCheckIcon", () => { - expect(KiloTerminalTitle.format({ base, title: "Build status", indicator: "finished" })).toBe( - "✓ Kilo CLI | Build status", - ) + test("format_unicodeStyle_usesUnicodeIcons", () => { + expect(KiloTerminalTitle.format({ base, indicator: "working", icon: "unicode" })).toBe("◔ Kilo CLI") + expect(KiloTerminalTitle.format({ base, indicator: "attention", icon: "unicode" })).toBe("⚠ Kilo CLI") + expect(KiloTerminalTitle.format({ base, indicator: "finished", icon: "unicode" })).toBe("✓ Kilo CLI") + }) + + test("format_emojiStyle_usesEmojiIcons", () => { + expect(KiloTerminalTitle.format({ base, indicator: "working", icon: "emojis" })).toBe("💭 Kilo CLI") + expect(KiloTerminalTitle.format({ base, indicator: "attention", icon: "emojis" })).toBe("🔶 Kilo CLI") + expect(KiloTerminalTitle.format({ base, indicator: "finished", icon: "emojis" })).toBe("✅ Kilo CLI") }) test("format_longSessionTitle_truncatesToExistingLimit", () => { @@ -46,6 +46,7 @@ describe("KiloTerminalTitle", () => { base, title: "12345678901234567890123456789012345678901234567890", indicator: "working", + icon: "unicode", }), ).toBe("◔ Kilo CLI | 1234567890123456789012345678901234567...") }) @@ -68,6 +69,7 @@ describe("KiloTerminalTitle", () => { id: "parent", data: data({ session_status: { parent: { type: "busy" } } }), done: {}, + icon: "unicode", }), ).toEqual({ title: "◔ Kilo CLI | Build status", id: "parent", active: true, indicator: "working" }) }) diff --git a/packages/opencode/test/kilocode/tui-terminal-title-reactivity.test.ts b/packages/opencode/test/kilocode/tui-terminal-title-reactivity.test.ts index 7ebfe8dd67..161c4b73c8 100644 --- a/packages/opencode/test/kilocode/tui-terminal-title-reactivity.test.ts +++ b/packages/opencode/test/kilocode/tui-terminal-title-reactivity.test.ts @@ -11,6 +11,12 @@ describe("terminal title done tracking", () => { expect(content).toContain("done: untrack(done)") }) + test("app.tsx reads the reactive title icon setting", () => { + const content = fs.readFileSync(APP_FILE, "utf-8") + + expect(content).toContain("icon: tuiConfig.title_icon") + }) + test("app.tsx untracks the done guard before setDone", () => { const content = fs.readFileSync(APP_FILE, "utf-8") diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index dbf279c109..a710dc2418 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -5267,6 +5267,7 @@ export class Config3 extends HeyApiClient { plugin_enabled?: { [key: string]: boolean } + title_icon?: "none" | "unicode" | "emojis" scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" scroll_acceleration?: { enabled: boolean @@ -5295,6 +5296,7 @@ export class Config3 extends HeyApiClient { { in: "body", key: "keybinds" }, { in: "body", key: "plugin" }, { in: "body", key: "plugin_enabled" }, + { in: "body", key: "title_icon" }, { in: "body", key: "scroll_speed" }, { in: "body", key: "scroll_acceleration" }, { in: "body", key: "diff_style" }, diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index b605d88a2c..7f5e3319be 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -2243,6 +2243,10 @@ export type TuiConfigGetResponse = { plugin_enabled?: { [key: string]: boolean } + /** + * Status icon style shown in terminal titles + */ + title_icon?: "none" | "unicode" | "emojis" scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" scroll_acceleration?: { enabled: boolean @@ -8644,6 +8648,10 @@ export type TuiConfigUpdateData = { plugin_enabled?: { [key: string]: boolean } + /** + * Status icon style shown in terminal titles + */ + title_icon?: "none" | "unicode" | "emojis" scroll_speed?: number | "NaN" | "Infinity" | "-Infinity" | "Infinity" | "-Infinity" | "NaN" scroll_acceleration?: { enabled: boolean diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 8243bf7d8e..1fdd9ea41d 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -10912,6 +10912,11 @@ "type": "boolean" } }, + "title_icon": { + "type": "string", + "enum": ["none", "unicode", "emojis"], + "description": "Status icon style shown in terminal titles" + }, "scroll_speed": { "anyOf": [ { @@ -21217,6 +21222,11 @@ "type": "boolean" } }, + "title_icon": { + "type": "string", + "enum": ["none", "unicode", "emojis"], + "description": "Status icon style shown in terminal titles" + }, "scroll_speed": { "anyOf": [ {