From 8428bd15b4348cdf0b04d6ab46ac8bee9ba387aa Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 8 Jul 2026 17:53:22 -0400 Subject: [PATCH 1/6] docs: shell-integration marks reference and accurate ANSI detection chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - terminal-integration: new "Shell integration marks (OSC 133 / OSC 633)" section (opt-in setup, mark table, modes, structural gates, E-mark privacy note, Windows Terminal settings note, ShellIntegrationStatus troubleshooting); move OSC 133 from "not yet implemented" to "currently in place". - customization: replace the speculative detection steps (COLORTERM, platform checks) with the actual chain — session override, AnsiMode, NO_COLOR, CLICOLOR_FORCE, TERM=dumb, redirection. --- src/content/docs/reference/customization.mdx | 11 +-- .../docs/reference/terminal-integration.mdx | 69 ++++++++++++++++++- 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/content/docs/reference/customization.mdx b/src/content/docs/reference/customization.mdx index f36cdcc..2eafbe5 100644 --- a/src/content/docs/reference/customization.mdx +++ b/src/content/docs/reference/customization.mdx @@ -70,11 +70,12 @@ Repl detects the terminal's color capability at startup and chooses rendering ac **Detection chain** (first match wins): -1. `NO_COLOR` env var → disable ANSI -2. `CLICOLOR_FORCE` env var → force ANSI -3. `TERM` / `COLORTERM` heuristics -4. Platform-specific checks (Windows Console, VS Code terminal, etc.) -5. Redirection check (piped stdout → no ANSI) +1. Session override — a hosted session can force ANSI on or off (`TerminalSessionOverrides.AnsiSupported`) +2. Explicit `OutputOptions.AnsiMode` (`Always` / `Never`) +3. `NO_COLOR` env var → disable ANSI +4. `CLICOLOR_FORCE=1` env var → force ANSI (even when stdout is redirected) +5. `TERM=dumb` → disable ANSI +6. Redirection check (piped stdout → no ANSI) Override programmatically using : diff --git a/src/content/docs/reference/terminal-integration.mdx b/src/content/docs/reference/terminal-integration.mdx index 5d915cf..a98ae08 100644 --- a/src/content/docs/reference/terminal-integration.mdx +++ b/src/content/docs/reference/terminal-integration.mdx @@ -1,12 +1,12 @@ --- title: Terminal Integration -description: Terminal features used by Repl — size detection, keyboard input, progress reporting, terminal capabilities, and the path toward a future TUI mode. +description: Terminal features used by Repl — size detection, keyboard input, progress reporting, shell-integration marks, terminal capabilities, and the path toward a future TUI mode. --- import { Aside } from '@astrojs/starlight/components'; import ApiRef from '../../../components/ApiRef.astro'; -Repl integrates with the host terminal at several levels: it detects window size, decodes VT keyboard sequences, emits progress notifications to capable terminals, and classifies terminal identity to adapt rendering. This page documents those interactions. +Repl integrates with the host terminal at several levels: it detects window size, decodes VT keyboard sequences, emits progress notifications and shell-integration marks to capable terminals, and classifies terminal identity to adapt rendering. This page documents those interactions. **VT sequence notation used throughout this page:** @@ -140,6 +140,68 @@ OSC 9;4 is never emitted when ANSI output is disabled or when the session is in --- +## Shell integration marks (OSC 133 / OSC 633) + +Modern terminals understand semantic marks that delimit the prompt, the user input, and the command output. When the marks are present, the terminal can offer command navigation (jump between commands), command-aware selection and copy, success/failure decorations in the gutter, and sticky command headers. Repl owns the prompt and the command lifecycle in interactive mode, so it emits those marks itself — no shell script hooks required. + +The feature is opt-in: + +```csharp +var app = ReplApp.Create() + .UseTerminalIntegration(); // ShellIntegration = Auto by default + +// or explicitly: +app.UseTerminalIntegration(options => +{ + options.ShellIntegration = ShellIntegrationMode.Always; +}); +``` + +Each interactive prompt cycle is delimited with the FinalTerm semantic sequence (OSC 133), or the VS Code shell-integration dialect (OSC 633) when the VS Code integrated terminal is detected: + +| Moment | Mark | +|---|---| +| Before the prompt text | `A` (prompt start) | +| After the prompt text, before input | `B` (input start) | +| After a committed line (VS Code only) | `E;` (command-line report) | +| Right before command execution | `C` (output start) | +| After the command completes | `D;` (command end) | + +Exit codes follow shell conventions: `0` for success, `1` for errors (failed results, unknown commands, validation failures), and `130` (128+SIGINT) when a command is cancelled with Ctrl+C. An abandoned cycle — Escape at the prompt, an empty line, or end of input — reports `D` without an exit code, the FinalTerm "command aborted" form. + +### Modes + +`ShellIntegrationMode` mirrors the `AdvancedProgressMode` semantics: + +- **`Auto`** (default) — emit when the terminal is known to render marks. For a hosted session, only what the remote client advertised counts: `TerminalCapabilities.ShellIntegrationMarks`, usually inferred from its reported terminal identity. For the local console, the environment identifies Windows Terminal (`WT_SESSION`), VS Code (`TERM_PROGRAM=vscode`), or WezTerm (`TERM_PROGRAM=WezTerm`); multiplexers (tmux, GNU screen) stay off because mark positioning is unreliable through panes. +- **`Always`** — emit whenever the structural gates allow it. Useful for terminals that render marks but are not auto-detected, such as iTerm2 reached over SSH. +- **`Never`** — never emit. + +Regardless of mode, marks are never written when output is redirected (and no hosted session is active), when ANSI output is disabled (`NO_COLOR`, `TERM=dumb`, `AnsiMode.Never`), or around a protocol-passthrough command (MCP stdio, completion payloads) — no mark may sit inside a raw protocol stream. + +CLI one-shot mode emits no marks: Repl does not own the surrounding shell prompt there, and fake prompt markers would corrupt the host shell's own command navigation. + + + + + +### Troubleshooting + +Ask the running app first: exposes `ShellIntegrationStatus`, which reports the detection outcome for the current prompt cycle — the active dialect (`"OSC 133"`, `"OSC 633 (VS Code)"`) or `"off ()"` naming the gate that disabled emission: + +```csharp +app.Map("terminal", (IReplSessionInfo session) => + session.ShellIntegrationStatus ?? "no prompt cycle yet"); +``` + +If a terminal is misdetected and shows raw `]133;…` text, set `ShellIntegrationMode.Never` app-side, or use `NO_COLOR=1` as a local end-user escape hatch (it disables all ANSI styling, marks included). For hosted sessions, fix the identity or capabilities the client advertises — environment variables on the server affect every connected session. + +--- + ## Terminal capabilities When a session connects, Repl classifies its terminal identity to determine which capabilities to enable. The identity string comes from: @@ -214,6 +276,7 @@ In CLI mode, Repl suppresses banners and interactive prompts automatically. For **Currently in place:** - OSC 9;4 progress in supported terminals +- Shell-integration marks (OSC 133 / OSC 633) for command navigation and gutter decorations - ANSI 256-color rendering (default) and 24-bit color via `Repl.Spectre` - Screen clear and cursor positioning for interactive menus - VT key decoding (arrows, Home/End, PgUp/PgDn, F1–F4) @@ -227,7 +290,7 @@ In CLI mode, Repl suppresses banners and interactive prompts automatically. For - Alternate screen buffer (`?1049`) - Bracketed paste mode (`?2004`) - Sixel and Kitty graphics -- OSC 7 (working directory), OSC 8 (hyperlinks), OSC 52 (clipboard), OSC 133 (shell integration marks) +- OSC 7 (working directory), OSC 8 (hyperlinks), OSC 52 (clipboard) - True-color palette in the default renderer (256-color only; 24-bit available via `Repl.Spectre`) These primitives form the foundation for a future TUI mode — full-screen, keystroke-driven surfaces (panels, menus, live updates) that will compose with the same command graph. The current `Repl.Spectre` integration covers static rich rendering; a dedicated `Repl.Tui` package is on the roadmap. From ac07e74e7f49a037c0817e9bd1f797030e4858d2 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 15 Jul 2026 13:27:05 -0400 Subject: [PATCH 2/6] docs: interactive and shell completion catch-up - repl-mode: Tab menu completes option names (route, global, result-flow), runs WithCompletion providers first with enum member fallback, and runs every registered provider (in-process). - cli-mode: document what shell completion returns, per-provider opt-in via CompletionProviderScope.InteractiveAndShell, provider timeout, and the two deliberate differences with the interactive menu. - configuration: mention the CompletionProviderScope argument. Covers yllibed/repl PRs #50 and #55. Co-Authored-By: Claude Fable 5 --- src/content/docs/getting-started/cli-mode.mdx | 21 +++++++++++++++++++ .../docs/getting-started/repl-mode.mdx | 10 ++++++++- src/content/docs/reference/configuration.mdx | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/content/docs/getting-started/cli-mode.mdx b/src/content/docs/getting-started/cli-mode.mdx index 3916c90..4ff1f34 100644 --- a/src/content/docs/getting-started/cli-mode.mdx +++ b/src/content/docs/getting-started/cli-mode.mdx @@ -74,6 +74,27 @@ myapp completion install --shell nu # Nushell This writes a managed block to the shell's profile file. Tab completion then works for all routes, context segments, and option names. +**What completion returns:** + +- Command literals and context segments from your graph. +- The route's own options, plus static global options (`--help`, `--interactive`, `--no-interactive`, `--no-logo`, output aliases, `--output:`, `--answer:`, and the result-flow flags `--result:page-size`, `--result:cursor`, `--result:pager`, `--result:all`). +- Enum member names for a pending enum-typed option. +- `.WithCompletion(...)` provider values — **opt-in per provider**. + +Every shell Tab spawns a new process and blocks the shell until the app answers, so a slow completion provider (network, database) must never run there implicitly. A provider only serves shell completion when its registration opts in: + +```csharp +app.Map("contact inspect {clientId}", (string clientId) => Inspect(clientId)) + .WithCompletion( + "clientId", + (ctx, input, ct) => LookupClientIdsAsync(input, ct), + CompletionProviderScope.InteractiveAndShell); +``` + +The default scope (`CompletionProviderScope.Interactive`) keeps the provider on in-process surfaces only: the interactive Tab menu and the `complete` ambient command. Each provider invocation is also bounded by `ShellCompletionOptions.ProviderTimeout` (default: 1 second) — a stalled provider degrades completion to the static candidates instead of blocking the shell. + +Shell completion and the [interactive REPL autocomplete](/getting-started/repl-mode/#history-and-completion) draw candidates from the same source and parse prior tokens the same way. Two deliberate differences remain: on an empty token after a complete command, shell completion lists option names while the interactive menu shows parameter placeholders (options appear from the first typed `-`); and the interactive menu runs every registered provider while the shell bridge only runs opted-in ones. + **Other commands:** ```bash diff --git a/src/content/docs/getting-started/repl-mode.mdx b/src/content/docs/getting-started/repl-mode.mdx index a500b43..c9cd54a 100644 --- a/src/content/docs/getting-started/repl-mode.mdx +++ b/src/content/docs/getting-started/repl-mode.mdx @@ -65,9 +65,17 @@ These are always available in REPL mode regardless of your command graph: ## History and completion - **Up/Down arrows** navigate command history. -- **Tab** triggers autocomplete for routes and parameters (requires `UseDefaultInteractive()`). +- **Tab** triggers autocomplete (requires `UseDefaultInteractive()`). - History is in-memory by default and does not persist across sessions. Inject a custom to add persistence (file, database, or any backing store). +The Tab menu completes: + +- **Routes and context segments** from your command graph, with parameter placeholders shown for the positions a command still expects. +- **Option names**, from the first typed `-`: the route's own options, global options (`--help`, `--output:`, `--answer:`, …), and the result-flow flags (`--result:page-size`, `--result:cursor`, `--result:pager`, `--result:all`). +- **Option and parameter values**: a `.WithCompletion(...)` provider runs first, and enum-typed parameters fall back to their member names (respecting the parameter's effective case sensitivity). + +Unlike [shell completion](/getting-started/cli-mode/#shell-completion), which is opt-in per provider, the interactive menu runs every registered completion provider — it executes in-process, so there is no shell to block. + ## Customizing the prompt ```csharp diff --git a/src/content/docs/reference/configuration.mdx b/src/content/docs/reference/configuration.mdx index 126c512..4c27976 100644 --- a/src/content/docs/reference/configuration.mdx +++ b/src/content/docs/reference/configuration.mdx @@ -79,7 +79,7 @@ app.Context("admin", admin => | `.AsResource()` | Registers as an MCP resource (URI derived from route) | | `.AsPrompt()` | Registers as an MCP prompt template | | `.AsMcpAppResource()` | Registers as an MCP Apps UI resource | -| `.WithCompletion(provider)` | Registers Tab completion for this route | +| `.WithCompletion(provider)` | Registers Tab completion for this route. An optional `CompletionProviderScope` argument (default `Interactive`) opts the provider into shell completion (`InteractiveAndShell`) | ## Parameters From 00969095838443e40da20331c92a5024c98181d4 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 15 Jul 2026 13:28:02 -0400 Subject: [PATCH 3/6] docs: global options in help and description overloads - dependency-injection: show the AddGlobalOption overload with aliases, default value, and description; note the Global Options help section and that defaults are intentionally not displayed. - cli-mode: point the help section at global options. Covers yllibed/repl PRs #34 and #41. Co-Authored-By: Claude Fable 5 --- src/content/docs/getting-started/cli-mode.mdx | 2 ++ src/content/docs/reference/dependency-injection.mdx | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/content/docs/getting-started/cli-mode.mdx b/src/content/docs/getting-started/cli-mode.mdx index 4ff1f34..ca453c9 100644 --- a/src/content/docs/getting-started/cli-mode.mdx +++ b/src/content/docs/getting-started/cli-mode.mdx @@ -56,6 +56,8 @@ Commands: client {id} remove ``` +Help also lists a `Global Options:` section covering the built-in flags and any [custom global options](/reference/dependency-injection/#global-options) you registered, with their descriptions. + ## Shell completion Register Repl's completion scripts to get tab completion in your shell: diff --git a/src/content/docs/reference/dependency-injection.mdx b/src/content/docs/reference/dependency-injection.mdx index 8f2c34e..aeaffc9 100644 --- a/src/content/docs/reference/dependency-injection.mdx +++ b/src/content/docs/reference/dependency-injection.mdx @@ -99,11 +99,17 @@ Global options are flags available on every command invocation, parsed before th ```csharp app.Options(o => { - o.Parsing.AddGlobalOption("tenant"); o.Parsing.AddGlobalOption("verbose"); + + // With aliases, default value, and a help description + o.Parsing.AddGlobalOption( + "tenant", aliases: ["t"], defaultValue: null, + description: "Tenant to operate on."); }); ``` +Custom global options appear in `--help` under the `Global Options:` section, with their description (or `Custom global option.` when none was given). Default values are intentionally not displayed in help. + Access them in DI factory registrations: ```csharp From baeb70f6ab6f52aed07f13a979b15ac03863127d Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 15 Jul 2026 13:28:35 -0400 Subject: [PATCH 4/6] docs: MCP prompt argument requiredness and plain-text output Covers yllibed/repl PRs #48 and #49. Co-Authored-By: Claude Fable 5 --- src/content/docs/reference/mcp-concepts.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/docs/reference/mcp-concepts.mdx b/src/content/docs/reference/mcp-concepts.mdx index 3187508..4b4e2da 100644 --- a/src/content/docs/reference/mcp-concepts.mdx +++ b/src/content/docs/reference/mcp-concepts.mdx @@ -138,6 +138,8 @@ app.Map("prompts summarize {id:int}", (int id, IContactStore store) => .WithDescription("Generate a summary prompt for a contact."); ``` +Non-optional route arguments are advertised as `required` in `prompts/list`, matching the validation `prompts/get` applies. Handlers that return a plain `string` surface it as the prompt's text — not as a quoted JSON string literal. + --- ## MCP Apps From 5c61ddcd253b6d4b32a2e9fa3b19f48f44d02f33 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 15 Jul 2026 13:31:25 -0400 Subject: [PATCH 5/6] docs: Spectre terminal detection follows the host ANSI gate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - customization: replace the generic 'Spectre detects automatically' claim with the actual behavior — host detection gates colors, tiered Unicode box-drawing fallback, CI enrichers disabled, and the SpectreTerminalDetection.CurrentBoxDrawingSupport diagnostic; drop a duplicated sentence. - terminal-integration: true-color is requested only when the host gate allows ANSI. Completes the passages deliberately deferred until yllibed/repl#47 merged (now in v0.11.0-dev.124+). Co-Authored-By: Claude Fable 5 --- src/content/docs/reference/customization.mdx | 10 +++++++--- src/content/docs/reference/terminal-integration.mdx | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/content/docs/reference/customization.mdx b/src/content/docs/reference/customization.mdx index 2eafbe5..bcb8e22 100644 --- a/src/content/docs/reference/customization.mdx +++ b/src/content/docs/reference/customization.mdx @@ -57,8 +57,6 @@ See [Result-Flow Paging](/reference/result-flow-paging/) for the full source pag ## ANSI capability levels -Repl detects the terminal's color capability at startup and chooses rendering accordingly. - Repl detects the terminal's color capability at startup and chooses rendering accordingly. Detected capability tiers (informational): | Detected tier | Rendering | @@ -226,7 +224,13 @@ return new Panel(new Markup(content)) ### Detecting Spectre capability -Spectre.Console detects terminal capabilities automatically. On terminals without ANSI support, all output degrades gracefully to plain text — no code changes needed. +Spectre rendering follows the same [ANSI detection chain](#ansi-capability-levels) as the rest of the framework — no configuration required: + +- **Colors** are emitted only when the host detection allows ANSI; otherwise the color system degrades to `NoColors` and output stays plain text. +- **Unicode box-drawing** degrades per output sink: full Unicode borders when the sink's encoding carries them, Spectre's square ASCII-safe fallback on a legacy OEM codepage, and ASCII transliteration (`+`, `-`, `|`) when no box glyph survives (redirected consoles, CI logs, pipes). The active verdict is exposed as `SpectreTerminalDetection.CurrentBoxDrawingSupport` for diagnostics. +- **CI logs are plain by default** — Spectre's built-in CI enrichers are disabled so they cannot override the host detection. Set `CLICOLOR_FORCE=1` in the workflow to restore colored logs. + +Outside a Repl container (bare `AddSpectreConsole()` without `UseSpectreConsole()`), the profile falls back to Spectre's own detection. --- diff --git a/src/content/docs/reference/terminal-integration.mdx b/src/content/docs/reference/terminal-integration.mdx index a98ae08..7092c34 100644 --- a/src/content/docs/reference/terminal-integration.mdx +++ b/src/content/docs/reference/terminal-integration.mdx @@ -33,7 +33,7 @@ ANSI escape sequences are enabled or disabled based on a precedence chain: | Redirected output | `Console.IsOutputRedirected` disables ANSI | | `TERM=dumb` | Disables ANSI | -When ANSI is enabled, the default renderer uses **256-color** SGR styling (`38;5;N`). Add `Repl.Spectre` for 24-bit color (`38;2;r;g;b`) and richer rendering — Spectre.Console always requests true-color when ANSI is on. +When ANSI is enabled, the default renderer uses **256-color** SGR styling (`38;5;N`). Add `Repl.Spectre` for 24-bit color (`38;2;r;g;b`) and richer rendering — Spectre honors the same detection chain, requesting true-color when the host allows ANSI and degrading to plain text when it doesn't. --- From 6be34f59dbf91b3ea226c8fb54725ee0b23260ce Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Wed, 15 Jul 2026 13:46:02 -0400 Subject: [PATCH 6/6] docs: address PR #3 review feedback - configuration: show the real WithCompletion overload shape (targetName, provider[, scope]) instead of a non-existent .WithCompletion(provider) form. - terminal-integration: add ShellIntegrationMarks and the vscode identity to the capability classifier table; note the OSC 633 dialect selection and ConEmu's deliberate exclusion. Co-Authored-By: Claude Fable 5 --- src/content/docs/reference/configuration.mdx | 2 +- .../docs/reference/terminal-integration.mdx | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/content/docs/reference/configuration.mdx b/src/content/docs/reference/configuration.mdx index 4c27976..f8b9bd3 100644 --- a/src/content/docs/reference/configuration.mdx +++ b/src/content/docs/reference/configuration.mdx @@ -79,7 +79,7 @@ app.Context("admin", admin => | `.AsResource()` | Registers as an MCP resource (URI derived from route) | | `.AsPrompt()` | Registers as an MCP prompt template | | `.AsMcpAppResource()` | Registers as an MCP Apps UI resource | -| `.WithCompletion(provider)` | Registers Tab completion for this route. An optional `CompletionProviderScope` argument (default `Interactive`) opts the provider into shell completion (`InteractiveAndShell`) | +| `.WithCompletion(targetName, provider[, scope])` | Registers Tab completion for the named parameter or option. The optional `CompletionProviderScope` (default `Interactive`) opts the provider into shell completion (`InteractiveAndShell`) | ## Parameters diff --git a/src/content/docs/reference/terminal-integration.mdx b/src/content/docs/reference/terminal-integration.mdx index 7092c34..45b2c6e 100644 --- a/src/content/docs/reference/terminal-integration.mdx +++ b/src/content/docs/reference/terminal-integration.mdx @@ -212,20 +212,23 @@ When a session connects, Repl classifies its terminal identity to determine whic The classifier maps substrings of the identity string to capability flags: -| Terminal identity contains | `Ansi` | `ProgressReporting` | `VtInput` | `ResizeReporting` | -|---|---|---|---|---| -| `windows terminal` | ✓ | ✓ | ✓ | ✓ | -| `wezterm` | ✓ | ✓ | ✓ | ✓ | -| `iterm` | ✓ | ✓ | ✓ | ✓ | -| `ghostty` | ✓ | ✓ | ✓ | ✓ | -| `conemu` | ✓ | ✓ | ✓ | ✓ | -| `xterm`, `vt`, `ansi` | ✓ | | ✓ | ✓ | -| `alacritty`, `rxvt`, `konsole`, `gnome`, `linux` | ✓ | | ✓ | ✓ | -| `screen`, `tmux` | ✓ | | ✓ | ✓ | -| `dumb` | | | | | +| Terminal identity contains | `Ansi` | `ProgressReporting` | `ShellIntegrationMarks` | `VtInput` | `ResizeReporting` | +|---|---|---|---|---|---| +| `windows terminal` | ✓ | ✓ | ✓ | ✓ | ✓ | +| `wezterm` | ✓ | ✓ | ✓ | ✓ | ✓ | +| `iterm` | ✓ | ✓ | ✓ | ✓ | ✓ | +| `ghostty` | ✓ | ✓ | ✓ | ✓ | ✓ | +| `conemu` | ✓ | ✓ | | ✓ | ✓ | +| `vscode` | ✓ | | ✓ | ✓ | ✓ | +| `xterm`, `vt`, `ansi` | ✓ | | | ✓ | ✓ | +| `alacritty`, `rxvt`, `konsole`, `gnome`, `linux` | ✓ | | | ✓ | ✓ | +| `screen`, `tmux` | ✓ | | | ✓ | ✓ | +| `dumb` | | | | | | Matching is case-insensitive and substring-based — `xterm-256color` matches `xterm`. +`ShellIntegrationMarks` is what [Auto mode](#modes) checks for hosted sessions. A `vscode` identity additionally selects the OSC 633 dialect. ConEmu deliberately lacks the flag: it renders OSC 9;4 progress but not FinalTerm/VS Code prompt marks. + `VtInput` enables VT keyboard sequence decoding. `ResizeReporting` enables live terminal resize events. Omitting either flag in a override will silently suppress that behavior. For local sessions (no identity string), terminal detection falls back to environment variables: `WT_SESSION`, `ConEmuANSI` (any case — `on`, `On`, `ON` all match), and `TERM_PROGRAM` are checked for OSC 9;4 gating.