isAllCapsWord matched any multi-letter token without a lowercase letter,
so CJK tokens registered as ALL-CAPS words: two adjacent ones marked the
whole source shouty and silently disabled acronym restoration for every
non-Latin-script message (e.g. '修复 CNPG 集群故障' kept 'Cnpg'). Require an
actual uppercase letter; cased-script shout detection is unchanged.
The PR's changelog, doc comment, and prompt examples all name ETL as a
restored acronym, but the review-response narrowing (vowel heuristic +
allowlist) silently dropped it: ETL bears a vowel and was not listed.
Add it to COMMON_TITLE_ACRONYMS and pin it in the allowlist test.
Narrow acronym restoration so plain all-caps English words such as FIX
and WORK do not get restored when the model naturally capitalizes the
first title word. Restorable all-caps source tokens now need a stronger
acronym signal: a common technical acronym allowlist, digits, or a
consonant-only shape.
This keeps CNPG, ETL, JWT, SQL, and API restoration while preserving the
anti-shout behavior for single emphatic words.
Fixes#4220
reconcileTitleCasing now maps ALL-CAPS source tokens (CNPG, API, ETL,
JWT) into an acronyms table and restores them when the model produces a
plain title-cased artifact (Cnpg). Restoration is disabled when the
source is shouty (>=2 consecutive multi-letter ALL-CAPS tokens like
"FIX the BUG NOW" or "ALL ERROR HANDLING"), and lowercase model output
is left alone so isolated single-word emphasis (WORK -> work) is never
re-shouted.
The three title system prompts (title-system.md, title-system-marker.md,
tiny-title-system.md) also gained an explicit instruction to preserve
ALL-CAPS acronyms verbatim, so a competent model short-circuits via the
verbatim set before post-processing kicks in.
Fixes#4220
- Updated `reconcileTitleCasing` to ignore purely uppercase words when restoring source casing.
- Restricted restoration logic to mixed-case identifiers (e.g., `TinyVMM`, `iOS`) to avoid overriding the model's clean sentence case with emphatic user shouting.
- Added regression tests to ensure all-caps input does not trigger title re-shouting.
- Updated `normalizeGeneratedTitle` to reconcile model-generated titles against the user's input instead of forcing title-case.
- Added logic to restore distinctive proper-noun casing (e.g., `TinyVMM`) and flatten model-generated camelCase artifacts (e.g., `dAemon`) that do not appear in the user's message.
- Ensured model-cased proper nouns that are not in the source message (e.g., `GitHub`) are preserved.
- Applied title-casing to `normalizeGeneratedTitle` outputs using a new internal helper.
- Adjusted tiny text and title generator tests to assert the new title-cased results.
- Adjusted session and dashboard renderers to derive heights from live terminal rows.
- Propagated terminal-row callbacks through picker/controller wiring and session selectors.
- Reworked list visibility and page navigation to honor row-based budgets and footer lines.
- Added DECRQM 2031 startup probing and stopped OSC11 polling once support was confirmed.
- Skipped titling for greeting/filler/empty first messages deterministically, retrying on later user messages.
- Let capable title models decline taskless input via a "none" sentinel.
- Guarded against clobbering a name set by a concurrent attempt.
- Added `stripCodeBlocks` to remove fenced code blocks before titling, preventing literal noise (e.g. version strings in UI mockups) from becoming the session title.
- Added `prepareTitleInput` composing strip and truncate steps, updated `formatTitleUserMessage` to use it.
- Added unit tests for stripping logic and an integration test verifying the model never receives code block contents.