feat(tui): supported risk notes with warning glyphs in settings lists
- Add support for risk notes and warning markers on setting items in the TUI settings list component. - Update the external thinking setting schema and help command to include a warning about provider abuse enforcement.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
|
||||
- `/settings` rows can now carry a risk note: a warning glyph on the row plus a warning-colored line above the description. `External Thinking` (`externalThinking`, `--external-thinking`) is the first user — providers have flagged the request shape it produces as abuse, up to account-level enforcement, so both the settings entry and `--help` now say so.
|
||||
|
||||
## [17.3.8] - 2026-08-19
|
||||
|
||||
### Added
|
||||
|
||||
@@ -78,7 +78,8 @@ export const launchHelp = {
|
||||
description: "Enable the advisor runtime (passively reviews each turn and injects notes)",
|
||||
}),
|
||||
"external-thinking": Flags.boolean({
|
||||
description: "Use a private scratchpad while disabling supported GPT, Claude, and Gemini reasoning",
|
||||
description:
|
||||
"Use a private scratchpad while disabling supported GPT, Claude, and Gemini reasoning (at your own risk: providers have flagged this request shape as abuse)",
|
||||
}),
|
||||
hook: Flags.string({ description: "Load a hook/extension file (can be used multiple times)", multiple: true }),
|
||||
extension: Flags.string({
|
||||
|
||||
@@ -199,6 +199,12 @@ interface UiBase {
|
||||
group?: string;
|
||||
label: string;
|
||||
description: string;
|
||||
/**
|
||||
* Risk note. Marks the settings row with a warning glyph and renders above
|
||||
* the description in warning styling. For settings that can get the user
|
||||
* rate-limited, flagged, or banned — not for merely advanced options.
|
||||
*/
|
||||
warning?: string;
|
||||
/** Condition function name - setting only shown when true */
|
||||
condition?: string;
|
||||
}
|
||||
@@ -1139,6 +1145,8 @@ export const SETTINGS_SCHEMA = {
|
||||
group: "Thinking",
|
||||
label: "External Thinking",
|
||||
description: "Private scratchpad; not shown to user. Disables supported GPT, Claude, and Gemini reasoning",
|
||||
warning:
|
||||
"At your own risk: providers have flagged this request shape as abuse, up to account-level enforcement",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ interface BaseSettingDef {
|
||||
path: SettingPath;
|
||||
label: string;
|
||||
description: string;
|
||||
/** Risk note shown in warning styling; set for settings that can get the user flagged or banned. */
|
||||
warning?: string;
|
||||
tab: SettingTab;
|
||||
/** Section within the tab; items are ordered by TAB_GROUPS[tab] and rendered under a heading row. */
|
||||
group?: string;
|
||||
@@ -162,7 +164,15 @@ function pathToSettingDef(path: SettingPath): SettingDef | null {
|
||||
|
||||
const schemaType = getType(path);
|
||||
const condition = ui.condition ? CONDITIONS[ui.condition] : undefined;
|
||||
const base = { path, label: ui.label, description: ui.description, tab: ui.tab, group: ui.group, condition };
|
||||
const base = {
|
||||
path,
|
||||
label: ui.label,
|
||||
description: ui.description,
|
||||
warning: ui.warning,
|
||||
tab: ui.tab,
|
||||
group: ui.group,
|
||||
condition,
|
||||
};
|
||||
|
||||
if (schemaType === "boolean") {
|
||||
return { ...base, type: "boolean" };
|
||||
|
||||
@@ -927,67 +927,47 @@ export class SettingsSelectorComponent implements Component {
|
||||
}
|
||||
|
||||
const currentValue = this.#getCurrentValue(def);
|
||||
const changed = this.#isChanged(def, currentValue);
|
||||
const item = {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
warning: def.warning,
|
||||
changed: this.#isChanged(def, currentValue),
|
||||
};
|
||||
|
||||
switch (def.type) {
|
||||
case "boolean":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
currentValue: currentValue ? "true" : "false",
|
||||
values: ["true", "false"],
|
||||
changed,
|
||||
};
|
||||
return { ...item, currentValue: currentValue ? "true" : "false", values: ["true", "false"] };
|
||||
|
||||
case "enum":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
currentValue: String(currentValue ?? ""),
|
||||
values: [...def.values],
|
||||
changed,
|
||||
};
|
||||
return { ...item, currentValue: String(currentValue ?? ""), values: [...def.values] };
|
||||
|
||||
case "submenu":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
...item,
|
||||
currentValue: this.#getSubmenuCurrentValue(def.path, currentValue),
|
||||
submenu: (cv, done) => this.#createSubmenu(def, cv, done),
|
||||
changed,
|
||||
};
|
||||
|
||||
case "text":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
...item,
|
||||
currentValue: this.#formatTextInputValue(def, currentValue),
|
||||
submenu: (cv, done) => this.#createTextInput(def, cv, done),
|
||||
changed,
|
||||
};
|
||||
|
||||
case "providerLimits":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
...item,
|
||||
currentValue: this.#formatProviderLimitsValue(currentValue),
|
||||
submenu: (_cv, done) => this.#createProviderLimitsInput(done),
|
||||
changed,
|
||||
};
|
||||
|
||||
case "multiselect":
|
||||
return {
|
||||
id: def.path,
|
||||
label: def.label,
|
||||
description: def.description,
|
||||
...item,
|
||||
currentValue: this.#formatMultiSelectValue(def, currentValue),
|
||||
submenu: (_cv, done) => this.#createMultiSelect(def, done),
|
||||
changed,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,6 +254,8 @@ export function getSettingsListTheme(): SettingsListTheme {
|
||||
label: (text: string) => text,
|
||||
value: (text: string) => text,
|
||||
description: (text: string) => text,
|
||||
warning: (text: string) => text,
|
||||
warningMark: "!",
|
||||
cursor: "> ",
|
||||
hint: (text: string) => text,
|
||||
heading: (text: string) => text,
|
||||
@@ -267,6 +269,8 @@ export function getSettingsListTheme(): SettingsListTheme {
|
||||
value: (text: string, selected: boolean, changed: boolean) =>
|
||||
changed ? theme.fg("statusLineGitDirty", text) : selected ? theme.fg("accent", text) : theme.fg("muted", text),
|
||||
description: (text: string) => theme.fg("dim", text),
|
||||
warning: (text: string) => theme.fg("warning", text),
|
||||
warningMark: theme.status.warning,
|
||||
cursor: theme.fg("accent", `${theme.nav.cursor} `),
|
||||
hint: (text: string) => theme.fg("dim", text),
|
||||
heading: (text: string, dimmed: boolean) =>
|
||||
|
||||
Reference in New Issue
Block a user