diff --git a/blog/2026-10-23-nushell_v0_116_0.md b/blog/2026-10-23-nushell_v0_116_0.md
new file mode 100644
index 00000000000..9d4402e2f25
--- /dev/null
+++ b/blog/2026-10-23-nushell_v0_116_0.md
@@ -0,0 +1,1221 @@
+---
+title: Nushell 0.116.0
+author: The Nu Authors
+author_site: https://www.nushell.sh/blog
+author_image: https://www.nushell.sh/blog/images/nu_logo.png
+excerpt: Today, we're releasing version 0.116.0 of Nu. This release brings a major custom completion rework, new `tui` commands for building terminal interfaces, interactive debugging, more tutor lessons, and a faster shell.
+---
+
+# Nushell 0.116.0
+
+Today, we're releasing version 0.116.0 of Nu. This release brings a major custom completion rework, new `tui` commands for building terminal interfaces, interactive debugging, more tutor lessons, and a faster shell.
+
+# In memory of Yash
+
+
+"It is with profound grief
+and deep love
+that the family of
+Yash Thakur
+announces his passing on
+April 2, 2026."
+
+
+The Nushell team is deeply saddened by Yash's passing.
+
+We found out about his passing recently and wanted to acknowledge his dedication and contributions to our project, as well as the friendship he shared with the Nushell community. Our condolences go out to his friends and family.
+
+Yash started working on Nushell at the young age of 19 in September 2023.
+
+He quickly learned the project and, in a short time, became a valuable contributor to the inner workings of Reedline, the parser, completions, and other components. At the time of his passing, he was also helping develop a new parser for Nushell.
+
+Please consider reading the beautiful obituary written for Yash to learn more about his life, passions, interests, and amazing spirit.
+
+- [Yash Santosh Thakur Obituary](https://www.goinghomecares.com/obituaries/Yash-Santosh-Thakur?obId=48028771)
+
+# Where to get it
+
+Nu 0.116.0 is available as [pre-built binaries](https://github.com/nushell/nushell/releases/tag/0.116.0) or from [crates.io](https://crates.io/crates/nu). If you have Rust installed you can install it using `cargo install nu`.
+
+As part of this release, we also publish a set of optional [plugins](https://www.nushell.sh/book/plugins.html) you can install and use with Nushell.
+
+# Table of contents
+
+
+
+# Highlights and themes of this release
+
+## I'm too lazy to type, lemme press tab
+
+Pressing Tab is easy. Making everything behind it agree on how completions work took a bit more effort. Thanks to [@philocalyst](https://github.com/philocalyst), custom completions now share one input and output model across parameter completers, command-wide completers, external completers, and menu sources. Completers can ask for the token, the completion location, or the whole buffer, and combine their suggestions with other completion sources.
+
+::: warning Breaking change
+Existing custom completers and menu sources may need updating. See the examples and migration table in [unified custom completions](#unified-custom-completions).
+:::
+
+There are plenty of smaller improvements around that big rework, too. Completers can now [see which command you are completing](#completion-input-now-exposes-the-command-being-completed), and external completers [receive expanded aliases](#external-completers-now-receive-expanded-alias-commands-and-show-warnings-after-menus-close). Sourced menus [refresh properly after partial completion](#sourced-menus-now-refresh-correctly-after-partial-completion), warnings wait until the menu closes, and you can opt into [keeping completion and history menus open while editing](#env-config-completions-persistent-menus-keeps-completion-and-history-menus-open-while-editing). Less fighting the menu, more pressing Tab.
+
+## Teach me things
+
+Nushell's interactive `tutor` has more lessons for you. Thanks to [@nos1dot618](https://github.com/nos1dot618), you can now learn about [command-history shortcuts and `$env`](#the-interactive-tutor-now-teaches-command-history-shortcuts-and-the-env-variable), write your own [custom commands and work with pipeline input](#the-interactive-tutor-now-covers-custom-commands-and-pipeline-input), and get to grips with [`if`, `match`, and `where`](#the-interactive-tutor-now-teaches-if-match-and-where).
+
+If you have been meaning to move beyond the commands you already know, this is a good excuse. Run `tutor` and try a lesson right there in your shell.
+
+## Build your TUI straight in Nushell
+
+Ever wanted your script to have a little interface? Thanks to [@fdncred](https://github.com/fdncred), the new `tui` commands let you build interactive terminal interfaces straight from Nushell. Put together tables, textboxes, menus, and more, then get the user's selections and entered values back as a record.
+
+You probably won't replace your entire Ratatui application this afternoon, but a picker or a small form no longer needs a separate Rust project. You can even open it as a floating dialog, and your shell comes back intact when you quit. Take a look at the commands and examples [here](#build-interactive-terminal-interfaces-with-tui), then head over to the [original PR](https://github.com/nushell/nushell/pull/19025) for more. Even this changelog cannot easily cover everything these commands can do.
+
+## Interactive debugging!
+
+That script is doing something strange again. Time to set a breakpoint. Thanks to [@rvhelden](https://github.com/rvhelden), Nushell now has a Debug Adapter Protocol server, started with `nu --dap`, so you can debug your scripts from an editor that supports DAP.
+
+Set breakpoints, step through pipelines, inspect variables, and evaluate watch expressions. You can even step backward through a recorded timeline when you realize you just stepped past the interesting bit. A lot of work behind a small flag. More details are [here](#nu-dap-starts-a-debug-adapter-protocol-server-for-nushell-scripts).
+
+## Make Nushell faster
+
+There is less waiting around this release, too. [Typing and completing `use` in the REPL](#faster-typing-of-use-in-the-repl) does less work, and [large configs load faster](#nu-startup-time-is-now-accurate-and-nushell-starts-faster-with-large-configs), along with the plugin registry. `gstat` also finds the nearest tag faster in large repositories.
+
+`$nu.startup-time` now measures all the way to the first prompt being ready, so you get a more honest account of where that time went. There is also [faster parsing and less work when styling values](#other-performance-improvements), and the [repeated `source` slowdown introduced in 0.115](#faster-repeated-source-of-the-same-file) is fixed. Thanks to everyone making the shell a little quicker, one less bit of unnecessary work at a time.
+
+
+
+
+# Changes
+
+## Breaking changes
+
+### Unified custom completions
+
+Custom completions now use one shared input and output model across parameter completers, command-wide completers, external completers, and menu sources. This makes completion behavior more consistent, but it means existing custom completers and menu sources may need to be updated.
+
+Previously, different completion entry points received different arguments. Parameter completers received something like `[context, offset]`, command-wide completers received `[spans]`, external completers commonly received `{|spans| ...}`, and menu sources received `{|buffer, position| ...}`.
+
+Completers now declare which completion inputs they want by naming their positional parameters. The recognized names are `token`, `place`, and `buffer`, and they can be declared in any order.
+
+```nushell
+def complete-branch [token: record] {
+ git branch --format '%(refname:short)' | lines | where $it =~ $token.text
+}
+
+def complete-from-place [place: record] {
+ if $place.kind == "flag-value" and $place.flag == "profile" {
+ [debug release]
+ }
+}
+
+def complete-from-buffer [buffer: string] {
+ $buffer | split row " "
+}
+```
+
+`token` describes the token at the cursor, with fields like `text`, `kind`, and `span`. `place` describes the resolved completion site and replacement range, including fields like `cursor`, `target`, `kind`, `flag`, `index`, and `shape` when applicable. `buffer` is the exact command line from the beginning of the line through the cursor, including text before pipes, inside closures, and after separators.
+
+Use `buffer` instead of calling `commandline` from inside a completer. `buffer` is always the line currently being completed; `commandline` can be empty in some editor states, such as after `;`.
+
+Menu sources use this same input model now. A source that used to look like this:
+
+```nushell
+source: {|buffer, position|
+ $buffer | str substring ..<$position | split row " " | last
+}
+```
+
+should usually become either:
+
+```nushell
+source: {|token| $token.text }
+```
+
+or, if it really needs the whole line:
+
+```nushell
+source: {|buffer| $buffer }
+```
+
+External completers also need to migrate from the old spans-style input to the new named inputs. For example, a whole-line external completer should declare `buffer`:
+
+```nushell
+$env.config.completions.external.completer = {|buffer|
+ let words = $buffer | split row " "
+ carapace ($words | first) nushell ...$words | from json
+}
+```
+
+If a completer declares an unrecognized positional name, Nushell passes `nothing` for that parameter and writes a diagnostic to the completion log.
+
+Custom completer output is also handled more consistently. A completer can now return `null` to decline and let another completion source answer, a string or list of strings, suggestion records, or an envelope record with `completions`, `options`, and `fallback`.
+
+```nushell
+def complete-preset [token: record] {
+ {
+ completions: [
+ {value: main, description: "default branch"}
+ {value: release, description: "release branch"}
+ ]
+ options: {
+ filter: true
+ completion_algorithm: "substring"
+ match_description: true
+ }
+ fallback: true
+ }
+}
+```
+
+`fallback: true` keeps the custom results and continues to the next completion source, so custom completions can appear beside built-in file completion or command-wide completions. Parameter completers are filtered by default; command-wide and external completers are not, because they usually do their own filtering. Set `options.filter` explicitly if you need the other behavior.
+
+The old global `background-completions` option has been removed. Completers normally run on a background worker. If a completer needs to own the terminal, such as one that launches `fzf` or `input list`, mark the completer command with `@interactive`:
+
+```nushell
+@interactive
+def pick-file [token: record] {
+ ls | get name | to text | ^fzf --query $token.text | lines
+}
+
+def open-file [path: string@pick-file] {
+ open $path
+}
+```
+
+When completing `open-file `, `pick-file` runs inline on the line-editor thread with stdin and the terminal available. This blocks the editor while the picker is open, then returns the selected values as completion suggestions. Calling an `@interactive` completer directly is not the intended test path, because the completion engine supplies its inputs.
+
+External completers are closures and cannot carry `@interactive` themselves. To make an external completer interactive, have the closure call an `@interactive` command:
+
+```nushell
+@interactive
+def carapace-fzf [buffer: string] {
+ let words = $buffer | split row " "
+ carapace ($words | first) nushell ...$words | from json | ^fzf | lines
+}
+
+$env.config.completions.external.completer = {|buffer|
+ carapace-fzf $buffer
+}
+```
+
+`commandline complete` gained tools for developing completers. `commandline complete --input` returns the `{token, place, buffer}` record a completer would receive without running the completer. `commandline complete --detailed` returns suggestions in the custom-completer output format. `commandline complete --type directory|path|glob|command|variable|env-var` runs one built-in completion source, which is useful when composing Nushell's built-in completions with custom ones. `--input` cannot be combined with `--detailed` or `--type`.
+
+Some completion behavior changed as part of this unification:
+
+- Parameter completers that fail now return no suggestions instead of unexpectedly falling back to the working directory.
+- Command-wide and external completers can return `null` to decline, allowing file completion or another source to answer.
+- Completion state is resolved at the cursor more accurately, including nested closures, aliases, multi-word command heads, flag values, cell paths, and empty argument slots.
+- Aliases resolve through to their completion command, including whether that command is interactive.
+- Malformed suggestions, styles, spans, or options are reported in the completion log without discarding unrelated valid suggestions.
+
+Common migrations:
+
+| Previous form | New form |
+| :----------------------------------- | :------------------------------------------------------- | ------------------------ | -------------------------------------- | -------------- | ---------- | ------------- | ------------- | -------------- | ------ |
+| `def comp [input pos] { ... }` | `def comp [token: record] { $token.text | ... }` |
+| `def comp [spans] { ... }` | `def comp [buffer: string] { $buffer | split row " " | ... }` when whole-line input is needed |
+| `{ | spans | ...}` external completer | `{ | buffer: string | ... }` |
+| `{ | buffer position | ...}` menu source | `{ | token: record | ... }`, `{ | place: record | ... }`, or `{ | buffer: string | ... }` |
+| Global background-completion opt-out | `@interactive` on the terminal-owning completion command |
+
+### Other breaking changes
+
+- Replaced `to yaml`/`to yml`'s `--compact-list-indent` flag with `--list-indent` flag which takes either `compact` or `indented`. ([#19005](https://github.com/nushell/nushell/pull/19005))
+
+## Additions
+
+### Named flags: null can omit or pass through based on type
+
+When a named flag is given `null`, Nushell now:
+
+- **Omits** the flag if its type does not accept `nothing` (e.g. `--x: int`, `--preserve: list`), so defaults and “flag not passed” behavior work—especially useful when shadowing builtins with `%cp` / `%ls` and writing `--flag=$maybe_null`
+- **Passes `null` through** if the type accepts `nothing` (e.g. `--x: any`, `--x: oneof`), so callers can still express an explicit null when they opt into that in the signature
+
+```nushell
+def f [--x: oneof = 5] { $x }
+f # 5
+f --x=null # null
+
+def g [--x: int = 5] { $x }
+g --x=(null) # 5 (omitted → default) note: in this example null is wrapped in parens because this syntax would fail with `g --x=null` as you're typing due to parse checking.
+```
+
+### Record spread into named flags
+
+Internal and custom commands accept spreading a record as named flags:
+
+```nushell
+def wrap [--preserve: list, --recursive, ...rest] {
+ %cp ...{ preserve: $preserve, recursive: $recursive } ...$rest
+}
+
+let flags = {preserve: [mode], recursive: true}
+wrap ...$flags src dest
+```
+
+Null fields follow the same type rule as named flags above. For switch fields, `true` sets the flag, while `false` or `null` omits it. Field values are type-checked against the flag signature, and unknown flag names in the record cause a runtime error. Spreading a **list** into a command with no `...rest` produces a clear error, since lists are not treated as named flags.
+
+### New Polars commands can create date and datetime ranges
+
+Implemented commands for creating date and datetime ranges:
+
+| Command | Description |
+| :----------------------- | :---------------------------------- |
+| `polars date-range` | Create a date range expression. |
+| `polars date-ranges` | Create a column of date ranges. |
+| `polars datetime-range` | Create a datetime range expression. |
+| `polars datetime-ranges` | Create a column of datetime ranges. |
+
+### The interactive tutor now teaches command-history shortcuts and the `$env` variable
+
+Added a `tutor` shortcuts tutorial covering command history shortcuts.
+
+```ansi :no-line-numbers
+[96m> [1m[36mtutor[22m[39m [32mshortcut
+[39m
+You can use shortcuts to quickly insert text from command history into the
+input buffer.
+
+You can use [36m!![39m to insert the last command you entered into the input buffer.
+[36m
+!!
+[39m
+After pressing Enter, [36m!![39m is expanded into the previous command in the input
+buffer. The expanded command is not executed until you press Enter again.
+
+You can also use [36m!![39m as part of a larger command.
+[1m[36m
+tutor[22m[39m [32mshortcut[36m
+!![39m [1m[35m|[22m[39m [1m[36mfind[22m[39m [32m"shortcut"
+[39m
+The above expands [36m!![39m into the previous command while keeping the rest of the
+text in the input buffer.
+
+You can use [36m!$[39m to insert the last spatially delimited argument from the
+previous command into the input buffer.
+[1m[36m
+echo[22m[39m [32mhello[39m [32mworld[1m[36m
+echo[22m[39m [32m!$
+[39m
+After pressing Enter, [36m!$[39m is expanded to [36mworld[39m in the input buffer. The
+resulting command is not executed until you press Enter again.
+
+You can use [36m![39m to insert a command from the command history into the input
+buffer. The index corresponds to the command's index in the history.
+[1m[36m
+history[22m
+!5
+[39m
+After pressing Enter, [36m!5[39m is expanded to the command with history index [1m[35m5[22m[39m in
+the input buffer.
+
+You can use [36m!-[39m to insert a command from a number of entries back in
+the history into the input buffer.
+[36m
+!-5
+[39m
+After pressing Enter, [36m!-5[39m is expanded to the command from five entries back in
+the history.
+[0m
+```
+
+The variable tutorial now also documents the $env built-in variable.
+
+```ansi :no-line-numbers
+[96m> [1m[36mtutor[22m[39m [32mvariable
+[39m
+Variables are an important way to store values to be used later. To create a
+variable, you can use the [1m[36mlet[22m[39m keyword. The [1m[36mlet[22m[39m command will create a
+variable and then assign it a value in one step.
+[1m[36m
+let[22m[39m [35mx[39m = [1m[35m3
+[22m[39m
+Once created, we can refer to this variable by name.
+[1m[41m
+$x
+[22m[49m
+Nushell also comes with built-in variables. The [35m$nu[39m variable is a reserved
+variable that contains a lot of information about the currently running
+instance of Nushell. The [35m$env[39m variable contains the environment variables
+available to the current Nushell process. The [1m[41m$it[22m[49m variable is the name given
+to row-condition closure parameters if you don't specify one. And [35m$in[39m is the
+variable that allows you to work with all of the data coming in from the
+pipeline in one place.
+[0m
+```
+
+### The interactive tutor now covers custom commands and pipeline input
+
+Added new `tutor` tutorials for defining custom commands and working with pipeline input.
+
+```ansi :no-line-numbers
+[96m> [1m[36mtutor[22m[39m [32mcustom-command
+[39m
+Custom commands allow you to create your own commands in Nushell. You can
+define a custom command using the [1m[36mdef[22m[39m keyword.
+
+For example, this defines a command called [36mgreet[39m:
+[1m[36m
+def[22m[39m [32mgreet[39m [1m[32m[][22m[39m [1m[32m{
+ [36mprint[22m[39m [32m"Hello!"[1m
+}
+
+[22m[39m
+You can then run it just like any other command:
+[36m
+greet
+
+[39m
+Custom commands can also accept arguments. You define the arguments between
+the square brackets:
+[1m[36m
+def[22m[39m [32mgreet[39m [1m[32m[name][22m[39m [1m[32m{
+ [36mprint[22m[39m [1m[36m$"[22m[32mHello, [1m[34m([22m[35m$name[1m[34m)[22m[32m![1m[36m"[32m
+}
+
+[22m[39m
+Now you can pass a name to the command:
+[36m
+greet[39m [1m[32m"Nushell"
+
+[22m[39m
+You can give arguments a type to make the expected input clearer:
+[1m[36m
+def[22m[39m [32madd[39m [1m[32m[a: int, b: int][22m[39m [1m[32m{
+ [22m[35m$a[39m [33m+[39m [35m$b[1m[32m
+}
+
+[22m[39m
+You can also provide default values for arguments:
+[1m[36m
+def[22m[39m [32mgreet[39m [1m[32m[name = "world"][22m[39m [1m[32m{
+ [36mprint[22m[39m [1m[36m$"[22m[32mHello, [1m[34m([22m[35m$name[1m[34m)[22m[32m![1m[36m"[32m
+}
+
+[22m[39m
+You can learn more about using pipeline input with custom commands by running:
+[1m[36m
+tutor[22m[39m [32mpipeline-input
+
+[39m
+You can learn more about custom commands and see additional examples by
+running:
+[1m[36m
+help[22m[39m [32mdef
+
+[96m
+> [1m[36mtutor[22m[39m [32mpipeline-input
+[39m
+Custom commands can receive values from the pipeline. This allows you to
+create commands that work naturally with other Nushell commands.
+
+For example, this custom command takes pipeline input and doubles each value:
+[1m[36m
+def[22m[39m [32mdouble[39m [1m[32m[][22m[39m [1m[32m{
+ [36meach[22m[39m [1m[32m{ |x| [22m[35m$x[39m [33m*[39m [1m[35m2[32m }
+}
+
+[22m[39m
+You can use it as part of a pipeline:
+[1m[36m
+[[35m1[36m [35m2[36m [35m3[36m][22m[39m [1m[35m|[22m[39m [36mdouble
+
+[39m
+Custom commands can also access all of their pipeline input through [35m$in[39m:
+[1m[36m
+def[22m[39m [32mtotal[39m [1m[32m[][22m[39m [1m[34m{
+ [22m[35m$in[39m [1m[35m|[22m[39m [1m[36mmath sum[34m
+}
+
+[22m[39m
+This allows the custom command to work with the entire value coming through
+the pipeline:
+[1m[36m
+[[35m1[36m [35m2[36m [35m3[36m [35m4[36m][22m[39m [1m[35m|[22m[39m [36mtotal
+
+[39m
+You can learn more about closures, which are commonly used when processing
+pipeline data, by running:
+[1m[36m
+tutor[22m[39m [32mclosures
+[0m
+```
+
+### `$env.config.completions.persistent_menus` keeps completion and history menus open while editing
+
+Added `$env.config.completions.persistent_menus`. When set to `true`, an active completion or history menu stays open while you edit: erasing characters (or emptying the commandline) refilters the menu instead of closing it. Default `false` keeps the old behavior.
+
+```nushell
+$env.config.completions.persistent_menus = true
+```
+
+### `view source --dependencies` can now include custom command dependencies
+
+Added `--dependencies` (`-d`) to `view source`. It appends the source of every custom command the target calls, transitively — including commands private to a module, which cannot be viewed any other way — and prepends every constant those bodies read, with the value the engine holds:
+
+```ansi :no-line-numbers
+[96m> [1m[36mmodule[22m[39m [32mm[39m [1m[4m[34m{[24m
+ [36mconst[22m[39m [35mLIMIT[39m = [1m[35m42[22m[39m
+ [1m[36mdef[22m[39m [32mhelper[39m [1m[32m[][22m[39m [1m[32m{ [22m[35m$LIMIT[1m[32m }[22m[39m
+ [1m[36mexport def[22m[39m [32mbar[39m [1m[32m[][22m[39m [1m[32m{ [36mhelper[32m }[4m[34m
+}[22m[24m[96m
+> [1m[36muse[22m[39m [32mm[96m
+> [1m[36mview source[22m[39m [32m"m bar"[39m [1m[34m--dependencies[22m[39m
+const LIMIT = 42
+
+def "m bar" [] { helper }
+
+def helper [] { $LIMIT }[0m
+```
+
+### The interactive tutor now teaches `if`, `match`, and `where`
+
+Added a new `tutor conditional` tutorial for learning conditional logic, pattern matching, and conditional filtering.
+
+```ansi :no-line-numbers
+[96m> [1m[36mtutor[22m[39m [32mconditional
+[39m
+Conditional commands allow you to choose which code to run based on a value or
+condition.
+
+The [1m[41mif[22m[49m command runs a block when its condition is true:
+[1m[36m
+if[22m[39m [1m[35m5[22m[39m [33m>[39m [1m[35m3[22m[39m [1m[34m{
+ [36mprint[22m[39m [32m"5 is greater than 3"[1m[34m
+}
+
+[22m[39m
+You can use [36melse[39m to run a different block when the condition is false:
+[1m[36m
+let[22m[39m [35mage[39m = [1m[35m20
+[36m
+if[22m[39m [35m$age[39m [33m>=[39m [1m[35m18[22m[39m [1m[34m{
+ [22m[32m"adult"[1m[34m
+}[22m[39m [1m[36melse[22m[39m [1m[34m{
+ [22m[32m"minor"[1m[34m
+}
+
+[22m[39m
+You can also chain multiple conditions with [36melse[39m [1m[32mif[22m[39m:
+[1m[36m
+let[22m[39m [35mscore[39m = [1m[35m75
+[36m
+if[22m[39m [35m$score[39m [33m>=[39m [1m[35m90[22m[39m [1m[34m{
+ [22m[32m"A"[1m[34m
+}[22m[39m [1m[36melse[22m[39m [1m[36mif[22m[39m [35m$score[39m [33m>=[39m [1m[35m80[22m[39m [1m[34m{
+ [22m[32m"B"[1m[34m
+}[22m[39m [1m[36melse[22m[39m [1m[36mif[22m[39m [35m$score[39m [33m>=[39m [1m[35m70[22m[39m [1m[34m{
+ [22m[32m"C"[1m[34m
+}[22m[39m [1m[36melse[22m[39m [1m[34m{
+ [22m[32m"F"[1m[34m
+}
+
+[22m[39m
+The [1m[41mif[22m[49m command returns a nushell value, so it can be store in a variable or
+use in a pipeline:
+[1m[36m
+let[22m[39m [35mresult[39m = [1m[36mif[22m[39m [1m[35m10[22m[39m [33m>[39m [1m[35m5[22m[39m [1m[34m{ [22m[32m"yes"[1m[34m }[22m[39m [1m[36melse[22m[39m [1m[34m{ [22m[32m"no"[1m[34m }[22m[35m
+$result
+
+[39m
+When you have several possible values to match, the [1m[41mmatch[22m[49m command can be more
+convenient. It checks a value against several patterns:
+[1m[36m
+let[22m[39m [35mnumber[39m = [1m[35m2
+[36m
+match[22m[39m [35m$number[39m {
+ [32m1[39m => [32m"one"[39m,
+ [32m2[39m => [32m"two"[39m,
+ [32m3[39m => [32m"three"[39m,
+ [96m_[39m => [32m"something else"[39m
+}
+
+The [36m_[39m pattern acts as a catch-all for anything that did not match an earlier
+branch.
+
+The [1m[41mmatch[22m[49m command can also be used to unpack structured values:
+[1m[36m
+let[22m[39m [35muser[39m = [1m[36m{ [22m[32mname[1m[36m: [22m[32m"Alice"[1m[36m, [22m[32madmin[1m[36m: [22m[96mtrue[1m[36m }
+
+match[22m[39m [35m$user[39m {
+ [32m{ admin: true }[39m => [32m"administrator"[39m,
+ [32m{ admin: false }[39m => [32m"regular user"[39m,
+ [96m_[39m => [32m"unknown"[39m
+}
+
+
+Conditions can also be used to filter values in a pipeline with the [1m[36mwhere[22m[39m
+command:
+[1m[36m
+[[35m1[36m [35m2[36m [35m3[36m [35m4[36m [35m5[36m][22m[39m [1m[35m|[22m[39m [1m[36mwhere[22m[39m [35m$it[39m [33m>[39m [1m[35m2
+[22m[39m
+This keeps only the values for which the condition is true:
+[36m
+╭───┬───╮
+│[39m [1m[32m0[22m[39m [1m[32m│[22m[39m [1m[32m3[22m[39m [1m[32m│[22m[36m
+│[39m [1m[32m1[22m[39m [1m[32m│[22m[39m [1m[32m4[22m[39m [1m[32m│[22m[36m
+│[39m [1m[32m2[22m[39m [1m[32m│[22m[39m [1m[32m5[22m[39m [1m[32m│[22m[36m
+╰───┴───╯
+
+[39m
+For tables, the [1m[36mwhere[22m[39m command is particularly useful for selecting rows:
+[1m[36m
+ls[22m[39m [1m[35m|[22m[39m [1m[36mwhere[22m[39m [32msize[39m [33m>[39m [1m[35m1[22m[32mkb
+
+[39m
+You can learn more about filtering pipelines with:
+[1m[36m
+help[22m[39m [32mwhere
+
+[39m
+You can learn more about blocks, which are used by the [1m[41mif[22m[49m command and other
+control flow commands, by running:
+[1m[36m
+tutor[22m[39m [32mblocks
+
+[39m
+You can also see more details about the [1m[41mif[22m[49m and [1m[41mmatch[22m[49m commands with:
+[1m[36m
+help[22m[39m [32mif[1m[36m
+help[22m[39m [32mmatch
+[0m
+```
+
+### `std/log` commands can now attach structured context fields
+
+Added a `--context` flag to all std/log emitters
+
+Example:
+
+```ansi :no-line-numbers
+[96m> [1m[36muse[22m[39m [32mstd/log[96m
+> [1m[36mlog info[22m[39m [32m'hello'[39m [1m[34m--context[22m[39m [1m[4m[36m{[22m[24m[32muser[1m[36m: [22m[32mAna[1m[4m[36m}[22m[24m[39m
+2026-09-26T18:56:49,484|INF|hello user="Ana"[0m
+```
+
+### Build interactive terminal interfaces with `tui`
+
+#### Summary
+
+This release adds a `tui` command family so a Nushell user can build an interactive TUI or popup from a pipeline, without writing Rust. The commands live in a new `nu-tui` crate; the ratatui style conversions are shared with `explore`.
+
+Interactive `tui run` always uses the alternate screen, so the shell comes back intact when you quit. `--dialog` is the same session in a smaller floating window. `tui debug` paints the same UI to a string and reports how it was laid out, for scripts and tests.
+
+`tui run` returns one record, `{action, focused, selected, page, values, rows, live}`, where `values` holds every widget's state by id. Colors come from a new `$env.config.tui` section (documented in `config nu --doc`).
+
+This release also fixes a related memory leak: `nu-utils` now reads the OS locale once per process. `sys_locale` goes through CoreFoundation on macOS and its autoreleased objects were never collected on a plain Rust thread, so any loop that formats filesizes (the TUI redraws per frame) grew memory without bound.
+
+#### Command reference
+
+Every builder takes `--id` and `--focus` (start with that widget focused). Data widgets (table, tree, log, select, progress, label) also take `--data` and `--from`; list widgets (table, tree, select) also take `--on-select` and `--multi`. The remaining flags are listed.
+
+| Command | Positional | Flags | Role |
+| -------------- | ------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
+| `tui` | | | Help listing subcommands |
+| `tui label` | text or closure | `--title`, `--status` | Static text: inline, on the title bar, or on the status bar. A closure follows a row |
+| `tui menu` | `[items]` | | Menu bar with mnemonics, dropdowns, and hook actions |
+| `tui textbox` | | `--placeholder`, `--value` | Editable field |
+| `tui table` | source closure | `--columns`, `--capture-keys`, `--index` | Navigable rows. Scalars show as one `item` column |
+| `tui select` | `[items]` | `--display`, `--index` | Radio list, or checkbox list with `--multi` |
+| `tui button` | label, hook | | Runs a hook, or submits its label. Adjacent buttons share a row |
+| `tui progress` | source closure | `--value`, `--total`, `--label` | Gauge fed by a value, the data, or a source row |
+| `tui log` | source closure | `--max-lines` | Append-only log. Follows the tail of a stream |
+| `tui tree` | source closure | `--walk`, `--column` | Nested records, or a directory walk |
+| `tui search` | | `--placeholder`, `--bind`, `--fuzzy`, `--case-sensitive`, `--columns` | Search box. Filters the lists in its scope |
+| `tui preview` | closure | `--from`, `--max-bytes` | Text for the selected row: a file, or whatever the closure returns |
+| `tui split` | `[children]` | `--vertical`, `--sizes`, `--ratio` | Side-by-side or stacked panes with draggable dividers |
+| `tui box` | title, `[children]` | | A titled, bordered group |
+| `tui tab` | title, `[children]` | | A page in the tab bar |
+| `tui bind` | key, hook | | Run a hook when a key is pressed anywhere |
+| `tui run` | hook | `--dialog`, `--size`, `--refresh`, `--no-mouse` | Event loop |
+| `tui debug` | hook | `--keys`, `--until`, `--size`, `--dialog` | Headless render, key replay, and layout/focus introspection |
+
+#### Layout model
+
+Widgets in the outer pipeline stack top to bottom, one row each. The exception is buttons: adjacent `tui button`s pack onto one row, left to right (§12). `tui split`, `tui box`, and `tui tab` take a list of child widgets and arrange them. Children are built inside parentheses:
+
+```nushell
+ls
+| tui label --title "files"
+| tui split --sizes [60% 1fr] [
+ (tui box "list" [ (tui search --bind /) (tui table --columns [name type size]) ])
+ (tui preview { nu-highlight })
+ ]
+| tui label --status "enter: pick /: filter q: quit"
+| tui run
+```
+
+Chrome, that is `tui label --title`, `tui label --status`, and `tui menu`, goes in the outer pipeline only and stays visible on every page. `tui tab` is also outer-pipeline only. `tui search` can go in either place; its position decides what it filters (§3).
+
+Auto ids are `table-0`, `search-0`, …, numbering widgets of each kind in tree order. When two children both contain a `table-0`, the second becomes `table-1` and a `--from table-0` inside that child follows it. An explicit `--id` is never renumbered; two of the same explicit id is an error. Pass `--id` when another widget needs a stable name; `tui debug` shows the resolved ids.
+
+#### Data flow
+
+Each widget shows the first of these that exists:
+
+1. its own `--data`, or the value piped into it inside a child list (`[(ls | tui table)]`);
+2. what its `--from` source produced (§4);
+3. the nearest ancestor container's data;
+4. the outer pipeline's data.
+
+So one pipeline can feed every list, or each pane can have its own rows:
+
+```nushell
+ls | tui split [ (tui table) (tui tree) ] | tui run # both read ls
+tui split [ (ps | tui table) (ls | tui table) ] | tui run # each has its own
+tui split [ (tui table --data (ps)) (tui table --data (ls)) ] # the same, spelled out
+```
+
+A builder reads a stream for a quarter of a second. A producer that finishes in that time (`ls`, `ps`, `open`) is collected into the widget's data; one that keeps going (`1..`, `tail -f`) stays live and flows on to `tui run` (§9). A child list can only hold collected values, so keep unbounded producers in the outer pipeline.
+
+#### Hook contract
+
+One contract covers every closure that reacts to the user: `tui bind`, menu `action`s, `tui button`, `--on-select`, and the `tui run` closure. The hook receives the state record (the same record `tui run` returns, §Result record) as `$in`, and as its first parameter when it declares one. Its output decides what happens:
+
+| Returns | Effect |
+| --------------------------------- | ----------------------------------------------------------------- |
+| nothing | nothing changes |
+| `{action: submit, selected: ...}` | the TUI closes with that selection |
+| `{action: quit}` | the TUI closes without a selection |
+| anything else | it replaces the shared data list; every widget reading it redraws |
+
+An error goes to the status bar as `error:…` and the TUI stays open.
+
+```nushell
+ls
+| tui table
+| tui bind ctrl+r {|| ls } # reload
+| tui bind s {|state| {action: submit, selected: $state.selected.name} } # submit the name
+| tui run
+```
+
+### `nu --dap` starts a Debug Adapter Protocol server for Nushell scripts
+
+Added a Debug Adapter Protocol server to Nushell. Running `nu --dap` starts a
+DAP server over stdio, so any DAP-capable editor (VS Code, Zed, Neovim, …) can
+debug `.nu` scripts — set breakpoints (including conditional breakpoints and
+logpoints), step through code and pipelines, inspect variables and `$env`,
+evaluate watch expressions, and even step backward through a recorded timeline.
+
+### Completion input now exposes the command being completed
+
+Added `place.command` to completion input records. Custom completers that declare `place` can now read the command being completed as a list of shell words, so external completers can reliably use `$place.command.0` and `...$place.command` even after pipes, semicolons, inside closures, or inside subexpressions.
+
+### Sourced menus now refresh correctly after partial completion
+
+Fixed sourced menus with partial completion enabled so Tab completion refreshes against the updated line after inserting a common prefix. This avoids corrupting the command line or replacing the wrong span, such as `bits r` becoming `bits ror o` instead of `bits ror`.
+
+### Other additions
+
+- Floating point number strings may now be parsed via `into float` if they use a comma as decimal separator. ([#18882](https://github.com/nushell/nushell/pull/18882))
+- `to yaml --non-roundtrip` now also accepts a raw `null` instead of only `"null"` for the null configuration. ([#18851](https://github.com/nushell/nushell/pull/18851))
+- Allow `take until`, `take while`, `skip until`, `skip while`, and `chunk-by` to use row condition syntax alongside closures. ([#18844](https://github.com/nushell/nushell/pull/18844))
+- Include UTC offset in `date list-timezone` output. ([#18922](https://github.com/nushell/nushell/pull/18922))
+- You can now hash a value using the sha512 algorithm using the `hash sha512` built-in. ([#19027](https://github.com/nushell/nushell/pull/19027))
+- Added `mkdir --fail-if-exists `, which errors if the directory already exists instead of silently succeeding. Default `mkdir` behavior is unchanged. ([#19021](https://github.com/nushell/nushell/pull/19021))
+- `save --force` now creates missing parent directories before writing the destination file. ([#19039](https://github.com/nushell/nushell/pull/19039))
+- `update cells` has a new `--recursive` (`-r`) flag. With it, the closure runs on every leaf value inside nested records and lists instead of on the containing cell as a whole. The default behavior is unchanged. ([#19060](https://github.com/nushell/nushell/pull/19060))
+- Added forward slash and backslash to `char`, independent of the underlying operating system. ([#19082](https://github.com/nushell/nushell/pull/19082))
+- Added the `SwitchMode` keybinding event, `{ send: SwitchMode, mode: vi_normal }`, taking the same mode names `mode` takes on a keybinding. A switch into the mode already active reports itself inapplicable, so an `until` list falls through to its next event where it used to stop; `ViChangeMode` and `HelixChangeMode` share that.
+- Added `vi_visual` as a keybinding mode and `$env.config.cursor_shape.vi_visual`, which follows `vi_normal` while left on `inherit`. Bindings for `vi_normal` no longer apply in visual mode.
+
+## Performance
+
+### Faster typing of `use` in the REPL
+
+The REPL no longer parse-time-loads a module just to syntax-highlight it. Typing `use std` or `use std/iter` no longer stalls on the first exact match of `std` (most noticeable in debug builds). Execution is unchanged: the module still loads when you run the line.
+
+Completing `use std/` (and `export use` / `overlay use`) lists virtual standard-library children without walking the current directory. `$NU_LIB_DIRS` is still searched. Completing a real path such as `use ./foo/` is unchanged.
+
+Syntax highlighting also does less work per keystroke: it reuses the last parse of the same line (for example when only the cursor moves) and copies less text while painting.
+
+```nushell
+# These should feel instant to type in the REPL, including debug `cargo run`
+use std
+use std/iter
+use std/assert
+```
+
+### `$nu.startup-time` is now accurate and Nushell starts faster with large configs
+
+#### More accurate startup reporting
+
+`$nu.startup-time` now measures the time until the first prompt is ready, starting at process creation on macOS and Windows, or at `main` on other platforms. This includes config files, plugins, `env_change` and `pre_prompt` hooks, and prompt evaluation. Startup hooks see a provisional value; the final value is available from the first command onward. Scripts also get a startup time instead of `-1ns`.
+
+The banner's "Startup Time" line now appears after the startup hooks, just before the first prompt, so it shows the final value. The welcome message still appears first, with hook output between it and the timing line. Use `banner --no-startup-time` to hide the timing line.
+
+For a closer look, `--log-level perf` reports time spent before `main`, in engine setup, and loading the standard library, followed by a final "startup (process start to first prompt)" line.
+
+#### Faster loading and commands
+
+Command lookups no longer rebuild overlay visibility maps, roughly halving config load time for configs that `use` many modules. Loading the plugin registry is also faster: about 5× for a registry with 20 plugins.
+
+`gstat` finds the nearest tag faster in large repositories—about 4× in the Nushell repo—with unchanged output. When no terminal is attached, `table` and `term size` avoid spawning `tput` and use `COLUMNS`/`LINES`, falling back to 80×24.
+
+### Other performance improvements
+
+- Optimize `style_computer.rs#style_primitive` to use `shallow_get_type()` instead of `get_type()` ([#18975](https://github.com/nushell/nushell/pull/18975))
+- Improved parsing performance: scripts, modules and `source`d files parse about 1.4-1.5x faster, and the REPL's per-keystroke parse benefits accordingly. No change to what is accepted, rejected, or reported. ([#19055](https://github.com/nushell/nushell/pull/19055))
+
+## Other changes
+
+### The MCP HTTP server now listens only on `127.0.0.1` by default
+
+The MCP HTTP server now binds to `127.0.0.1` by default instead of `0.0.0.0`, so it is no longer exposed to other hosts on the network unless explicitly configured.
+
+Added `--mcp-host` for choosing the MCP HTTP bind address. Use `--mcp-host 0.0.0.0` with `--mcp-transport http` if you intentionally want the MCP server to listen on all interfaces.
+
+### Additional changes
+
+- The `each` command's documentation now includes more information on supported input types. ([#18893](https://github.com/nushell/nushell/pull/18893))
+- Refreshing `$env.ENV_CONVERSIONS` now also normalizes `PATH` into its usual list form. The `load-env` help documents how to refresh environment conversions after importing string values. ([#18832](https://github.com/nushell/nushell/pull/18832))
+
+## Bug fixes
+
+### `lines --skip-empty` now works consistently across input types
+
+`lines --skip-empty` now skips empty lines for string and byte stream input, not only list streams.
+
+```ansi :no-line-numbers
+[96m> [32m"foo\n\nbar"[39m [1m[35m|[22m[39m [1m[36mlines[22m[39m [1m[34m--skip-empty[22m[39m
+╭───┬─────╮
+│ [1m[32m0[22m[39m │ foo │
+│ [1m[32m1[22m[39m │ bar │
+╰───┴─────╯[0m
+```
+
+Whitespace-only lines are treated as empty, same as they already were for list streams.
+
+### `format pattern` and `parse` now reject unclosed `{` patterns
+
+`format pattern` already reported a delimiter error for a lone `}`. A pattern that ended with `{` succeeded and dropped the brace. `parse` simple patterns did the same.
+
+Both commands now treat an unescaped `{` without a matching `}` as a delimiter error.
+
+```ansi :no-line-numbers
+[96m> [1m[36m{}[22m[39m [1m[35m|[22m[39m [1m[36mformat pattern[22m[39m [32m'{'[39m
+Error: [31mnu::shell::delimiter_error
+[39m
+ [31m×[39m Delimiter error
+ ╭─[[1m[4m[36mrepl_entry #20:1:6[22m[24m[39m]
+ [2m1[22m │ {} | format pattern '{'
+ · [1m[35m ───────┬──────[22m[39m
+ · [1m[35m╰── there are unmatched curly braces[22m[39m
+ ╰────
+[96m
+> [32m"hello "[39m [1m[35m|[22m[39m [1m[36mparse[22m[39m [32m"hello {"[39m
+Error: [31mnu::shell::delimiter_error
+[39m
+ [31m×[39m Delimiter error
+ ╭─[[1m[4m[36mrepl_entry #21:1:18[22m[24m[39m]
+ [2m1[22m │ "hello " | parse "hello {"
+ · [1m[35m ────┬────[22m[39m
+ · [1m[35m╰── Found opening `{` without an associated closing `}`[22m[39m
+ ╰────
+[0m
+```
+
+Escaped braces (`{{` and `}}`) still insert a literal brace. A lone `}` in `parse` is still a literal character to match, not an error. `parse --regex` is unchanged.
+
+### `into string` now preserves string typing for semver values
+
+```ansi :no-line-numbers
+[96m> [1m[36mlet[22m[39m [35ms[39m = [32m"1.0.0"[39m [1m[35m|[22m[39m [1m[36minto semver[22m[39m [1m[35m|[22m[39m [1m[36minto string[22m[96m
+> [35m$s[39m [1m[35m|[22m[39m [1m[36mdescribe[22m[39m
+string[96m
+> [32m"/tmp"[39m [1m[35m|[22m[39m [1m[36mpath join[22m[39m [1m[4m[34m([22m[24m[32m"1.115.0"[39m [1m[35m|[22m[39m [1m[36minto semver[22m[39m [1m[35m|[22m[39m [1m[36minto string[4m[34m)[22m[24m[39m
+/tmp/1.115.0[0m
+```
+
+### `format date` handles locale-specific formats correctly
+
+`format date` now handles `%E` and `%O` modifiers in locale-specific formats. Under locales such as Thai (`th_TH`) and Lao (`lo_LA`), `%x`, `%X` and `%c` render in the locale's own field order, without the era. This also fixes startup errors from the default config's `date now | format date '%x %X'`.
+
+```ansi :no-line-numbers title="Thai locale"
+[96m> [35m$env[39m.[32mLC_TIME[39m [33m=[39m [32m"th_TH.UTF-8"[96m
+> [1m[36mdate now[22m[39m [1m[35m|[22m[39m [1m[36mformat date[22m[39m [32m'%c'[39m
+ส. 26 ก.ย. 26, 20:30:58[0m
+```
+
+Explicit modifiers work too: `%Ey` and `%Od` render as `%y` and `%d` would. For locales without an AM/PM format, including `az_IR` and `fa_IR`, `%r` falls back to the locale's plain time format and handles its modifiers:
+
+```ansi :no-line-numbers title="Persian (Iran) locale"
+[96m> [35m$env[39m.[32mLC_TIME[39m [33m=[39m [32m"fa_IR.UTF-8"[96m
+> [1m[36mdate now[22m[39m [1m[35m|[22m[39m [1m[36mformat date[22m[39m [32m%r[39m
+20:34:19[0m
+```
+
+Other locales, including `de_DE`, `fr_FR` and `nl_NL`, continue to render as before.
+
+### Faster repeated `source` of the same file
+
+0.115 started re-parsing every `source` / `source-env` of a file that had already been parsed, so configs and libraries that `source` the same helpers many times got slower as more files were loaded. A 63-file case that stayed around 50ms in 0.114 grew to hundreds of milliseconds.
+
+This release restores safe reuse of cached blocks for `source` and `source-env`. Libraries without captured values can use the cache, as in 0.114, while blocks with stale captures are parsed again to keep their values up to date.
+
+### Redirected `nu --help` output no longer contains ANSI color escapes
+
+`nu --help` no longer writes ANSI escape sequences when its stdout is redirected to a pipe or file.
+
+For example:
+
+```sh
+nu --help > help.txt
+```
+
+Now produces plain text instead of ANSI-colored text.
+
+### Table display now respects `$env.config.table.trim` wrapping and truncating more consistently
+
+Fixed `$env.config.table.trim` so wrapping and truncating actually differ on default table display (`table -e` on terminals 100 columns or wider), including with `header_on_separator`.
+
+| Mode | Behavior |
+| :------------- | :--------------------------------------------------------------------------------------------------------------- |
+| **Wrapping** | Shows more columns, wrapping long cells onto extra lines. |
+| **Truncating** | Keeps one line per row, drops extra columns with a trailing `...`, and marks cut cells with `truncating_suffix`. |
+
+In both modes, columns are no longer squeezed to a single character, avoiding the vertical `s/i/z/e` layout for `size`. The trailing `...` column indicates omitted columns; `truncating_suffix` only marks a visible cell whose content was cut.
+
+Examples:
+
+```ansi :no-line-numbers title="Wrapping"
+[96m> [35m$env[39m.[32mconfig[39m.[32mtable[39m.[32mtrim[39m [33m=[39m [1m[4m[36m{[24m [22m[32mmethodology[1m[36m: [22m[32mwrapping[1m[36m, [22m[32mtruncating_suffix[1m[36m: [22m[32m"..."[1m[36m [4m}[22m[24m[96m
+> [1m[36mls[22m[39m [1m[34m-al[22m[39m [1m[35m|[22m[39m [1m[36mfirst[22m[39m [1m[35m5[22m[39m
+╭───┬─────────────────────────────────────────┬──────┬────────┬──────────┬────────┬────────┬─────╮
+│ [1m[32m#[22m[39m │ [1m[32mname[22m[39m │ [1m[32mtype[22m[39m │ [1m[32mtarget[22m[39m │ [1m[32mreadonly[22m[39m │ [1m[32msize[22m[39m │ [1m[32mcreate[22m[39m │ ... │
+│ │ │ │ │ │ │ [1m[32md[22m[39m │ │
+├───┼─────────────────────────────────────────┼──────┼────────┼──────────┼────────┼────────┼─────┤
+│ [1m[32m0[22m[39m │ .abc___________________________________ │ file │ │ [96mfalse[39m │ [36m0 B[39m │ [35ma minu[39m │ ... │
+│ │ │ │ │ │ │ [35mte ago[39m │ │
+│ [1m[32m1[22m[39m │ [38;5;81m.cargo[39m │ dir │ │ [96mfalse[39m │ [36m0 B[39m │ [35ma year[39m │ ... │
+│ │ │ │ │ │ │ [35m ago[39m │ │
+│ [1m[32m2[22m[39m │ [38;5;81m.git[39m │ dir │ │ [96mfalse[39m │ [36m4,0 kB[39m │ [35m2 year[39m │ ... │
+│ │ │ │ │ │ │ [35ms ago[39m │ │
+│ [1m[32m3[22m[39m │ [38;5;149m.gitattributes[39m │ file │ │ [96mfalse[39m │ [36m113 B[39m │ [35m3 mont[39m │ ... │
+│ │ │ │ │ │ │ [35mhs ago[39m │ │
+│ [1m[32m4[22m[39m │ [38;5;81m.githooks[39m │ dir │ │ [96mfalse[39m │ [36m0 B[39m │ [35m3 mont[39m │ ... │
+│ │ │ │ │ │ │ [35mhs ago[39m │ │
+╰───┴─────────────────────────────────────────┴──────┴────────┴──────────┴────────┴────────┴─────╯[0m
+```
+
+```ansi :no-line-numbers title="Truncating"
+[96m> [35m$env[39m.[32mconfig[39m.[32mtable[39m.[32mtrim[39m [33m=[39m [1m[4m[36m{[24m [22m[32mmethodology[1m[36m: [22m[32mtruncating[1m[36m, [22m[32mtruncating_suffix[1m[36m: [22m[32m"..."[1m[36m [4m}[22m[24m[96m
+> [1m[36mls[22m[39m [1m[34m-al[22m[39m [1m[35m|[22m[39m [1m[36mfirst[22m[39m [1m[35m5[22m[39m
+╭───┬─────────────────────────────────────────┬──────┬────────┬──────────┬────────┬────────┬─────╮
+│ [1m[32m#[22m[39m │ [1m[32mname[22m[39m │ [1m[32mtype[22m[39m │ [1m[32mtarget[22m[39m │ [1m[32mreadonly[22m[39m │ [1m[32msize[22m[39m │ [1m[32mcre...[22m[39m │ ... │
+├───┼─────────────────────────────────────────┼──────┼────────┼──────────┼────────┼────────┼─────┤
+│ [1m[32m0[22m[39m │ .abc___________________________________ │ file │ │ [96mfalse[39m │ [36m0 B[39m │ [35m2 m...[39m │ ... │
+│ [1m[32m1[22m[39m │ [38;5;81m.cargo[39m │ dir │ │ [96mfalse[39m │ [36m0 B[39m │ [35ma y...[39m │ ... │
+│ [1m[32m2[22m[39m │ [38;5;81m.git[39m │ dir │ │ [96mfalse[39m │ [36m4,0 kB[39m │ [35m2 y...[39m │ ... │
+│ [1m[32m3[22m[39m │ [38;5;149m.gitattributes[39m │ file │ │ [96mfalse[39m │ [36m113 B[39m │ [35m3 m...[39m │ ... │
+│ [1m[32m4[22m[39m │ [38;5;81m.githooks[39m │ dir │ │ [96mfalse[39m │ [36m0 B[39m │ [35m3 m...[39m │ ... │
+╰───┴─────────────────────────────────────────┴──────┴────────┴──────────┴────────┴────────┴─────╯[0m
+```
+
+### `length`, `columns`, and `is-empty` now surface errors from streamed input
+
+Fixed an issue where `length`, `columns`, and `is-empty` / `is-not-empty` could silently ignore errors in streamed input and return incorrect results instead of surfacing the original error.
+
+For example, `[[name size]; [a 100b] [b 200b]] | where size <= 150 | length` now errors with `nu::shell::operator_incompatible_types` instead of returning `2`, and likewise for `columns` / `is-empty`.
+
+```ansi :no-line-numbers
+[96m> [1m[34m[[[22m[32mname[1m[34m [22m[32msize[1m[34m]; [[22m[32ma[1m[34m [35m100[22m[32mb[1m[34m] [[22m[32mb[1m[34m [35m200[22m[32mb[1m[34m]][22m[39m [1m[35m|[22m[39m [1m[36mwhere[22m[39m [32msize[39m [33m<=[39m [1m[35m150[22m[39m [1m[35m|[22m[39m [1m[36mlength[22m[39m
+Error: [31mnu::shell::operator_incompatible_types
+[39m
+ [31m×[39m Types 'filesize' and 'int' are not compatible for the '<=' operator.
+ ╭─[[1m[4m[36mrepl_entry #52:1:18[22m[24m[39m]
+ [2m1[22m │ [[name size]; [a 100b] [b 200b]] | where size <= 150 | length
+ · [1m[35m ──┬─[33m ─┬[32m ─┬─[22m[39m
+ · [1m[35m│[22m[39m [1m[33m│[22m[39m [1m[32m╰── int[22m[39m
+ · [1m[35m│[22m[39m [1m[33m╰── does not operate between 'filesize' and 'int'[22m[39m
+ · [1m[35m╰── filesize[22m[39m
+ ╰────
+[0m
+```
+
+### Chained `par-each` pipelines no longer deadlock on same-size thread pools
+
+Chaining `par-each` commands with the same thread count could cause a pipeline to hang. The commands could share a thread pool while both were still running: the earlier stage would wait for the next stage to consume its output, while the next stage waited for a free worker.
+
+This release reuses cached thread pools only when they are idle. Stages running at the same time use separate pools, allowing pipelines like this to finish:
+
+```ansi :no-line-numbers
+[96m> [1m[35m0[22m[33m..[1m[35m99
+|[22m[39m [1m[36mpar-each[22m[39m [1m[34m--threads[22m[39m [1m[35m1[22m[39m [1m[32m{|it| [22m[35m$it[1m[32m }[35m
+|[22m[39m [1m[36mpar-each[22m[39m [1m[34m--threads[22m[39m [1m[35m1[22m[39m [1m[32m{|it| [22m[35m$it[1m[32m }[35m
+|[22m[39m [1m[36mlength[22m[39m
+100[0m
+```
+
+### Expanded nested tables now keep their table borders when cells wrap
+
+`table --expand` now preserves the borders of nested tables, including those in `plugin list` output. Previously, wrapping a nested table as plain text could break its layout.
+
+Long cells wrap or truncate within the nested table according to `$env.config.table.trim`, keeping its structure intact. Scalar values in the outer table continue to follow the same wrapping or truncation setting.
+
+### `mkdir --verbose` no longer reports existing directories as newly created
+
+Fixed `mkdir --verbose` reporting `created: true` for directories that already
+existed. Such rows now report `created: false`. Directories that are actually
+created are unaffected.
+
+### `finally` now always runs, in the right order, however a `try` block is left
+
+#### Cleanup runs in the right order
+
+When an outer `catch` handles an error, every `finally` block between the error and that handler now runs, innermost first. This also applies to errors raised inside a `catch` or another `finally` block. An error raised in `finally` still replaces the original error.
+
+An error or `return` inside `try` now runs `finally` and takes effect without executing the statements after the `try` expression. Likewise, `break` and `continue` run `finally` before control returns to the loop. They also leave error handlers intact, fixing cases where a later, unrelated error triggered a leftover handler.
+
+#### Consistent input to `finally`
+
+`$in` is now always defined inside `finally` and matches the block's optional parameter (`finally {|x| ... }`):
+
+| How `try`/`catch` completes | Value passed to `finally` |
+| :-------------------------------------- | :---------------------------------- |
+| Success | The value produced by `try`/`catch` |
+| Error | The error record |
+| `return`, `exit`, `break` or `continue` | `nothing` |
+
+#### Changes to `view ir`
+
+`view ir` now shows `begin-finally`, `end-finally` and `unwind-jump` in place of `pop-finally`. The register-less `finally` instruction has also been removed.
+
+### List literals and `match` patterns now reject semicolon separators
+
+List literals and `match` list patterns now reject unexpected semicolon separators instead of silently accepting malformed input or discarding subsequent content.
+
+Header-only table syntax such as `[[a b];]` now also produces a parse error.
+
+```ansi :no-line-numbers
+[96m> [1m[4m[34m[[24m[[22m[32ma[1m[34m [22m[32mb[1m[34m];[4m][22m[24m[39m
+Error: [31mnu::parser::parse_mismatch
+[39m
+ [31m×[39m Parse mismatch: expected table row.
+ ╭─[[1m[4m[36mrepl_entry #60:1:8[22m[24m[39m]
+ [2m1[22m │ [[a b];]
+ · [1m[35m ▲[22m[39m
+ · [1m[35m╰── expected table row[22m[39m
+ ╰────[36m
+ help: [39mCheck the syntax around this position — a typo, missing delimiter, or wrong separator is common.
+[0m
+```
+
+### LSP hover tooltips now render Markdown without accidental bold text
+
+LSP hover descriptions now render as normal text. A missing blank line before the Markdown separator made the description look like a heading instead.
+
+
+
+ Before
+
+
Renders some greeting message
+
Usage
+
hello {flags}
+
+
+
+ After
+
+
Renders some greeting message
+
+
Usage
+
hello {flags}
+
+
+
+
+
* These previews are approximations for illustration, not actual LSP output. The exact appearance depends on your editor.
+
+### External completers now receive expanded alias commands and show warnings after menus close
+
+External completers receive the command name and its arguments in `$place.command`, with one list item per shell word. This list describes the command at the cursor, including when it appears after a pipe or `;`, or inside a closure.
+
+For example, this completer passes the command name and argument list to Carapace:
+
+```nu
+$env.config.completions.external.completer = {|place|
+ carapace $place.command.0 nushell ...$place.command | from json
+}
+```
+
+Aliases are expanded before the list reaches the completer. If `gco` is an alias for `git checkout`, typing `gco ma` gives the completer `[git, checkout, ma]`.
+
+The legacy `spans` input receives the same list. Incomplete arguments stay together: typing `foo [a b` produces `[foo, "[a b"]`, keeping the unfinished list as one argument instead of splitting it into brackets, words and spaces.
+
+Deprecation warnings for menu `source` configurations now appear after the command line is handed back, once the completion menu has closed. This keeps warnings from appearing over the menu.
+
+### Other fixes
+
+- 2 issues were identified which may result in invalid suggestions when an unresolved command is entered. ([#18728](https://github.com/nushell/nushell/pull/18728))
+- Fixed an issue where YAML values containing `.inf` or `.nan` as embedded text could be incorrectly converted to floating-point values. Values such as `a.infra` and `a.nanotube` now remain strings when decoded with `from yaml`. ([#18897](https://github.com/nushell/nushell/pull/18897))
+- Invalidate the config any time anything changes under $env.config ([#18950](https://github.com/nushell/nushell/pull/18950))
+- Nushell now supports color coded `ls` output for a broader range of files by default (e.g. `.avif`, `.odin`, etc.), with the exception of `.kex` which has been removed. `.csv` has a new default color value. ([#18937](https://github.com/nushell/nushell/pull/18937))
+- Fixed an issue in `keybindings listen` where `Esc` wouldn't quit if a state (e.g. `NumLock` or `CapsLock`) was reported. ([#18867](https://github.com/nushell/nushell/pull/18867))
+- `try` with a `catch` or `finally` block no longer prints a stray blank line after an external command's output. ([#18811](https://github.com/nushell/nushell/pull/18811))
+- Fixed an issue where each while silently stopped when the closure or input ByteStream produced an error. These errors are now preserved and reported. ([#18958](https://github.com/nushell/nushell/pull/18958))
+- External command arguments beginning with { are now parsed as closures or records; literal curly-braced arguments must be quoted. ([#18837](https://github.com/nushell/nushell/pull/18837))
+- Fixed an issue where `--ide-check` silently succeeded when the target file could not be read. Nushell now reports the file read error and exits with a non-zero status. ([#18961](https://github.com/nushell/nushell/pull/18961))
+- Fixed an issue in workspace compilation where using the "plugin" feature flag that would result in a compilation error. ([#18988](https://github.com/nushell/nushell/pull/18988))
+- Fixed an issue where `commandline complete` ignored an external completer assigned to `$env.config.completions.external.completer` earlier in the same script. ([#19012](https://github.com/nushell/nushell/pull/19012))
+- Adds a default value to `error make`'s labels `text` ([#19037](https://github.com/nushell/nushell/pull/19037))
+- Fixed `query web -t []` failing with `plugin_failed_to_decode` on HTML tables that have no `
` headers and more than one row. Such tables now produce one record per row with generated `column0`, `column1`, ... column names. ([#19041](https://github.com/nushell/nushell/pull/19041))
+- Fixed a panic when printing empty lists/records or narrow-fitting tables on a zero-column pty (e.g. some CI environments). Nushell now falls back to plain text output or a warning instead of crashing. ([#19045](https://github.com/nushell/nushell/pull/19045))
+- mktemp --directory is now relative to the working directory if a template is passed ([#18996](https://github.com/nushell/nushell/pull/18996))
+- `default` now accepts cell paths for its column arguments, so `default 5 a.b` fills the nested field `b` inside `a` (creating `a` if needed) instead of adding a literal `"a.b"` key. Quote the argument, as in `default 5 "a.b"`, to target a key that actually contains a dot. ([#19058](https://github.com/nushell/nushell/pull/19058))
+- Fixed an issue where `flatten` silently dropped a nested record field when a top-level column of the same name came later in the record. The nested field is now renamed to `_`, as it already was for the opposite field order. The `flatten` help text now describes how record input is handled. ([#19059](https://github.com/nushell/nushell/pull/19059))
+- Fixed an issue where `std dt datetime-diff` reported an incorrect day count when the difference crossed a month boundary — for example, the difference between `2021-01-15` and `2021-03-01` was `1month 17days` instead of the correct `1month 14days`. This also corrects the standard-library startup banner, which formats its uptime with `datetime-diff` via `pretty-print-duration`. ([#19064](https://github.com/nushell/nushell/pull/19064))
+- Fixed `rm` with leading-dot globs such as `rm -r dir/.*` on Windows deleting `dir` and its parent directory. The `.` and `..` entries are now skipped on all platforms. ([#19065](https://github.com/nushell/nushell/pull/19065))
+- `table --theme markdown` and `table --theme restructured` (and the matching `$env.config.table.mode` values) now always produce valid Markdown / reStructuredText, even when `$env.config.table.header_on_separator` is enabled. ([#19066](https://github.com/nushell/nushell/pull/19066))
+- Fixed `rm --interactive` on Windows answering two prompts with a single key press. ([#19067](https://github.com/nushell/nushell/pull/19067))
+- Fixed `idx search` returning at most 200 matches per file and ignoring the exact `--limit` value. ([#19078](https://github.com/nushell/nushell/pull/19078))
+- Fixed an issue where Nushell ignored `XDG_CONFIG_HOME` for users without a home directory. Config loads from `XDG_CONFIG_HOME` again, and `$nu.home-dir` reports an error when there is no home directory. ([#19083](https://github.com/nushell/nushell/pull/19083))
+- Fixed `path relative-to` providing improper error messages when its argument was not a parent of the input.
+- `view source` now renders a rest parameter as `...rest: string` rather than `...rest:string`, matching how it already renders every other parameter.
+
+# Notes for plugin developers
+
+- Fixed compiling `nu-plugin-test-support` by default together with `nu-plugin`.
+
+# Hall of fame
+
+Thanks to all the contributors below for helping us solve issues, improve documentation, refactor code, and more! :pray:
+
+| author | change | link |
+| ---------------------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------- |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Remove most `fs` helpers from `nu-test-support` | [#18910](https://github.com/nushell/nushell/pull/18910) |
+| [@fdncred](https://github.com/fdncred) | Fix completion tests by resolving ".." in `WORKSPACE_ROOT` path | [#18941](https://github.com/nushell/nushell/pull/18941) |
+| [@fdncred](https://github.com/fdncred) | IR-shaped const evaluation for run_const (AST migration phase 2) | [#18967](https://github.com/nushell/nushell/pull/18967) |
+| [@hustcer](https://github.com/hustcer) | Fix nushell command docs build error | [#19084](https://github.com/nushell/nushell/pull/19084) |
+
+# Full changelog
+
+| author | title | link |
+| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
+| [@Developer1010x](https://github.com/Developer1010x) | fix(mkdir): don't report an existing directory as created in --verbose | [#19017](https://github.com/nushell/nushell/pull/19017) |
+| [@Developer1010x](https://github.com/Developer1010x) | docs(mkdir): the --verbose example showed output that never occurs | [#19023](https://github.com/nushell/nushell/pull/19023) |
+| [@Developer1010x](https://github.com/Developer1010x) | fix(view source): put a space after the colon on a rest parameter | [#19024](https://github.com/nushell/nushell/pull/19024) |
+| [@Dheebz](https://github.com/Dheebz) | fix(env): normalize PATH when refreshing ENV_CONVERSIONS | [#18832](https://github.com/nushell/nushell/pull/18832) |
+| [@Dheebz](https://github.com/Dheebz) | fix(parser): parse brace expressions in external calls | [#18837](https://github.com/nushell/nushell/pull/18837) |
+| [@Dheebz](https://github.com/Dheebz) | fix: use stack config for commandline completions | [#19012](https://github.com/nushell/nushell/pull/19012) |
+| [@Dorumin](https://github.com/Dorumin) | Don't go to tmp if --directory | [#18996](https://github.com/nushell/nushell/pull/18996) |
+| [@Jorge-Polanco-Roque](https://github.com/Jorge-Polanco-Roque) | feat(mkdir): add --fail-if-exists flag to error on existing directory | [#19021](https://github.com/nushell/nushell/pull/19021) |
+| [@KaiSforza](https://github.com/KaiSforza) | error make: Allow no text value | [#19037](https://github.com/nushell/nushell/pull/19037) |
+| [@KaiSforza](https://github.com/KaiSforza) | scripts/nix: Update the flake lock | [#19038](https://github.com/nushell/nushell/pull/19038) |
+| [@LouisDeconinck](https://github.com/LouisDeconinck) | fix(query web): parse headerless tables row by row | [#19041](https://github.com/nushell/nushell/pull/19041) |
+| [@LouisDeconinck](https://github.com/LouisDeconinck) | fix(table): don't panic when the terminal is too narrow to draw | [#19045](https://github.com/nushell/nushell/pull/19045) |
+| [@Mrfiregem](https://github.com/Mrfiregem) | let more commands use row conditions | [#18844](https://github.com/nushell/nushell/pull/18844) |
+| [@Mrfiregem](https://github.com/Mrfiregem) | Include UTC offset in `date list-timezone` output | [#18922](https://github.com/nushell/nushell/pull/18922) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump taiki-e/install-action from 2.85.11 to 2.86.6 | [#18904](https://github.com/nushell/nushell/pull/18904) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump uuid from 1.24.0 to 1.25.0 | [#18906](https://github.com/nushell/nushell/pull/18906) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump tango-bench from 0.7.2 to 0.8.0 | [#18907](https://github.com/nushell/nushell/pull/18907) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.48.0 to 1.50.0 | [#18954](https://github.com/nushell/nushell/pull/18954) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump hustcer/milestone-action from 3.1 to 3.2 | [#18955](https://github.com/nushell/nushell/pull/18955) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump ureq from 3.3.0 to 3.4.0 | [#18957](https://github.com/nushell/nushell/pull/18957) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump taiki-e/install-action from 2.86.6 to 2.87.7 | [#18990](https://github.com/nushell/nushell/pull/18990) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.50.0 to 1.50.1 | [#18991](https://github.com/nushell/nushell/pull/18991) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump the uutils group with 8 updates | [#18992](https://github.com/nushell/nushell/pull/18992) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump aws-config from 1.10.0 to 1.12.0 | [#18994](https://github.com/nushell/nushell/pull/18994) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump taiki-e/install-action from 2.87.7 to 2.87.12 | [#19028](https://github.com/nushell/nushell/pull/19028) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump actions-rust-lang/setup-rust-toolchain from 1.17.0 to 2.0.0 | [#19029](https://github.com/nushell/nushell/pull/19029) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump dirs from 6.0.0 to 7.0.0 | [#19030](https://github.com/nushell/nushell/pull/19030) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump tabled from 0.21.0 to 0.22.0 | [#19031](https://github.com/nushell/nushell/pull/19031) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump taiki-e/install-action from 2.87.12 to 2.87.17 | [#19068](https://github.com/nushell/nushell/pull/19068) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.50.1 to 1.50.2 | [#19069](https://github.com/nushell/nushell/pull/19069) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump rstest from 0.26.1 to 0.27.0 | [#19070](https://github.com/nushell/nushell/pull/19070) |
+| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump serde-saphyr from 1.2.0 to 1.3.0 | [#19071](https://github.com/nushell/nushell/pull/19071) |
+| [@aron-intframe](https://github.com/aron-intframe) | fix(format date): render locales whose format carries %E or %O | [#18918](https://github.com/nushell/nushell/pull/18918) |
+| [@aron-intframe](https://github.com/aron-intframe) | fix(format date): resolve `%r` when the locale's am/pm fallback also carries `%O` | [#18924](https://github.com/nushell/nushell/pull/18924) |
+| [@ayax79](https://github.com/ayax79) | Polars date range | [#18887](https://github.com/nushell/nushell/pull/18887) |
+| [@ayax79](https://github.com/ayax79) | MCP: set default bind host to 127.0.0.1 | [#18952](https://github.com/nushell/nushell/pull/18952) |
+| [@bobisageek](https://github.com/bobisageek) | fix `keybindings listen` - ignore KeyEventState when checking for Esc | [#18867](https://github.com/nushell/nushell/pull/18867) |
+| [@catlover-bot](https://github.com/catlover-bot) | fix: strip ANSI from redirected CLI help | [#18899](https://github.com/nushell/nushell/pull/18899) |
+| [@costajohnt](https://github.com/costajohnt) | fix(config): keep XDG config when there is no home directory | [#19083](https://github.com/nushell/nushell/pull/19083) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow raw `null` as a value for `to yaml --non-roundtrip` | [#18851](https://github.com/nushell/nushell/pull/18851) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow float value strings with commas in `into float` | [#18882](https://github.com/nushell/nushell/pull/18882) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Prepare patch release | [#18884](https://github.com/nushell/nushell/pull/18884) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump patch version after release | [#18885](https://github.com/nushell/nushell/pull/18885) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Remove most `fs` helpers from `nu-test-support` | [#18910](https://github.com/nushell/nushell/pull/18910) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Propagate `local-socket` feature into `nu-plugin-test-support` | [#18947](https://github.com/nushell/nushell/pull/18947) |
+| [@cptpiepmatz](https://github.com/cptpiepmatz) | Replace `to yaml` `--compact-list-indent` with `--list-indent` | [#19005](https://github.com/nushell/nushell/pull/19005) |
+| [@cuishuang](https://github.com/cuishuang) | ide: report file read failures from --ide-check | [#18961](https://github.com/nushell/nushell/pull/18961) |
+| [@dilr](https://github.com/dilr) | Document behavior of `each` for more types of inputs. | [#18893](https://github.com/nushell/nushell/pull/18893) |
+| [@fdncred](https://github.com/fdncred) | named parameters can pass null or omit parameter entirely for easier shadowing | [#18796](https://github.com/nushell/nushell/pull/18796) |
+| [@fdncred](https://github.com/fdncred) | reduce ast dependency for ir calls - phase 1 | [#18813](https://github.com/nushell/nushell/pull/18813) |
+| [@fdncred](https://github.com/fdncred) | perf - stop parse-time-loading modules and extra cwd walks while typing `use std/` | [#18841](https://github.com/nushell/nushell/pull/18841) |
+| [@fdncred](https://github.com/fdncred) | fix unmatched `{` at end of `format pattern` and `parse` patterns | [#18871](https://github.com/nushell/nushell/pull/18871) |
+| [@fdncred](https://github.com/fdncred) | fix `lines --skip-empty` for string and byte stream input | [#18872](https://github.com/nushell/nushell/pull/18872) |
+| [@fdncred](https://github.com/fdncred) | fix: infer string from `semver \| into string`. | [#18901](https://github.com/nushell/nushell/pull/18901) |
+| [@fdncred](https://github.com/fdncred) | fix(tests): fix completion tests by resolving ".." in `WORKSPACE_ROOT` path | [#18941](https://github.com/nushell/nushell/pull/18941) |
+| [@fdncred](https://github.com/fdncred) | update proc_macro_error to 3 and other dependencies | [#18945](https://github.com/nushell/nushell/pull/18945) |
+| [@fdncred](https://github.com/fdncred) | update fff-search to 0.10.6 | [#18946](https://github.com/nushell/nushell/pull/18946) |
+| [@fdncred](https://github.com/fdncred) | fix parsing performance regression | [#18948](https://github.com/nushell/nushell/pull/18948) |
+| [@fdncred](https://github.com/fdncred) | when config changes invalidate cache | [#18950](https://github.com/nushell/nushell/pull/18950) |
+| [@fdncred](https://github.com/fdncred) | bump reedline to a8e9364 | [#18959](https://github.com/nushell/nushell/pull/18959) |
+| [@fdncred](https://github.com/fdncred) | engine: IR-shaped const evaluation for run_const (AST migration phase 2) | [#18967](https://github.com/nushell/nushell/pull/18967) |
+| [@fdncred](https://github.com/fdncred) | bump rust toolchain to 1.96.1 | [#18968](https://github.com/nushell/nushell/pull/18968) |
+| [@fdncred](https://github.com/fdncred) | fix table truncating vs wrapping | [#18979](https://github.com/nushell/nushell/pull/18979) |
+| [@fdncred](https://github.com/fdncred) | fix nested table after wrapping/truncating changes | [#19007](https://github.com/nushell/nushell/pull/19007) |
+| [@fdncred](https://github.com/fdncred) | Revert "mkdir errors on already-created dir" | [#19008](https://github.com/nushell/nushell/pull/19008) |
+| [@fdncred](https://github.com/fdncred) | the tui family of commands | [#19025](https://github.com/nushell/nushell/pull/19025) |
+| [@fdncred](https://github.com/fdncred) | update rustls & friends | [#19026](https://github.com/nushell/nushell/pull/19026) |
+| [@fdncred](https://github.com/fdncred) | update some deps | [#19034](https://github.com/nushell/nushell/pull/19034) |
+| [@fdncred](https://github.com/fdncred) | bump uu\_\* crates to 0.12.0 | [#19040](https://github.com/nushell/nushell/pull/19040) |
+| [@fdncred](https://github.com/fdncred) | perf(startup): make $nu.startup-time accurate and speed up config loading, plugin registry, and gstat | [#19049](https://github.com/nushell/nushell/pull/19049) |
+| [@fdncred](https://github.com/fdncred) | fix(engine): run every finally on the way out of nested try blocks, and unwind break/continue through them | [#19052](https://github.com/nushell/nushell/pull/19052) |
+| [@fdncred](https://github.com/fdncred) | perf(parser): reduce parse time by 30% - 50% | [#19055](https://github.com/nushell/nushell/pull/19055) |
+| [@fdncred](https://github.com/fdncred) | bump fff-search to 0.11.0 | [#19057](https://github.com/nushell/nushell/pull/19057) |
+| [@fdncred](https://github.com/fdncred) | fix(default): accept cell paths for column arguments | [#19058](https://github.com/nushell/nushell/pull/19058) |
+| [@fdncred](https://github.com/fdncred) | fix(flatten): keep nested fields that collide with top-level columns | [#19059](https://github.com/nushell/nushell/pull/19059) |
+| [@fdncred](https://github.com/fdncred) | feat(update cells): add --recursive flag to visit nested leaf values | [#19060](https://github.com/nushell/nushell/pull/19060) |
+| [@fdncred](https://github.com/fdncred) | fix lsp hover tooltip markdown | [#19080](https://github.com/nushell/nushell/pull/19080) |
+| [@fly1d](https://github.com/fly1d) | fix(yaml): do not parse embedded float tokens | [#18897](https://github.com/nushell/nushell/pull/18897) |
+| [@hexbinoct](https://github.com/hexbinoct) | Don't print a stray blank line when try with catch or finally collects an external | [#18811](https://github.com/nushell/nushell/pull/18811) |
+| [@hustcer](https://github.com/hustcer) | Fix nushell command docs build error | [#19084](https://github.com/nushell/nushell/pull/19084) |
+| [@i-api](https://github.com/i-api) | docs(nuon): add a specification of the NUON format | [#18925](https://github.com/nushell/nushell/pull/18925) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | chore(reedline): bump reedline to 73b928a | [#18890](https://github.com/nushell/nushell/pull/18890) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | chore(reedline): bump reedline fc19b91 | [#18892](https://github.com/nushell/nushell/pull/18892) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | fix(nix): bump rust-overlay so the 1.96.1 toolchain resolves | [#18985](https://github.com/nushell/nushell/pull/18985) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | chore: bump reedline 06bf606 | [#18986](https://github.com/nushell/nushell/pull/18986) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | chore: bump reedline to 436f17b | [#19013](https://github.com/nushell/nushell/pull/19013) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | chore(reedline): bump reedline to e0f1c0b | [#19042](https://github.com/nushell/nushell/pull/19042) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | fix(reedline): forward Menu::settings through SourcedMenu | [#19043](https://github.com/nushell/nushell/pull/19043) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | fix(ci): run `ready_for_review` CI on the PR head, not on `main` | [#19047](https://github.com/nushell/nushell/pull/19047) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | feat(reedline): bump to db34d84 | [#19077](https://github.com/nushell/nushell/pull/19077) |
+| [@kronberger-droid](https://github.com/kronberger-droid) | fix(completions): expand alias heads in `place.command`, keep completer warnings off the menu | [#19085](https://github.com/nushell/nushell/pull/19085) |
+| [@luangucun](https://github.com/luangucun) | each while: preserve errors instead of silently stopping | [#18958](https://github.com/nushell/nushell/pull/18958) |
+| [@magnify035](https://github.com/magnify035) | chore(ls): update default color mappings | [#18937](https://github.com/nushell/nushell/pull/18937) |
+| [@maxim-uvarov](https://github.com/maxim-uvarov) | Add `completions.persistent_menus` config option | [#18573](https://github.com/nushell/nushell/pull/18573) |
+| [@maxim-uvarov](https://github.com/maxim-uvarov) | View source dependencies | [#18801](https://github.com/nushell/nushell/pull/18801) |
+| [@mikehasa](https://github.com/mikehasa) | fix(std/dt): correct `datetime-diff` day count when borrowing a month | [#19064](https://github.com/nushell/nushell/pull/19064) |
+| [@mkatychev](https://github.com/mkatychev) | fix(nu-plugin): add socket feature flag to handle `--no-default-features` correctly | [#18988](https://github.com/nushell/nushell/pull/18988) |
+| [@mrhard9090](https://github.com/mrhard9090) | fix(rm): skip `.` and `..` glob matches on Windows | [#19065](https://github.com/nushell/nushell/pull/19065) |
+| [@mrhard9090](https://github.com/mrhard9090) | fix(table): keep markdown and restructured headers off the separator | [#19066](https://github.com/nushell/nushell/pull/19066) |
+| [@mrhard9090](https://github.com/mrhard9090) | fix(rm): answer one `--interactive` prompt per key press on Windows | [#19067](https://github.com/nushell/nushell/pull/19067) |
+| [@mrhard9090](https://github.com/mrhard9090) | fix(idx search): don't cap matches at 200 per file | [#19078](https://github.com/nushell/nushell/pull/19078) |
+| [@neveroNiwe](https://github.com/neveroNiwe) | Add structured context support to std/log | [#18971](https://github.com/nushell/nushell/pull/18971) |
+| [@nos1dot618](https://github.com/nos1dot618) | docs(tutor): add reedline shortcuts tutorial and document $env | [#18903](https://github.com/nushell/nushell/pull/18903) |
+| [@nos1dot618](https://github.com/nos1dot618) | docs(tutor): add custom commands and pipeline input tutorials | [#18927](https://github.com/nushell/nushell/pull/18927) |
+| [@nos1dot618](https://github.com/nos1dot618) | docs(tutor): add conditional(if, match, where) tutorials | [#18972](https://github.com/nushell/nushell/pull/18972) |
+| [@pheenty](https://github.com/pheenty) | fix improper cant convert error in path-relative-to | [#18792](https://github.com/nushell/nushell/pull/18792) |
+| [@philocalyst](https://github.com/philocalyst) | Unified Completions | [#18791](https://github.com/nushell/nushell/pull/18791) |
+| [@philocalyst](https://github.com/philocalyst) | fixes for unified/completions in general | [#19054](https://github.com/nushell/nushell/pull/19054) |
+| [@pickx](https://github.com/pickx) | roundup of 2 fixes for "did you mean?" | [#18728](https://github.com/nushell/nushell/pull/18728) |
+| [@pickx](https://github.com/pickx) | mkdir errors on already-created dir | [#19006](https://github.com/nushell/nushell/pull/19006) |
+| [@pickx](https://github.com/pickx) | `char`: add forward slash/backslash. | [#19082](https://github.com/nushell/nushell/pull/19082) |
+| [@rvhelden](https://github.com/rvhelden) | Add a `nu-dap` crate and `nu --dap`: a Debug Adapter Protocol server for Nushell | [#18738](https://github.com/nushell/nushell/pull/18738) |
+| [@sebaschi](https://github.com/sebaschi) | feat(hash): add `sha512` subcommand | [#19027](https://github.com/nushell/nushell/pull/19027) |
+| [@sidsri14](https://github.com/sidsri14) | fix: propagate error stream values in length, columns, and is-empty | [#18976](https://github.com/nushell/nushell/pull/18976) |
+| [@surma](https://github.com/surma) | feat(save): create parent directories with `--force` | [#19039](https://github.com/nushell/nushell/pull/19039) |
+| [@user93390](https://github.com/user93390) | update(style_computer.rs): fixed unessesary string allocations | [#18975](https://github.com/nushell/nushell/pull/18975) |
+| [@windlandneko](https://github.com/windlandneko) | fix(parser): reject unexpected semicolons in list literals and patterns | [#19063](https://github.com/nushell/nushell/pull/19063) |
+| [@zozo123](https://github.com/zozo123) | Test Incredibuild self-hosted runner in CI | [#18810](https://github.com/nushell/nushell/pull/18810) |
+| [@zozo123](https://github.com/zozo123) | Fix par-each deadlock when chaining same-size thread pools | [#18999](https://github.com/nushell/nushell/pull/18999) |