ui: UI/chat form follow ups (#26743)

* ui: split the markdown rendering setting per surface

User content and thinking get their own toggle again, so turning off
markdown for a message leaves reasoning blocks formatted. Both default
to markdown. A stored renderContentAsRawText unfolds onto the user key
and is dropped from the config.

File mentions render as badges in the raw text path too, through a
narrow pass over [name](file://path) that leaves everything else
untouched.

* ui: let the rich chat input scroll past its max height

The contenteditable renderer caps its height with max-height but had no
overflow rule, so a long buffer overflowed into the input area wrapper
and got clipped by its overflow-hidden, leaving no way to reach the
bottom of the message. The textarea renderer scrolls natively and was
never affected.

* ui: apply the new lint and format config

* ui: move the render keys unfolding into the migration service

Address review from @allozaur: the settings store no longer rewrites
persisted config on load, the raw text toggle now unfolds onto the
per-surface render keys in migration.service.ts, next to the other
config migrations. The mention scanner flag and the directory path
suffix become named constants.
This commit is contained in:
Pascal
2026-08-10 13:32:51 +02:00
committed by GitHub
parent e5275f6f77
commit 4dee52f82d
18 changed files with 282 additions and 109 deletions
+33 -1
View File
@@ -629,6 +629,37 @@ const configTypesMigration: Migration = {
console.log(`[Migration] Config types: coerced string booleans (changed=${changed})`);
}
};
const RENDER_KEYS_MIGRATION_ID = 'render-keys-unfold-v1';
const LEGACY_RENDER_RAW_TEXT_KEY = 'renderContentAsRawText';
const renderKeysMigration: Migration = {
description: 'Unfold the single raw text render toggle onto the per-surface render keys',
id: RENDER_KEYS_MIGRATION_ID,
async run(): Promise<void> {
const configRaw = localStorage.getItem(CONFIG_LOCALSTORAGE_KEY);
if (configRaw === null) return;
const config = JSON.parse(configRaw);
if (!(LEGACY_RENDER_RAW_TEXT_KEY in config)) return;
// The toggle carried user content and thinking at once and cannot say which surface
// was chosen, so it only restores the user key and thinking keeps its own default.
if (!(SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN in config)) {
config[SETTINGS_KEYS.RENDER_USER_CONTENT_AS_MARKDOWN] =
config[LEGACY_RENDER_RAW_TEXT_KEY] !== true;
}
// Dropped rather than preserved: the two render keys and the toggle describe the same
// surfaces, so leaving it behind would let a stale value fight the restored one.
delete config[LEGACY_RENDER_RAW_TEXT_KEY];
localStorage.setItem(CONFIG_LOCALSTORAGE_KEY, JSON.stringify(config));
if (import.meta.env.DEV && import.meta.env.VITE_DEBUG)
console.log('[Migration] Render keys: unfolded the raw text toggle');
}
};
const MCP_DEFAULT_OVERRIDES_LEGACY_KEY = `${STORAGE_APP_NAME}.mcpDefaultServerOverrides`;
const MCP_DEFAULT_OVERRIDES_MERGE_MIGRATION_ID = 'mcp-default-overrides-merge-v1';
/**
@@ -722,7 +753,8 @@ const migrations: Migration[] = [
customJsonKeyMigration,
mcpDefaultEnabledMigration,
mcpDefaultOverridesMergeMigration,
configTypesMigration
configTypesMigration,
renderKeysMigration
];
export const MigrationService = {