diff --git a/.vuepress/client.js b/.vuepress/client.js index 30391c6b5d8..c97025ed32a 100755 --- a/.vuepress/client.js +++ b/.vuepress/client.js @@ -7,6 +7,7 @@ import { defineClientConfig } from 'vuepress/client'; import AsciinemaPlayer from './components/AsciinemaPlayer.vue'; import BlogPosts from './components/BlogPosts.vue'; +import ExperimentalOption from './components/ExperimentalOption.vue'; import JumpToc from './components/JumpToc.vue'; import PrBy from './components/PrBy.vue'; import ReleaseToc from './components/ReleaseToc.vue'; @@ -15,6 +16,7 @@ export default defineClientConfig({ enhance({ app }) { app.component('AsciinemaPlayer', AsciinemaPlayer); app.component('BlogPosts', BlogPosts); + app.component('ExperimentalOption', ExperimentalOption); app.component('JumpToc', JumpToc); app.component('PrBy', PrBy); app.component('ReleaseToc', ReleaseToc); diff --git a/.vuepress/components/ExperimentalOption.vue b/.vuepress/components/ExperimentalOption.vue new file mode 100644 index 00000000000..5766584ed71 --- /dev/null +++ b/.vuepress/components/ExperimentalOption.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/blog/2026-04-11-nushell_v0_112_0.md b/blog/2026-04-11-nushell_v0_112_0.md new file mode 100644 index 00000000000..6f33fdc65e4 --- /dev/null +++ b/blog/2026-04-11-nushell_v0_112_0.md @@ -0,0 +1,1294 @@ +--- +title: Nushell 0.112.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.112.0 of Nu. This release adds... +--- + + + + + +# Nushell 0.112.0 + + + +Today, we're releasing version 0.112.0 of Nu. This release adds... + +# Where to get it + +Nu 0.112.0 is available as [pre-built binaries](https://github.com/nushell/nushell/releases/tag/0.112.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 + + + + +# Changes + +## Breaking changes + +### Parse markdown via `from md` + +::: info +The introduction of `from md` caused some discussion whether Nushell should automatically parse text formats like markdown. +We want to encourage discussion whether this is a fitting name or not in a [Github discussion](https://github.com/nushell/nushell/discussions/18011). +Please state your opinion on this. +::: + +Added new command `from md` to parse markdown into an AST. +This is considered a breaking change as `open`ing a markdown file now no longer returns a raw string but rather a structured AST. + +Use `open --raw` to open without conversion or hide the command using `hide 'from md'`. + +```ansi:no-line-numbers +> '# Title' | from md | table -e +╭───────┬──────────┬────────────────────────────────┬──────────────────┬───────────────────────────────────────────────────────────────────────────────────╮ +│ # │ type │ position │ attrs │ children │ +├───────┼──────────┼────────────────────────────────┼──────────────────┼───────────────────────────────────────────────────────────────────────────────────┤ +│ 0 │ h1 │ ╭───────┬────────────────╮ │ ╭───────┬───╮ │ ╭───┬──────┬────────────────────────────┬───────────────────┬────────────────╮ │ +│ │ │ │ │ ╭────────┬───╮ │ │ │ depth │ 1 │ │ │ # │ type │ position │ attrs │ children │ │ +│ │ │ │ start │ │ line │ 1 │ │ │ │ level │ 1 │ │ ├───┼──────┼────────────────────────────┼───────────────────┼────────────────┤ │ +│ │ │ │ │ │ column │ 1 │ │ │ ╰───────┴───╯ │ │ 0 │ text │ ╭───────┬────────────────╮ │ ╭───────┬───────╮ │ [list 0 items] │ │ +│ │ │ │ │ ╰────────┴───╯ │ │ │ │ │ │ │ │ ╭────────┬───╮ │ │ │ value │ Title │ │ │ │ +│ │ │ │ │ ╭────────┬───╮ │ │ │ │ │ │ │ start │ │ line │ 1 │ │ │ ╰───────┴───────╯ │ │ │ +│ │ │ │ end │ │ line │ 1 │ │ │ │ │ │ │ │ │ │ column │ 3 │ │ │ │ │ │ +│ │ │ │ │ │ column │ 8 │ │ │ │ │ │ │ │ │ ╰────────┴───╯ │ │ │ │ │ +│ │ │ │ │ ╰────────┴───╯ │ │ │ │ │ │ │ │ ╭────────┬───╮ │ │ │ │ │ +│ │ │ ╰───────┴────────────────╯ │ │ │ │ │ │ end │ │ line │ 1 │ │ │ │ │ │ +│ │ │ │ │ │ │ │ │ │ │ column │ 8 │ │ │ │ │ │ +│ │ │ │ │ │ │ │ │ │ ╰────────┴───╯ │ │ │ │ │ +│ │ │ │ │ │ │ │ ╰───────┴────────────────╯ │ │ │ │ +│ │ │ │ │ ╰───┴──────┴────────────────────────────┴───────────────────┴────────────────╯ │ +╰───────┴──────────┴────────────────────────────────┴──────────────────┴───────────────────────────────────────────────────────────────────────────────────╯ +``` + +### Other breaking changes + +- Mutable cell assignment now respects experimental option [`reorder-cell-paths`](#new-experimental-option-cell-path-types). ([#17696](https://github.com/nushell/nushell/pull/17696)) +- `job tag` is now called `job describe`, the `--tag` flag in `job spawn` and the `tag` column in `job list`, as `tag` was renamed to `description` for these. ([#17496](https://github.com/nushell/nushell/pull/17496)) +- `random choice` from `std-rfc` now behaves more similar to `first`, so that `random choice` returns a single element and `random choice 1` returns a list with one element. ([#17983](https://github.com/nushell/nushell/pull/17983)) + +## Additions + +### New flag ` --list-of-records` for `to nuon` + +Add support for `list-of-records` serialization in `to nuon` command to return tables as a list of records instead of inline tables. + +```ansi +> ls | to nuon --list-of-records +[{name: ".cargo", type: dir, size: 0b, modified: 2026-04-11T14:28:01.485060+02:00}, {name: ".gitattributes", type: file, size: 113b, modified: 2026-04-11T14:28:01.485565900+02:00}, {name: ".githooks", type: dir, size: 0b, modified: 2026-04-11T14:28:01.486572700+02:00}, {name: ".github", type: dir, size: 0b, modified: 2026-04-11T14:28:01.490573100+02:00}, {name: ".gitignore", type: file, size: 834b, modified: 2026-04-11T14:28:01.497597200+02:00}, {name: "AGENTS.md", type: file, size: 2115b, modified: 2026-04-11T14:28:01.498597200+02:00}, {name: "CITATION.cff", type: file, size: 838b, modified: 2026-04-11T14:28:01.498597200+02:00}, {name: "CLAUDE.md", type: symlink, size: 0b, modified: 2026-04-11T14:28:01.499597100+02:00}, {name: "CODE_OF_CONDUCT.md", type: file, size: 3520b, modified: 2026-04-11T14:28:01.499597100+02:00}, {name: "CONTRIBUTING.md", type: file, size: 18714b, modified: 2026-04-11T14:28:01.500597200+02:00}, {name: "Cargo.lock", type: file, size: 257047b, modified: 2026-04-11T14:28:01.501597200+02:00}, {name: "Cargo.toml", type: file, size: 11950b, modified: 2026-04-11T14:28:01.502596700+02:00}, {name: "Cross.toml", type: file, size: 684b, modified: 2026-04-11T14:28:01.502596700+02:00}, {name: LICENSE, type: file, size: 1115b, modified: 2026-04-11T14:28:01.502596700+02:00}, {name: "README.md", type: file, size: 12742b, modified: 2026-04-11T14:28:01.504102900+02:00}, {name: "SECURITY.md", type: file, size: 2710b, modified: 2026-04-11T14:28:01.504102900+02:00}, {name: assets, type: dir, size: 0b, modified: 2026-04-11T14:28:01.512623900+02:00}, {name: ast-grep, type: dir, size: 0b, modified: 2026-04-11T14:28:01.522645800+02:00}, {name: benches, type: dir, size: 0b, modified: 2026-04-11T14:28:01.524151300+02:00}, {name: "clippy.toml", type: file, size: 170b, modified: 2026-04-11T14:28:01.525159300+02:00}, {name: crates, type: dir, size: 0b, modified: 2026-04-11T14:28:02.451098600+02:00}, {name: devdocs, type: dir, size: 0b, modified: 2026-04-11T14:28:02.457631100+02:00}, {name: docker, type: dir, size: 0b, modified: 2026-04-11T14:28:02.458631500+02:00}, {name: "rust-toolchain.toml", type: file, size: 956b, modified: 2026-04-11T14:28:02.459632800+02:00}, {name: "rustfmt.toml", type: file, size: 18b, modified: 2026-04-11T14:28:02.459632800+02:00}, {name: scripts, type: dir, size: 0b, modified: 2026-04-11T14:28:02.466730800+02:00}, {name: "sgconfig.yml", type: file, size: 218b, modified: 2026-04-11T14:28:02.466730800+02:00}, {name: src, type: dir, size: 0b, modified: 2026-04-11T14:28:02.472540600+02:00}, {name: target, type: dir, size: 0b, modified: 2026-04-11T14:30:48.430795700+02:00}, {name: tests, type: dir, size: 0b, modified: 2026-04-11T14:28:02.629683500+02:00}, {name: toolkit, type: dir, size: 0b, modified: 2026-04-11T14:28:02.641237300+02:00}, {name: "toolkit.nu", type: file, size: 61b, modified: 2026-04-11T14:28:02.635231400+02:00}, {name: "typos.toml", type: file, size: 732b, modified: 2026-04-11T14:28:02.642236500+02:00}, {name: wix, type: dir, size: 0b, modified: 2026-04-11T14:28:02.645247500+02:00}] +``` + +```ansi:no-line-numbers +> ls | to nuon --list-of-records --indent 2 +[ + {name: ".cargo", type: dir, size: 0b, modified: 2026-04-11T14:28:01.485060+02:00}, + {name: ".gitattributes", type: file, size: 113b, modified: 2026-04-11T14:28:01.485565900+02:00}, + {name: ".githooks", type: dir, size: 0b, modified: 2026-04-11T14:28:01.486572700+02:00}, + {name: ".github", type: dir, size: 0b, modified: 2026-04-11T14:28:01.490573100+02:00}, + {name: ".gitignore", type: file, size: 834b, modified: 2026-04-11T14:28:01.497597200+02:00}, + {name: "AGENTS.md", type: file, size: 2115b, modified: 2026-04-11T14:28:01.498597200+02:00}, + {name: "CITATION.cff", type: file, size: 838b, modified: 2026-04-11T14:28:01.498597200+02:00}, + {name: "CLAUDE.md", type: symlink, size: 0b, modified: 2026-04-11T14:28:01.499597100+02:00}, + {name: "CODE_OF_CONDUCT.md", type: file, size: 3520b, modified: 2026-04-11T14:28:01.499597100+02:00}, + {name: "CONTRIBUTING.md", type: file, size: 18714b, modified: 2026-04-11T14:28:01.500597200+02:00}, + {name: "Cargo.lock", type: file, size: 257047b, modified: 2026-04-11T14:28:01.501597200+02:00}, + {name: "Cargo.toml", type: file, size: 11950b, modified: 2026-04-11T14:28:01.502596700+02:00}, + {name: "Cross.toml", type: file, size: 684b, modified: 2026-04-11T14:28:01.502596700+02:00}, + {name: LICENSE, type: file, size: 1115b, modified: 2026-04-11T14:28:01.502596700+02:00}, + {name: "README.md", type: file, size: 12742b, modified: 2026-04-11T14:28:01.504102900+02:00}, + {name: "SECURITY.md", type: file, size: 2710b, modified: 2026-04-11T14:28:01.504102900+02:00}, + {name: assets, type: dir, size: 0b, modified: 2026-04-11T14:28:01.512623900+02:00}, + {name: ast-grep, type: dir, size: 0b, modified: 2026-04-11T14:28:01.522645800+02:00}, + {name: benches, type: dir, size: 0b, modified: 2026-04-11T14:28:01.524151300+02:00}, + {name: "clippy.toml", type: file, size: 170b, modified: 2026-04-11T14:28:01.525159300+02:00}, + {name: crates, type: dir, size: 0b, modified: 2026-04-11T14:28:02.451098600+02:00}, + {name: devdocs, type: dir, size: 0b, modified: 2026-04-11T14:28:02.457631100+02:00}, + {name: docker, type: dir, size: 0b, modified: 2026-04-11T14:28:02.458631500+02:00}, + {name: "rust-toolchain.toml", type: file, size: 956b, modified: 2026-04-11T14:28:02.459632800+02:00}, + {name: "rustfmt.toml", type: file, size: 18b, modified: 2026-04-11T14:28:02.459632800+02:00}, + {name: scripts, type: dir, size: 0b, modified: 2026-04-11T14:28:02.466730800+02:00}, + {name: "sgconfig.yml", type: file, size: 218b, modified: 2026-04-11T14:28:02.466730800+02:00}, + {name: src, type: dir, size: 0b, modified: 2026-04-11T14:28:02.472540600+02:00}, + {name: target, type: dir, size: 0b, modified: 2026-04-11T14:30:48.430795700+02:00}, + {name: tests, type: dir, size: 0b, modified: 2026-04-11T14:28:02.629683500+02:00}, + {name: toolkit, type: dir, size: 0b, modified: 2026-04-11T14:28:02.641237300+02:00}, + {name: "toolkit.nu", type: file, size: 61b, modified: 2026-04-11T14:28:02.635231400+02:00}, + {name: "typos.toml", type: file, size: 732b, modified: 2026-04-11T14:28:02.642236500+02:00}, + {name: wix, type: dir, size: 0b, modified: 2026-04-11T14:28:02.645247500+02:00} +] +``` + +### New command `str escape-regex` + +A new command, `str escape-regex`, has been added. +It allows us to sanitize strings before inserting them into a regular-expression pattern. + +```nushell +# Check if the input matches the data exactly (not using `==` for demonstration) + +# User input used directly in a regex +def bad [str: string] { + $in like $"^($str)$" +} + +"hello" | bad ".*" # true (incorrect) + +# Escape the input before inserting it into the regex +def good [str: string] { + $in like $"^($str | str escape-regex)$" +} + +"hello" | good ".*" # false +``` + +### Add `polars selector ends-with` + +Introduces `polars selector ends-with` allowing columns to be selected by a suffix: + +```ansi +> { + "foo": ["x", "y"], + "bar": [123, 456], + "baz": [2.0, 5.5], + "zap": [false, true], +} +| polars into-df --as-columns +| polars select (polars selector ends-with z) +| polars sort-by baz +| polars collect +╭───┬──────╮ +│ # │ baz │ +├───┼──────┤ +│ 0 │ 2.00 │ +│ 1 │ 5.50 │ +╰───┴──────╯ +``` + +This is is part of an effort to add selectors available in the python API. + +### History file path can now be configured + +Nushell now supports configuring the history file path using `$env.config.history.path`. This value can be `null` or any custom location, which is particularly useful for TTY login scenarios where the `--no-history` flag cannot be used + +```bash +$env.config.history.path = null # disable history +$env.config.history.path = "/custom/history.txt" # custom location +``` + +### New experimental option `cell-path-types` + + + +Added a new experimental option named `cell-path-types` which enforces type inferencing on cell path expressions like `{foo: 1}.foo` if enabled. That means the following examples (previously caused runtime errors or ran successfully) will be rejected by the parser: + +```nushell +let foo: string = [1].0 +``` + +```nushell +mut foo = {bar: 0} +$foo.bar = 1.0 +``` + +```nushell +let foo = [1] +def bar [baz: string] { } +bar $foo.0 +``` + +### Implement selector commands for numeric types + +- Added command `polars selector numeric` to select all numeric columns. +- Added command `polars selector integer` to select all integer columns. +- Added command `polars selector signed-integer` to select signed integer columns. +- Added command `polars selector unsigned-integer` to select unsigned integer columns. +- Added command `polars selector float` to select unsigned float columns. + +### Add testbin "bins" to nushell help + +Updates the nushell command help by adding the testbin "bins" to the `nu --help` screen. Now you see this output in the `--testbin` section of the help (but colore). + +``` + --testbin + run an internal test binary (see available bins below) + Example: nu --testbin cococo + Available test bins: + chop -> With no parameters, will chop a character off the end of each line + cococo -> Cross platform echo using println!()(e.g: nu --testbin cococo a b c) + echo_env -> Echo's value of env keys from args(e.g: nu --testbin echo_env FOO BAR) + echo_env_mixed -> Mix echo of env keys from input(e.g: nu --testbin echo_env_mixed out-err FOO BAR; nu --testbin echo_env_mixed err-out FOO BAR) + echo_env_stderr -> Echo's value of env keys from args to stderr(e.g: nu --testbin echo_env_stderr FOO BAR) + echo_env_stderr_fail -> Echo's value of env keys from args to stderr, and exit with failure(e.g: nu --testbin echo_env_stderr_fail FOO BAR) + fail -> Exits with failure code , if not given, fail with code 1(e.g: nu --testbin fail 10) + iecho -> Another type of echo that outputs a parameter per line, looping infinitely(e.g: nu --testbin iecho 3) + input_bytes_length -> Prints the number of bytes received on stdin(e.g: 0x[deadbeef] | nu --testbin input_bytes_length) + meow -> Cross platform cat (open a file, print the contents) using read_to_string and println!()(e.g: nu --testbin meow file.txt) + meowb -> Cross platform cat (open a file, print the contents) using read() and write_all() / binary(e.g: nu --testbin meowb sample.db) + nonu -> Cross platform echo but concats arguments without space and NO newline(e.g: nu --testbin nonu a b c) + nu_repl -> Run a REPL with the given source lines, it must be called with `--testbin=nu_repl`, `--testbin nu_repl` will not work due to argument count logic + relay -> Relays anything received on stdin to stdout(e.g: 0x[beef] | nu --testbin relay) + repeat_bytes -> A version of repeater that can output binary data, even null bytes(e.g: nu --testbin repeat_bytes 003d9fbf 10) + repeater -> Repeat a string or char N times(e.g: nu --testbin repeater a 5) +``` + +### Add full and allow-errors flags to http head + +> TODO(changelog): distribute these + +- Add `--full` (`-f`) and `--allow-errors` (`-e`) support to `http head` for parity with other HTTP verbs. +- When `--full` is used, `http head` now returns the standard full response record (urls, headers.request, headers.response, body, status). +- When `--allow-errors` is used, `http head` no longer fails on non-2xx statuses and still exposes headers. + +### Add support for parsing `hh:mm:ss` formatted strings in `into duration` + +Add the ability to parse `h:m:s` with `into datetime` with optional .mmm for millis, .mmmmmm for micros, and .mmmmmmmmm for nanos. + +It has to be in the format of h:m:s + +```nushell +❯ "3:34" | into duration +Error: nu::shell::incorrect_value + + × Incorrect value. + ╭─[repl_entry #1:1:1] + 1 │ "3:34" | into duration + · ──┬─┬ + · │ ╰── encountered here + · ╰── invalid clock-style duration; please use hh:mm:ss (mm & ss must be < 60 and >= 0) + ╰──── +``` + +When it is, it should just work. + +```nushell +❯ "3:34:0" | into duration +3hr 34min +``` + +When minutes or seconds >= 60 there are errors + +```nushell +❯ "3:61:0" | into duration +Error: nu::shell::incorrect_value + + × Incorrect value. + ╭─[repl_entry #3:1:1] + 1 │ "3:61:0" | into duration + · ───┬──┬ + · │ ╰── encountered here + · ╰── invalid clock-style duration; please use hh:mm:ss (mm & ss must be < 60 and >= 0) + ╰──── + +❯ "3:59:60" | into duration +Error: nu::shell::incorrect_value + + × Incorrect value. + ╭─[repl_entry #4:1:1] + 1 │ "3:59:60" | into duration + · ───┬───┬ + · │ ╰── encountered here + · ╰── invalid clock-style duration; please use hh:mm:ss (mm & ss must be < 60 and >= 0) + ╰──── +``` + +Parsing h:m:s + +```nushell +❯ "16:59:58" | into duration +16hr 59min 58sec +❯ "316:59:58" | into duration +1wk 6day 4hr 59min 58sec +``` + +With 100% more optional fractional time + +```nushell +❯ "16:59:58.235" | into duration +16hr 59min 58sec 235ms +❯ "16:59:58.235123" | into duration +16hr 59min 58sec 235ms 123µs +❯ "16:59:58.235123456" | into duration +16hr 59min 58sec 235ms 123µs 456ns +❯ '2:45:31.2' | into duration +2hr 45min 31sec 200ms +❯ '2:45:31.23' | into duration +2hr 45min 31sec 230ms +❯ '2:45:31.234' | into duration +2hr 45min 31sec 234ms +❯ '2:45:31.2345' | into duration +2hr 45min 31sec 234ms 500µs +``` + +### `help` now also shows command type + +Add `command type` information to help. + +```nushell +❯ help from ini +Parse text as .ini and create table. + +Usage: + > from ini {flags} + +Flags: + -h, --help: Display the help message for this command + -q, --no-quote: Disable quote handling for values. + -e, --no-escape: Disable escape sequence handling for values. + -m, --indented-multiline-value: Allow values to continue on indented lines. + -w, --preserve-key-leading-whitespace: Preserve leading whitespace in keys. + +Command Type: + > plugin + +Input/output types: + ╭─#─┬─input──┬─output─╮ + │ 0 │ string │ record │ + ╰───┴────────┴────────╯ +``` + +closes https://github.com/nushell/nushell.github.io/issues/2138 + +### New flag `--prune` for `group-by` + +Adds `group-by --prune` to delete the column(s) used for grouping when the arguments are cell paths; closure arguments are unaffected. If pruning leaves a parent empty (e.g., due to nested columns), the parent is removed as well.` + +```nushell +> let table = [[name, meta]; [andres, {lang: rb, year: "2019"}], [jt, {lang: rs, year: "2019"}], [storm, {lang: rs, year: "2021"}], [kai, {lang: rb, year: "2021"}]] + +> $table +╭───┬────────┬─────────────────╮ +│ # │ name │ meta │ +├───┼────────┼─────────────────┤ +│ 0 │ andres │ ╭──────┬──────╮ │ +│ │ │ │ lang │ rb │ │ +│ │ │ │ year │ 2019 │ │ +│ │ │ ╰──────┴──────╯ │ +│ 1 │ jt │ ╭──────┬──────╮ │ +│ │ │ │ lang │ rs │ │ +│ │ │ │ year │ 2019 │ │ +│ │ │ ╰──────┴──────╯ │ +│ 2 │ storm │ ╭──────┬──────╮ │ +│ │ │ │ lang │ rs │ │ +│ │ │ │ year │ 2021 │ │ +│ │ │ ╰──────┴──────╯ │ +│ 3 │ kai │ ╭──────┬──────╮ │ +│ │ │ │ lang │ rb │ │ +│ │ │ │ year │ 2021 │ │ +│ │ │ ╰──────┴──────╯ │ +╰───┴────────┴─────────────────╯ +> $table | group-by meta.year --prune +╭──────┬────────────────────────────────╮ +│ │ ╭───┬────────┬───────────────╮ │ +│ 2019 │ │ # │ name │ meta │ │ +│ │ ├───┼────────┼───────────────┤ │ +│ │ │ 0 │ andres │ ╭──────┬────╮ │ │ +│ │ │ │ │ │ lang │ rb │ │ │ +│ │ │ │ │ ╰──────┴────╯ │ │ +│ │ │ 1 │ jt │ ╭──────┬────╮ │ │ +│ │ │ │ │ │ lang │ rs │ │ │ +│ │ │ │ │ ╰──────┴────╯ │ │ +│ │ ╰───┴────────┴───────────────╯ │ +│ │ ╭───┬───────┬───────────────╮ │ +│ 2021 │ │ # │ name │ meta │ │ +│ │ ├───┼───────┼───────────────┤ │ +│ │ │ 0 │ storm │ ╭──────┬────╮ │ │ +│ │ │ │ │ │ lang │ rs │ │ │ +│ │ │ │ │ ╰──────┴────╯ │ │ +│ │ │ 1 │ kai │ ╭──────┬────╮ │ │ +│ │ │ │ │ │ lang │ rb │ │ │ +│ │ │ │ │ ╰──────┴────╯ │ │ +│ │ ╰───┴───────┴───────────────╯ │ +╰──────┴────────────────────────────────╯ +> $table | group-by meta.year meta.lang --prune # also removes the parent if it's now empty +╭──────┬─────────────────────────╮ +│ │ ╭────┬────────────────╮ │ +│ 2019 │ │ │ ╭───┬────────╮ │ │ +│ │ │ rb │ │ # │ name │ │ │ +│ │ │ │ ├───┼────────┤ │ │ +│ │ │ │ │ 0 │ andres │ │ │ +│ │ │ │ ╰───┴────────╯ │ │ +│ │ │ │ ╭───┬──────╮ │ │ +│ │ │ rs │ │ # │ name │ │ │ +│ │ │ │ ├───┼──────┤ │ │ +│ │ │ │ │ 0 │ jt │ │ │ +│ │ │ │ ╰───┴──────╯ │ │ +│ │ ╰────┴────────────────╯ │ +│ │ ╭────┬───────────────╮ │ +│ 2021 │ │ │ ╭───┬───────╮ │ │ +│ │ │ rs │ │ # │ name │ │ │ +│ │ │ │ ├───┼───────┤ │ │ +│ │ │ │ │ 0 │ storm │ │ │ +│ │ │ │ ╰───┴───────╯ │ │ +│ │ │ │ ╭───┬──────╮ │ │ +│ │ │ rb │ │ # │ name │ │ │ +│ │ │ │ ├───┼──────┤ │ │ +│ │ │ │ │ 0 │ kai │ │ │ +│ │ │ │ ╰───┴──────╯ │ │ +│ │ ╰────┴───────────────╯ │ +╰──────┴─────────────────────────╯ +``` + +### New and improved `xaccess`! + +An experimental upgrade to `std/xml xaccess`, currently accessible as `std-rfc/xml xaccess`. It is completely backwards compatible, with the addition of: + +- using a `...rest` parameter, removing the need to use a list (though still supporting it). +- supporting cell-paths, rather than plain strings and ints. +- supporting `descendant-or-self::node()` (aka `//`) with `**` + +```nushell +http get 'https://www.nushell.sh/rss.xml' +| xaccess rss.**.item # grab all items +| update content { + xaccess * { $in.tag? in [title, link] } # only grab title and link +} +| first 3 +| {tag: rss, content: $in} | to xml -i 2 +``` + +```xml + + + Nushell 0.111.0 + https://www.nushell.sh/blog/2026-02-28-nushell_v0_111_0.html + + + This week in Nushell #340 + https://www.nushell.sh/blog/2026-02-27-twin0340.html + + + This week in Nushell #339 + https://www.nushell.sh/blog/2026-02-20-twin0339.html + + +``` + +### Add configurable external hinter closure + +Added support for configurable external hinter closures via `$env.config.hinter.closure`. This allows users to provide a custom closure that receives the current line, cursor position, and working directory, and returns inline hint text (like fish-style autosuggestions). Closures can return a simple string or a record `{hint: string, next_token?: string}` for custom token-based hint acceptance. + +#### Examples + +- Atuin-based hint closure + +```nu +$env.config.line_editor.external.hinter = { + enable: true + closure: {|ctx| + if ($ctx.line | str length) == 0 { + null + } else { + let candidate = (try { + ^atuin search --cwd $ctx.cwd --limit 1 --search-mode prefix --cmd-only $ctx.line + | lines + | first + } catch { + null + }) + + if $candidate == null or not ($candidate | str starts-with $ctx.line) { + null + } else { + ($candidate | str substring (($ctx.line | str length))..) + } + } + } +} +``` + +- Simple deterministic test closure (good for validating script hinter behavior) + +```nu +$env.config.line_editor.external.hinter = { + enable: true + closure: {|ctx| + if ($ctx.line | str length) == 0 { + null + } else { + let target = "zzhint from-script" + if not ($target | str starts-with $ctx.line) { + null + } else { + let remaining = ($target | str substring (($ctx.line | str length))..) + if ($remaining | str length) == 0 { null } else { $remaining } + } + } + } +} +``` + +### New `--base` flag for `url parse` + +`url parse` now supports an optional `--base/-b` flag to resolve relative URLs against a base URL (WHATWG-compatible). This makes it easier to normalize links from scraped pages while still returning the same structured URL record (scheme, host, path, query, fragment, and params). + +### MCP: Auto-promote long-running evaluations to background jobs + +Evaluations that take longer than 10 seconds, or are cancelled by the client, are automatically promoted to background jobs instead of being discarded. Their results are delivered to job 0's mailbox, where they can be retrieved using `job recv`. These promoted jobs appear in `job list` with descriptions like `mcp: `, and they can be terminated using `job kill`. The timeout for this behavior can be configured through the `$env.NU_MCP_PROMOTE_AFTER` setting. + +### New option to allow command with space prefixes to be recorded in history + +Usually commands that start with a space are not recorded to the history. +With `$env.config.history.ignore_space_prefixed` this can be changed. + +### `table` command now respects metadata of `Custom` values. + +```nushell +# before nushell didn't render the `cwd` column like paths +# now it does +history | metadata set --path-columns [cwd] | table --icons +``` + +### New configuration option `auto_cd_always` + +This release adds the configuration option `$env.config.auto_cd_implicit`, which allows auto-cd behavior as long as the command string is an existing directory. + +### Unordered `par-each` is now streaming + +Allow `par-each` to stream. The following example will print out a new value each second that passes. + +```nushell +❯ [7,8,9,10] | each {|x| sleep 1sec; $x} | par-each {|el| $el} | each {|x| print $x} +7 +8 +9 +10 +``` + +### New sigil `%` to explicitly call built-ins + +Nushell has a new sigil `%` that allows you to call a built-in even if you have the built-in shadowed by a custom command or alias. + +My fancy `ls` custom command sorts directories first. + +```nushell +❯ ls | first 5 +╭─#─┬────name─────┬─type─┬─size──┬───modified───╮ +│ 0 │  assets │ dir │ 160 │ 2 years ago │ +│ 1 │  ast-grep │ dir │ 160 │ 2 months ago │ +│ 2 │  benches │ dir │ 128 │ 2 weeks ago │ +│ 3 │  clippy │ dir │ 96 │ a year ago │ +│ 4 │  crates │ dir │ 1,472 │ 2 weeks ago │ +╰─#─┴────name─────┴─type─┴─size──┴───modified───╯ +``` + +Now you can call the built-in even if you have your built-in shadowed as above. + +```nushell +❯ %ls | first 5 +╭─#─┬─────────name──────────┬─type─┬──size───┬───modified───╮ +│ 0 │ * CITATION.cff │ file │ 812 │ 2 years ago │ +│ 1 │  CODE_OF_CONDUCT.md │ file │ 3,444 │ a year ago │ +│ 2 │  CONTRIBUTING.md │ file │ 18,387 │ 2 months ago │ +│ 3 │  Cargo.lock │ file │ 245,738 │ 2 days ago │ +│ 4 │  Cargo.toml │ file │ 11,601 │ 2 days ago │ +╰─#─┴─────────name──────────┴─type─┴──size───┴───modified───╯ +``` + +If you try to call something that doesn't exist as a built-in you get an error. + +```nushell +❯ %lss +Error: nu::parser::error + + × percent sigil requires a built-in command + ╭─[repl_entry #4:1:2] + 1 │ %lss + · ─┬─ + · ╰── unknown built-in command + ╰──── + help: remove `%` to use normal resolution, or use `^` to run an external command explicitly +``` + +### New table style `frameless` + +Add a frameless table theme. + +imagen + +### MCP: Promoted jobs now return full output + +When an MCP evaluation gets auto-promoted to a background job (after timeout or client cancellation), the mailbox payload was the potentially-truncated MCP response. If output exceeded `NU_MCP_OUTPUT_LIMIT`, `job recv` would return a dangling `$history.N` reference instead of the actual data — `$history` is only populated for non-promoted evals. + +This PR introduces an `EvalOutput` struct that separates the MCP response (possibly truncated with a `$history` note) from the full output string. Promoted jobs now send `full_output` through the mailbox so `job recv` always returns complete, usable data. + +Also fixes a pipefail issue where external commands that write to both stdout and stderr would re-raise `non_zero_exit_code` after `process_pipeline` had already captured the output — solved by calling `ignore_error(true)` on the child. + +### Other additions + +- Added `ctrl + p/n` to move up and down the input list like with `fzf`. ([#17707](https://github.com/nushell/nushell/pull/17707)) +- `hide-env` now autocompletes environment variable names when pressing tab. ([#17658](https://github.com/nushell/nushell/pull/17658)) +- Add the ability for `query web` to parse the entire html document when using the `--document` flag. ([#17759](https://github.com/nushell/nushell/pull/17759)) +- `ansi` command now has completions for its positional argument. ([#17761](https://github.com/nushell/nushell/pull/17761)) +- `into binary` now has a completion for the `--endian` flag. ([#17788](https://github.com/nushell/nushell/pull/17788)) +- `ps -l` output has two new columns: `process_group_id` and `session_id`. ([#16357](https://github.com/nushell/nushell/pull/16357)) +- Binary hex colors are now configurable with `$env.config.color_config.binary_*` and `$env.config.use_ansi_coloring`. ([#17887](https://github.com/nushell/nushell/pull/17887)) +- `metadata set --content-type` now also accepts `null` to unset the `content_type` metadata ([#17944](https://github.com/nushell/nushell/pull/17944)) +- `http get` now also automatically parses `x-`-prefixed mime types like `application/x-nuon`. ([#17967](https://github.com/nushell/nushell/pull/17967)) +- The `input list` command now streams by consuming an upstream list or range incrementally vs collecting. The responsiveness should be improved but everything _should_ still work as before. I kind of fake it by priming the list and then incrementally load things. ([#17966](https://github.com/nushell/nushell/pull/17966)) +- Refactor nu-mcp to allow for engine introspection and add more thorough testing. ([#17988](https://github.com/nushell/nushell/pull/17988)) + +## Deprecations + +### Replace `ShellError::GenericError` with `ShellError::Generic(GenericError)` + +For plugin developers: + +`ShellError::GenericError` is now deprecated, prefer to use `ShellError::Generic` instead. + +## Removals + +### Removed some deprecated commands and flags + +Command removed: + +- `random dice` in favor of `std/random dice` + +Flags removed: + +- `metadata set --merge` in favor of `metadata set { merge {key: value} }` +- `watch --debounce-ms` in favor of `watch --debounce` +- `into value --columns --prefer-filesizes` in favor of `detect type --columns --prefer-filesizes` + +`into value` no longer infer nushell datatype form string. Use `detect type` in combination with `update cells` instead. + +## Other changes + +### `$nu/$env/$in` are now more aggressively reserved + +More aggressive reserved names (`$nu/$env/$in`) exclusion in implicit variable declaration. e.g. + +```nushell +for nu: int in [] {} + +match [1, 2, 3] { [$in, $nu, $env] => { $in + $nu + $env }, _ => 0 } +``` + +On the other hand, `$it` is re-enabled in `let it = 1` or `1 | let it` + +### Improve alias expression error message to use user-friendly descriptions + +Error messages for invalid alias expressions now show user-friendly descriptions instead of internal Rust type names. The error code `nu::parser::cant_alias_expression` is unchanged. + +**Before:** + +``` + × Can't create alias to expression. + ╭─[entry #1:1:1] + 1 │ alias foo = $bar.baz + · ── aliasing FullCellPath is not supported + ╰──── + help: Only command calls can be aliased. +``` + +**After:** + +``` + × Can't create alias to expression. + ╭─[entry #1:1:1] + 1 │ alias foo = $bar.baz + · ── aliasing a cell path expression is not supported + ╰──── + help: Only command calls can be aliased. +``` + +### Update metadata handling for `skip` and `reject` command + +- `skip` command only removes `content_type` metadata if n > 0 and input is binary. +- `reject` command also removes the path from `path_columns` metadata when removing a column + +### More compact output for `to nuon --indent n` + +to `nuon --indent n` will print in a more compact output + +#### Before + +```bash +> [{column1: 1, column2: 2}, {column1: 3, column2: 4}] | to nuon --indent 2 +[ + [ + "column1", + "column2" + ]; + [ + 1, + 2 + ], + [ + 3, + 4 + ] +] +``` + +#### After + +```bash +> [{column1: 1, column2: 2}, {column1: 3, column2: 4}] | to nuon --indent 2 +[ + ["column1", "column2"]; + [1, 2], + [3, 4] +] +``` + +### Some Polars upgrades + +- Upgrades polars to 0.53. +- Reimplemented `polars pivot` command to polars' updated pivot library. Introduced support for "element" type aggregates. +- `polars unpivot` will now only work on LazyFrames. Eager dataframes will be converted to a LazyFrame. +- Added flags `--keep-nulls` and `--empty-as-null` to `polars concat`. +- Some improvements on list conversion from nushell to polars. Sub-lists should retain their type instead of being converted to type "object". Using NuDataFrame::try_from_value will convert a Value::List object directly and attempt use an appropriate DataType before falling back to "object". +- Added additional selectors: `polars selector not`, `polars selector matches`, `polars selector starts-with`. + +### Additional changes + +- Type widening now flattens a bit more. ([#17575](https://github.com/nushell/nushell/pull/17575)) +- `keybindings list` command is updated with new descriptions. `CutFromStartLinewise` / `CutToEndLinewise` now takes `keep_line` instead of `value` as its parameter for clarity. ([#17859](https://github.com/nushell/nushell/pull/17859)) +- `get` command now removes the `path_columns` metadata if none of the cell paths are a index. ([#17866](https://github.com/nushell/nushell/pull/17866)) +- Replaced `Span::unknown()` with real spans in MCP evaluation and protocol deprecation handling. MCP tool errors and deprecated flag warnings now report accurate source locations. ([#17877](https://github.com/nushell/nushell/pull/17877)) +- Replaced `Span::unknown()` with real spans across remaining nu-command files including `cal`, `to xml`, `stor insert/update`, `input list`, `du`, `ls`, `table`, `source`, `tutor`, `http`, and `url join`. Error messages from these commands now report accurate source locations. ([#17888](https://github.com/nushell/nushell/pull/17888)) +- `first` and `last` preserve pipeline metadata (such as `content_type` and `path_columns`) for list, range, and list-stream input. `content_type` is still cleared when the output is only part of a binary value (for example a single byte as an integer or a truncated binary value). ([#17875](https://github.com/nushell/nushell/pull/17875)) +- Fixed a crash (“known external name not found”) when an alias reused the same name as an extern used for completions (for example wrapping an external with default flags). ([#17878](https://github.com/nushell/nushell/pull/17878)) +- Update help text for the `--ide-*` commands in the `nu --help` screen. ([#17905](https://github.com/nushell/nushell/pull/17905)) +- `detect type` now preserves `content_type` metadata if it cannot detect the input value ([#17906](https://github.com/nushell/nushell/pull/17906)) +- Some code that was already known to be invalid early-on, will now be highlighted as an error This also fixes a discrepancy between error-highlighting of internal and external calls. ([#17917](https://github.com/nushell/nushell/pull/17917)) +- Replaced `Span::unknown()` with real spans in `nu-engine`. The help system (`get_full_help`) and IR evaluation now provide accurate source locations in error messages and highlighted output. ([#17938](https://github.com/nushell/nushell/pull/17938)) + +## Bug fixes + +### Improved robustness of plugin handling on startup + +The reason for this PR is that if you have an old version of plugins on Windows and you startup nushell, with the current main branch, nushell just exits, no warnings, not error messages, no nothing. With this PR, you now get something like this and nushell doesn't exit. + +```nushell +Error: nu::shell::plugin_failed_to_load + + × Plugin failed to load: Plugin `gstat` is compiled for nushell version 0.110.1, which is not compatible with version 0.111.1 + +Error: nu::shell::io::broken_pipe + + × I/O error + ╰─▶ × PluginWrite could not flush + + ╭──── + 1 │ crates\nu-plugin-core\src\interface\mod.rs:117:17 + · ────────────────────────┬──────────────────────── + · ╰── Broken pipe + ╰──── + +Error: nu::shell::plugin_failed_to_load + + × Plugin failed to load: Plugin `gstat` is compiled for nushell version 0.110.1, which is not compatible with version 0.111.1 +``` + +### `history` now returns date values for sqlite-based history + +Update the sqlite output of the history file by adding column adapters so we can maintain speed but still get nushell values out of the command. + +#### Before + +```nushell +❯ history | last +╭─────────────────┬────────────────────────────╮ +│ start_timestamp │ 1772317356190 │ +│ command │ history | last │ +│ cwd │ /Users/fdncred/src/nushell │ +│ duration │ │ +│ exit_status │ │ +╰─────────────────┴────────────────────────────╯ +❯ history | last 3 +╭─#─┬─start_timestamp─┬─────command──────┬────────────cwd─────────────┬─duration─┬─exit_status─╮ +│ 0 │ 1772317254249 │ exit │ /Users/fdncred/src/nushell │ │ │ +│ 1 │ 1772317356190 │ history | last │ /Users/fdncred/src/nushell │ 3 │ 0 │ +│ 2 │ 1772317382357 │ history | last 3 │ /Users/fdncred/src/nushell │ │ │ +╰───┴─────────────────┴──────────────────┴────────────────────────────┴──────────┴─────────────╯ +``` + +#### After + +```nushell +❯ history | last +╭─────────────────┬────────────────────────────╮ +│ start_timestamp │ now │ +│ command │ history | last │ +│ cwd │ /Users/fdncred/src/nushell │ +│ duration │ │ +│ exit_status │ │ +╰─────────────────┴────────────────────────────╯ +❯ history | last 3 +╭─#─┬─start_timestamp─┬─────command──────┬────────────cwd─────────────┬─duration─┬─exit_status─╮ +│ 0 │ 24 seconds ago │ exit │ /Users/fdncred/src/nushell │ │ │ +│ 1 │ now │ history | last │ /Users/fdncred/src/nushell │ 23ms │ 0 │ +│ 2 │ now │ history | last 3 │ /Users/fdncred/src/nushell │ │ │ +╰───┴─────────────────┴──────────────────┴────────────────────────────┴──────────┴─────────────╯ +``` + +### Brought back missing `--log-*` flags for nushell + +Fixes the broken nushell executable logging flags. + +Here's the new logging section. + +``` +Logging: + --log-level + log level for diagnostic logs (error, warn, info, debug, trace). Off by default + Example: nu --log-level info + --log-target + set the target for the log to output. stdout, stderr(default), mixed or file (requires --log-file) + Example: nu --log-target stdout + --log-file + specify a custom log file path (requires --log-target file and --log-level ) + Example: nu --log-target file --log-file ~/.local/share/nushell/nu.log --log-level info + --log-include + set the Rust module prefixes to include from the log output + Example: nu --log-include info + --log-exclude + set the Rust module prefixes to exclude from the log output + Example: nu --log-exclude info +``` + +### Fix confusing type mismatch error in bytes collect + +`bytes collect` now accepts table/stream input (e.g. from `each`), and type mismatch errors no longer repeat the same type multiple times. + +Two changes: + +- Added `Type::table()` to `bytes collect` input types so pipelines like `0..128 | each {} | into binary --compact | bytes collect` work without requiring an explicit `collect` first +- Deduplicated types in `combined_type_string` so error messages say "binary, table, or record" instead of "binary, binary, binary, binary, table, or record" + +### Builtin commands now support `null` for optional parameters + +Optional positional parameters in builtin commands now accept `null`, treating it as if the argument was omitted. This allows custom commands to wrap builtins and transparently forward optional parameters: + +```nushell +def wraps-first [rows?: int] { [1, 2, 3] | first $rows } +wraps-first # => 1 (previously errored) +wraps-first 2 # => [1, 2] +``` + +### finally block won't run twice if error produced in finally block + +``` +> try { +} finally { + print "inside finally" + error make +} +``` + +It prints "inside finally" once. + +### finally block won't run before try/catch finished + +``` +try { + ^ping -n 3 127.0.0.1 # or `^ping -c 3 127.0.0.1` on Linux/macOS +} finally { + print "finally ran" +} +``` + +Finally won't run before try finished. +NOTES ABOUT STREAMING: +_try_ won't streaming if `catch` or `finally` exists. +_catch_ won't streaming if `finally` exists + +### let ignores pipefail checking + +``` +> sh -c "echo 'hello\nworld' && false" | lines | let x +``` + +The variable `x` will be assigned. + +### Try doesn't produce output if it has an error + +``` +> try { bash -c 'exit 1' | is-empty } catch { 'result-on-catch' } +result-on-catch +``` + +It returns `result-on-catch`, and redundant `true` won't be returned. + +### Fixed some `into datetime` inconsistencies + +#### Before + +```nushell +> "2026-03-21_00:25" | into datetime --format "%F_%R" --timezone utc +Sat, 21 Mar 2026 00:25:00 +0100 (3 hours ago) +~> "2026-03-21_00:25" | into datetime --format "%F_%R" --timezone local +Sat, 21 Mar 2026 00:25:00 +0100 (3 hours ago) +``` + +#### After (note different timezones, example is -5) + +```nushell +❯ "2026-03-21_00:25" | into datetime --format "%F_%R" --timezone utc +Sat, 21 Mar 2026 00:25:00 +0000 (2 days ago) +❯ "2026-03-21_00:25" | into datetime --format "%F_%R" --timezone local +Sat, 21 Mar 2026 00:25:00 -0500 (2 days ago) +``` + +### Fixed argument parsing for strings non-space whitespace + +Update argument parsing to allow things like this without having an error. + +```nushell +nu test.nu a b "c\nd" +``` + +### Fixed parsing optional cell paths on literal braced values + +Nushell now correctly parses braced values followed by optional cell paths. +Expressions like `{}.foo?` are handled as expected and return null for missing fields, instead of raising an unclosed-delimiter parse error. + +### Fixed error propagation for `reject + +Fixed an error in `reject` command where an error value in the input would return `column_not_found` error instead of propagating the error. + +#### Before + +```nushell +❯ ls | insert foo { error make { msg: 'boo' } } | reject name +Error: nu::shell::column_not_found + + × Cannot find column 'name' + ╭─[repl_entry #12:1:6] + 1 │ ls | insert foo { error make { msg: 'boo' } } | reject name + · ───┬── ──┬─ + · │ ╰── cannot find column 'name' + · ╰── value originates here + ╰──── +``` + +#### After + +```nushell +❯ ls | insert foo { error make { msg: 'boo' } } | reject name +Error: nu::shell::error + + × boo + ╭─[repl_entry #1:1:31] + 1 │ ls | insert foo { error make { msg: 'boo' } } | reject name + · ────────────── + ╰──── +``` + +### Other fixes + +- Fix the problem where searching in the `explore` command was off by 1 which caused the hit to sometimes be hidden. ([#17718](https://github.com/nushell/nushell/pull/17718)) +- There were rendering bugs when the prompt was at the bottom of the screen. Removing the custom rendering helped fix the problems. ([#17691](https://github.com/nushell/nushell/pull/17691)) +- When in `explore` and `:nu` returns null, you can now `q/esc` out. ([#17661](https://github.com/nushell/nushell/pull/17661)) +- Fixed a bug where numerical keys in records mess up type inference, e.g. `let foo: string = {1: 1}` is allowed before the fix. As a side effect, previously forbidden key names, like`{1kb: 1}`, are valid now. ([#17684](https://github.com/nushell/nushell/pull/17684)) +- Nushell now resolves symlinks via `$env.PWD` if that dir is the same as `std::env::current_dir` to allow formatted paths. ([#17720](https://github.com/nushell/nushell/pull/17720)) +- Fixes a bug where creating nushell scripts with subcommands would show duplicate subcommands. ([#17727](https://github.com/nushell/nushell/pull/17727)) +- Fixed the `variable_not_found` error in scenarios with recursive functions. ([#17726](https://github.com/nushell/nushell/pull/17726)) +- Default arguments now allowed to have the same name as the parameter. ([#17697](https://github.com/nushell/nushell/pull/17697)) +- Avoid `input listen --timeout` panic from double counting. ([#17744](https://github.com/nushell/nushell/pull/17744)) +- `reject` now preserves the stream metadata. For example, `ls | reject ...[]` will keep the LS_COLORS and ansi links. ([#17775](https://github.com/nushell/nushell/pull/17775)) +- Reject format strings with tokens after ending quote. ([#17777](https://github.com/nushell/nushell/pull/17777)) +- Fixed a regression of v0.111.0 that made `http` commands not respect environment variables for proxying like `ALL_PROXY`. ([#17794](https://github.com/nushell/nushell/pull/17794)) +- Fixes an issue where read-only directories are unable to be copied due to the mode attribute being preserved by default. ([#17791](https://github.com/nushell/nushell/pull/17791)) +- Nushell now resolves library paths with user‑provided `-I` entries before the default `NU_LIB_DIRS`, fixing cases where bundled modules shadowed user scripts. `NU_LIB_DIRS` is also correctly treated as immutable at startup to avoid unexpected mutation in config or scripts. ([#17819](https://github.com/nushell/nushell/pull/17819)) +- Adds a simple check to prevent histogram output from having overlapping names when a named column is passed to the histogram. So now histograms _of_ columns named "count", "frequency" (or the frequency user-defined name), "quantile", "percentage" will have sensible output. ([#17783](https://github.com/nushell/nushell/pull/17783)) +- `group-by` now correctly groups rows when the grouper values are compound types like lists or records. Previously, grouping could collapse distinct values into the same bucket due to a lossy abbreviation of the compound key. ([#17837](https://github.com/nushell/nushell/pull/17837)) +- Fix the command `tee` truncating the input for the inner closure when the output of tee is ignored by subsequent commands. ([#17793](https://github.com/nushell/nushell/pull/17793)) +- Aligns http options with the other http verbs so flags and output shape match `http head`. ([#17841](https://github.com/nushell/nushell/pull/17841)) +- Fixed a bug of lossy parsing of unclosed subexpressions in string interpolation, e.g. `$'(foo'`, which blocks completions inside all kinds of string interpolation subexpressions. ([#17851](https://github.com/nushell/nushell/pull/17851)) +- `rm` now errors when given a symlink path with a trailing slash, preventing accidental deletion of the underlying directory. Use `rm foo-link` without the trailing slash to remove the symlink itself. ([#17847](https://github.com/nushell/nushell/pull/17847)) +- Fixed a bug of duration/filesize parsing with numbers started by `.`, e.g. `.5sec` ([#17923](https://github.com/nushell/nushell/pull/17923)) +- Make MCP more responsive in stdio mode. ([#17945](https://github.com/nushell/nushell/pull/17945)) +- Use strict comparison for float-based sorting to fix panics. ([#17930](https://github.com/nushell/nushell/pull/17930)) +- `nu --experimental-options ... script.nu` now works correctly without requiring `--` before the script path. Nushell no longer treats the script file as part of the `--experimental-options` values. ([#17943](https://github.com/nushell/nushell/pull/17943)) +- `parse` simple patterns: literal `{` via `(char lbrace)` before a `{name}` capture works now. ([#17962](https://github.com/nushell/nushell/pull/17962)) +- Fixed `input list` when stdin is redirected in Unix TTY environments. ([#17987](https://github.com/nushell/nushell/pull/17987)) + +# Notes for plugin developers + +# 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) | Kitest-based Test Harness | [#17628](https://github.com/nushell/nushell/pull/17628) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Update winresource versions | [#17702](https://github.com/nushell/nushell/pull/17702) | +| [@ChrisDenton](https://github.com/ChrisDenton) | Tests should not end cwd with a / | [#17721](https://github.com/nushell/nushell/pull/17721) | +| [@fdncred](https://github.com/fdncred) | Refactor sqlite push down and apply to (nearly) all filter commands. | [#17737](https://github.com/nushell/nushell/pull/17737) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add in-process testing with `nu_test_support::test()` | [#17733](https://github.com/nushell/nushell/pull/17733) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Moved some tests around and applied some more `nu_test_support::test` | [#17740](https://github.com/nushell/nushell/pull/17740) | +| [@Juhan280](https://github.com/Juhan280) | Two new reedline events added: `ToStart` and `ToEnd` to jump to the start/end of the buffer. | [#17747](https://github.com/nushell/nushell/pull/17747) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Use `std::panic::Location` instead of custom `Location` type | [#17748](https://github.com/nushell/nushell/pull/17748) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Update more tests and use `assert_contains()` | [#17745](https://github.com/nushell/nushell/pull/17745) | +| [@Juhan280](https://github.com/Juhan280) | _Users would not notice any difference other than that the error message when providing incorrect variant will preserve case_ | [#17749](https://github.com/nushell/nushell/pull/17749) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Added `TestResult::expect_value_eq` and provide more comprehensive errors for `test()` | [#17750](https://github.com/nushell/nushell/pull/17750) | +| [@preiter93](https://github.com/preiter93) | Bump edtui to 0.11.2 and remove workarounds | [#17752](https://github.com/nushell/nushell/pull/17752) | +| [@weirdan](https://github.com/weirdan) | `char` command now has completions for its positional argument. | [#17762](https://github.com/nushell/nushell/pull/17762) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Merge `To/FromYaml` and `To/FromYml` into one struct | [#17766](https://github.com/nushell/nushell/pull/17766) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Refactored most nested command integraiont tests in `nu-command` | [#17767](https://github.com/nushell/nushell/pull/17767) | +| [@Bahex](https://github.com/Bahex) | Make `Span`'s `Debug` impl succinct | [#17782](https://github.com/nushell/nushell/pull/17782) | +| [@Juhan280](https://github.com/Juhan280) | Update reedline to commit 5c2f105 | [#17785](https://github.com/nushell/nushell/pull/17785) | +| [@andrewgazelka](https://github.com/andrewgazelka) | Document automatic JSON parsing for HTTP commands | [#17158](https://github.com/nushell/nushell/pull/17158) | +| [@Bahex](https://github.com/Bahex) | `test_record!` macro for convenience | [#17797](https://github.com/nushell/nushell/pull/17797) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Refactor usages of `test_examples` with a centralized example testing code (except plugins) | [#17801](https://github.com/nushell/nushell/pull/17801) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Enable `env_shlvl_in_repl` and `env_shlvl_in_exec_repl` tests | [#17803](https://github.com/nushell/nushell/pull/17803) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Give `http get` command tests with socks proxy more time to execute | [#17804](https://github.com/nushell/nushell/pull/17804) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Warn on `clippy::push_format_string` | [#17805](https://github.com/nushell/nushell/pull/17805) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump `toml` crate to 1.0 | [#17813](https://github.com/nushell/nushell/pull/17813) | +| [@zhiburt](https://github.com/zhiburt) | Change width estimation in case of header_on_border | [#17812](https://github.com/nushell/nushell/pull/17812) | +| [@tauanbinato](https://github.com/tauanbinato) | N/A — type signature correction only, no behavior change. | [#17811](https://github.com/nushell/nushell/pull/17811) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Refactored more command integration tests | [#17820](https://github.com/nushell/nushell/pull/17820) | +| [@hustcer](https://github.com/hustcer) | Exclude nu-test-support for loongarch64 to avoid build error of release script | [#17821](https://github.com/nushell/nushell/pull/17821) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Warn on `clippy::needless_raw_strings` | [#17822](https://github.com/nushell/nushell/pull/17822) | +| [@Rohan5commit](https://github.com/Rohan5commit) | N/A (devdocs wording fix). | [#17818](https://github.com/nushell/nushell/pull/17818) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix clippy issues | [#17825](https://github.com/nushell/nushell/pull/17825) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Refactor more command integration tests | [#17858](https://github.com/nushell/nushell/pull/17858) | +| [@Juhan280](https://github.com/Juhan280) | Add take_metadata and with_path_columns | [#17862](https://github.com/nushell/nushell/pull/17862) | +| [@rayzeller](https://github.com/rayzeller) | Replaced `Span::unknown()` with real spans in the `which` command. Error messages from `which` now report accurate source locations. | [#17842](https://github.com/nushell/nushell/pull/17842) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `GenericError::new_internal_with_location` | [#17868](https://github.com/nushell/nushell/pull/17868) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow showing an error source for generic errors | [#17869](https://github.com/nushell/nushell/pull/17869) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `From` conversions for `ErrorSite` | [#17870](https://github.com/nushell/nushell/pull/17870) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Apply `#[doc(no_inline)]` to `prelude` modules | [#17873](https://github.com/nushell/nushell/pull/17873) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Only update PR labels on opened or ready PRs | [#17874](https://github.com/nushell/nushell/pull/17874) | +| [@rayzeller](https://github.com/rayzeller) | Replaced `Span::unknown()` with real spans in plugin crates. Plugin custom value comparison errors now report accurate source locations. | [#17871](https://github.com/nushell/nushell/pull/17871) | +| [@rayzeller](https://github.com/rayzeller) | Replaced `Span::unknown()` with real spans in nu-command filters and strings. This improves error messages by providing accurate source locations when errors occur in `uniq`, `find`, `sort`, `detect columns`, `split list`, and related commands. | [#17872](https://github.com/nushell/nushell/pull/17872) | +| [@rayzeller](https://github.com/rayzeller) | Replaced `Span::unknown()` with real spans in `nu-cli` and main binary. Interactive commands like `keybindings listen`, REPL error handling, and IDE support now provide accurate source locations in error messages. | [#17876](https://github.com/nushell/nushell/pull/17876) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Restructure `nu-test-support` crate and add lots of docs | [#17900](https://github.com/nushell/nushell/pull/17900) | +| [@Juhan280](https://github.com/Juhan280) | Deprecate `PipelineData::metadata()` | [#17891](https://github.com/nushell/nushell/pull/17891) | +| [@Juhan280](https://github.com/Juhan280) | Implement DerefMut for PipelineExecutionData | [#17909](https://github.com/nushell/nushell/pull/17909) | +| [@Juhan280](https://github.com/Juhan280) | Fix `cargo doc` warnings | [#17910](https://github.com/nushell/nushell/pull/17910) | +| [@Bahex](https://github.com/Bahex) | `http` commands' output metadata properly includes content-type | [#17899](https://github.com/nushell/nushell/pull/17899) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump `rand` and related to 0.10 | [#17929](https://github.com/nushell/nushell/pull/17929) | +| [@xtqqczze](https://github.com/xtqqczze) | Update Cargo.toml files to use workspace edition and rust-version | [#17931](https://github.com/nushell/nushell/pull/17931) | +| [@xtqqczze](https://github.com/xtqqczze) | Failed to parse manifest error | [#17950](https://github.com/nushell/nushell/pull/17950) | +| [@fdncred](https://github.com/fdncred) | Revert "detect lexer-stage errors at highlighting" | [#17955](https://github.com/nushell/nushell/pull/17955) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Streamline CI Cargo Checks | [#17954](https://github.com/nushell/nushell/pull/17954) | +| [@rayzeller](https://github.com/rayzeller) | Internal change only: test code now uses `Span::test_data()` instead of `Span::unknown()` to better distinguish test spans from genuinely unknown spans. No user-facing behavior changes. | [#17893](https://github.com/nushell/nushell/pull/17893) | +| [@rayzeller](https://github.com/rayzeller) | Replaced `Span::unknown()` with real spans in the polars plugin. DataFrame operations, type conversions, and custom value comparisons now provide accurate source locations in error messages. | [#17939](https://github.com/nushell/nushell/pull/17939) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Move conversion between `nu_json::Value` and `nu_protocol::Value` into `nu-json` | [#17980](https://github.com/nushell/nushell/pull/17980) | +| [@andrewgazelka](https://github.com/andrewgazelka) | Improve model guidance | [#17996](https://github.com/nushell/nushell/pull/17996) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Mark `CustomValue::is_iterable` as deprecated | [#18003](https://github.com/nushell/nushell/pull/18003) | +| [@sholderbach](https://github.com/sholderbach) | Fix confusing double negation with empty `else if` | [#16708](https://github.com/nushell/nushell/pull/16708) | + +# Full changelog + +| author | title | link | +| ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | +| [@0xRozier](https://github.com/0xRozier) | fix: allow passing null to optional positional params in builtin commands | [#17753](https://github.com/nushell/nushell/pull/17753) | +| [@Bahex](https://github.com/Bahex) | feat(std-rfc/xml xaccess): experimental rewrite of `std/xml xaccess` | [#16804](https://github.com/nushell/nushell/pull/16804) | +| [@Bahex](https://github.com/Bahex) | feat: make `Span`'s `Debug` impl succinct | [#17782](https://github.com/nushell/nushell/pull/17782) | +| [@Bahex](https://github.com/Bahex) | feat: `test_record!` macro for convenience | [#17797](https://github.com/nushell/nushell/pull/17797) | +| [@Bahex](https://github.com/Bahex) | fix(`test_record!`): specify `$crate::record!` | [#17848](https://github.com/nushell/nushell/pull/17848) | +| [@Bahex](https://github.com/Bahex) | `http` commands' output metadata properly includes content-type | [#17899](https://github.com/nushell/nushell/pull/17899) | +| [@Benjas333](https://github.com/Benjas333) | Add frameless table theme | [#17993](https://github.com/nushell/nushell/pull/17993) | +| [@Bortlesboat](https://github.com/Bortlesboat) | Fix confusing type mismatch error in bytes collect | [#17746](https://github.com/nushell/nushell/pull/17746) | +| [@ChrisDenton](https://github.com/ChrisDenton) | Prefer PWD over current_dir if they're the same directory | [#17720](https://github.com/nushell/nushell/pull/17720) | +| [@ChrisDenton](https://github.com/ChrisDenton) | Fix: Tests should not end cwd with a / | [#17721](https://github.com/nushell/nushell/pull/17721) | +| [@CloveSVG](https://github.com/CloveSVG) | fix(parser): improve alias expression error message to use user-friendly descriptions | [#17751](https://github.com/nushell/nushell/pull/17751) | +| [@Dexterity104](https://github.com/Dexterity104) | fix(parse): support char lbrace before trailing capture | [#17962](https://github.com/nushell/nushell/pull/17962) | +| [@Juhan280](https://github.com/Juhan280) | feat: add `str escape-regex` | [#17703](https://github.com/nushell/nushell/pull/17703) | +| [@Juhan280](https://github.com/Juhan280) | Add `metadata_ref` and `metadata_mut` methods to `PipelineData` | [#17706](https://github.com/nushell/nushell/pull/17706) | +| [@Juhan280](https://github.com/Juhan280) | refactor!: remove deprecated commands and flags | [#17731](https://github.com/nushell/nushell/pull/17731) | +| [@Juhan280](https://github.com/Juhan280) | feat: add ToStart/ToEnd reedline events | [#17747](https://github.com/nushell/nushell/pull/17747) | +| [@Juhan280](https://github.com/Juhan280) | refactor: move the display logic for `ReedlineEvent` and `EditCommand` to nushell | [#17749](https://github.com/nushell/nushell/pull/17749) | +| [@Juhan280](https://github.com/Juhan280) | update reedline to commit 5c2f105 | [#17785](https://github.com/nushell/nushell/pull/17785) | +| [@Juhan280](https://github.com/Juhan280) | Update the names in `keybindings list` | [#17859](https://github.com/nushell/nushell/pull/17859) | +| [@Juhan280](https://github.com/Juhan280) | nu-protocol: add take_metadata and with_path_columns | [#17862](https://github.com/nushell/nushell/pull/17862) | +| [@Juhan280](https://github.com/Juhan280) | Update metadata handling for `get` command | [#17866](https://github.com/nushell/nushell/pull/17866) | +| [@Juhan280](https://github.com/Juhan280) | Update metadata handling for `skip` and `reject` command | [#17867](https://github.com/nushell/nushell/pull/17867) | +| [@Juhan280](https://github.com/Juhan280) | Deprecate `PipelineData::metadata()` | [#17891](https://github.com/nushell/nushell/pull/17891) | +| [@Juhan280](https://github.com/Juhan280) | build: fix cross compilation to/from windows | [#17894](https://github.com/nushell/nushell/pull/17894) | +| [@Juhan280](https://github.com/Juhan280) | Preserve pipeline metadata if detect type cannot determine the input | [#17906](https://github.com/nushell/nushell/pull/17906) | +| [@Juhan280](https://github.com/Juhan280) | nu-protocol: Implement DerefMut for PipelineExecutionData | [#17909](https://github.com/nushell/nushell/pull/17909) | +| [@Juhan280](https://github.com/Juhan280) | doc: fix `cargo doc` warnings | [#17910](https://github.com/nushell/nushell/pull/17910) | +| [@Juhan280](https://github.com/Juhan280) | fix: preserve metadata when rendering `Custom` value in `table` command | [#17911](https://github.com/nushell/nushell/pull/17911) | +| [@Juhan280](https://github.com/Juhan280) | Allow `--content-type` to accept `null` in `metadata set` | [#17944](https://github.com/nushell/nushell/pull/17944) | +| [@Juhan280](https://github.com/Juhan280) | fix(nu-command/reject): make `reject` command forward error value properly | [#17961](https://github.com/nushell/nushell/pull/17961) | +| [@Juhan280](https://github.com/Juhan280) | refactor(nu-command): update tests for `reject` command | [#17968](https://github.com/nushell/nushell/pull/17968) | +| [@Juhan280](https://github.com/Juhan280) | Add rustfmt.toml | [#17995](https://github.com/nushell/nushell/pull/17995) | +| [@Moayad717](https://github.com/Moayad717) | Fix rm symlink trailing slash | [#17847](https://github.com/nushell/nushell/pull/17847) | +| [@Rohan5commit](https://github.com/Rohan5commit) | docs: fix devdocs wording | [#17818](https://github.com/nushell/nushell/pull/17818) | +| [@Rohan5commit](https://github.com/Rohan5commit) | docs: fix typo in completer comment | [#17904](https://github.com/nushell/nushell/pull/17904) | +| [@Rohan5commit](https://github.com/Rohan5commit) | docs: fix typo in flags section comment | [#17915](https://github.com/nushell/nushell/pull/17915) | +| [@Tyarel8](https://github.com/Tyarel8) | feat(`input list`): add ctrl+p/n to go up/down | [#17707](https://github.com/nushell/nushell/pull/17707) | +| [@WindSoilder](https://github.com/WindSoilder) | pipefail: avoid `try` outputs value when `catch` exists, avoid `finally` runs twice, avoid `finally` funs before `try` finish. | [#17764](https://github.com/nushell/nushell/pull/17764) | +| [@WookiesRpeople2](https://github.com/WookiesRpeople2) | chore: Update to noun output to be more compact when `--indent n` is used | [#17928](https://github.com/nushell/nushell/pull/17928) | +| [@amaanq](https://github.com/amaanq) | cli: add hide-env autocompletion | [#17658](https://github.com/nushell/nushell/pull/17658) | +| [@andrewgazelka](https://github.com/andrewgazelka) | docs(mcp): document automatic JSON parsing for HTTP commands | [#17158](https://github.com/nushell/nushell/pull/17158) | +| [@andrewgazelka](https://github.com/andrewgazelka) | feat(mcp): auto-promote long-running evaluations to background jobs | [#17861](https://github.com/nushell/nushell/pull/17861) | +| [@andrewgazelka](https://github.com/andrewgazelka) | fix(nu-mcp): deliver full output for promoted background jobs | [#17989](https://github.com/nushell/nushell/pull/17989) | +| [@andrewgazelka](https://github.com/andrewgazelka) | Improve model guidance | [#17996](https://github.com/nushell/nushell/pull/17996) | +| [@app/](https://github.com/app/) | Add cross-shell search terms to 16 commands (bash/CMD/PowerShell) | [#17844](https://github.com/nushell/nushell/pull/17844) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump calamine from 0.32.0 to 0.33.0 | [#17647](https://github.com/nushell/nushell/pull/17647) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump actions/upload-artifact from 6 to 7 | [#17710](https://github.com/nushell/nushell/pull/17710) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.43.5 to 1.44.0 | [#17711](https://github.com/nushell/nushell/pull/17711) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump interprocess from 2.3.1 to 2.4.0 | [#17713](https://github.com/nushell/nushell/pull/17713) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump quickcheck_macros from 1.1.0 to 1.2.0 | [#17771](https://github.com/nushell/nushell/pull/17771) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump calamine from 0.33.0 to 0.34.0 | [#17772](https://github.com/nushell/nushell/pull/17772) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump sqlparser from 0.60.0 to 0.61.0 | [#17774](https://github.com/nushell/nushell/pull/17774) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump scraper from 0.25.0 to 0.26.0 | [#17830](https://github.com/nushell/nushell/pull/17830) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump winreg from 0.55.0 to 0.56.0 | [#17831](https://github.com/nushell/nushell/pull/17831) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump ureq from 3.2.0 to 3.3.0 | [#17879](https://github.com/nushell/nushell/pull/17879) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump toml from 1.0.6+spec-1.1.0 to 1.0.7+spec-1.1.0 | [#17883](https://github.com/nushell/nushell/pull/17883) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump uuid from 1.22.0 to 1.23.0 | [#17946](https://github.com/nushell/nushell/pull/17946) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump unicode-segmentation from 1.12.0 to 1.13.2 | [#17949](https://github.com/nushell/nushell/pull/17949) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump crate-ci/typos from 1.44.0 to 1.45.0 | [#17997](https://github.com/nushell/nushell/pull/17997) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump tokio from 1.50.0 to 1.51.0 | [#17998](https://github.com/nushell/nushell/pull/17998) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump similar from 2.7.0 to 3.0.0 | [#17999](https://github.com/nushell/nushell/pull/17999) | +| [@app/dependabot](https://github.com/app/dependabot) | build(deps): bump tempfile from 3.25.0 to 3.27.0 | [#18000](https://github.com/nushell/nushell/pull/18000) | +| [@ayax79](https://github.com/ayax79) | Polars upgrade | [#17641](https://github.com/nushell/nushell/pull/17641) | +| [@ayax79](https://github.com/ayax79) | Polars: added `polars selector ends-with` | [#17722](https://github.com/nushell/nushell/pull/17722) | +| [@ayax79](https://github.com/ayax79) | Polars: Implement selector commands for numeric types | [#17723](https://github.com/nushell/nushell/pull/17723) | +| [@blackhat-hemsworth](https://github.com/blackhat-hemsworth) | Add a check to avoid duplicate histogram output column names | [#17783](https://github.com/nushell/nushell/pull/17783) | +| [@blindFS](https://github.com/blindFS) | feat!(parser): type inference following cell paths | [#17673](https://github.com/nushell/nushell/pull/17673) | +| [@blindFS](https://github.com/blindFS) | fix(parser): record keys parsed as strings | [#17684](https://github.com/nushell/nushell/pull/17684) | +| [@blindFS](https://github.com/blindFS) | fix!: respect `reorder-cell-paths` option in assignments | [#17696](https://github.com/nushell/nushell/pull/17696) | +| [@blindFS](https://github.com/blindFS) | refactor!(parser): move reserved variable name checking near `is_variable` and `add_variable` | [#17741](https://github.com/nushell/nushell/pull/17741) | +| [@blindFS](https://github.com/blindFS) | fix(parser): string interpolation with unclosed `)` | [#17851](https://github.com/nushell/nushell/pull/17851) | +| [@blindFS](https://github.com/blindFS) | fix(parser): do not check for reserved variable names in external signature | [#17903](https://github.com/nushell/nushell/pull/17903) | +| [@blindFS](https://github.com/blindFS) | fix(parser): an edge case of parse_unit_value | [#17923](https://github.com/nushell/nushell/pull/17923) | +| [@blindFS](https://github.com/blindFS) | revert: allow default values in external signatures | [#17974](https://github.com/nushell/nushell/pull/17974) | +| [@cmtm](https://github.com/cmtm) | Add process_group_id and session_id to `ps -l` output | [#16357](https://github.com/nushell/nushell/pull/16357) | +| [@coravacav](https://github.com/coravacav) | fix(input listen): calculate timeout using elapsed start time rather than subtraction | [#17744](https://github.com/nushell/nushell/pull/17744) | +| [@cosineblast](https://github.com/cosineblast) | Reword job tag to job describe | [#17496](https://github.com/nushell/nushell/pull/17496) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Kitest-based Test Harness | [#17628](https://github.com/nushell/nushell/pull/17628) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump patch after release | [#17682](https://github.com/nushell/nushell/pull/17682) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Update winresource versions | [#17702](https://github.com/nushell/nushell/pull/17702) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump kitest & remove `RefUnwindSafe` from experimental option markers | [#17716](https://github.com/nushell/nushell/pull/17716) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add in-process testing with `nu_test_support::test()` | [#17733](https://github.com/nushell/nushell/pull/17733) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command/tests): moved some tests around and applied some more `nu_test_support::test` | [#17740](https://github.com/nushell/nushell/pull/17740) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump aws related crates | [#17742](https://github.com/nushell/nushell/pull/17742) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command/tests): update more tests and use `assert_contains()` | [#17745](https://github.com/nushell/nushell/pull/17745) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor: use `std::panic::Location` instead of custom `Location` type | [#17748](https://github.com/nushell/nushell/pull/17748) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(testing): Added `TestResult::expect_value_eq` and provide more comprehensive errors for `test()` | [#17750](https://github.com/nushell/nushell/pull/17750) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump some packages to handle security issues | [#17765](https://github.com/nushell/nushell/pull/17765) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command): Merge `To/FromYaml` and `To/FromYml` into one struct | [#17766](https://github.com/nushell/nushell/pull/17766) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command/testing): Refactored most nested command integraiont tests in `nu-command` | [#17767](https://github.com/nushell/nushell/pull/17767) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix `http` not respecting proxy environment variables like `ALL_PROXY` | [#17794](https://github.com/nushell/nushell/pull/17794) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Refactor usages of `test_examples` with a centralized example testing code (except plugins) | [#17801](https://github.com/nushell/nushell/pull/17801) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Enable `env_shlvl_in_repl` and `env_shlvl_in_exec_repl` tests | [#17803](https://github.com/nushell/nushell/pull/17803) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Give `http get` command tests with socks proxy more time to execute | [#17804](https://github.com/nushell/nushell/pull/17804) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Warn on `clippy::push_format_string` | [#17805](https://github.com/nushell/nushell/pull/17805) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump `toml` crate to 1.0 | [#17813](https://github.com/nushell/nushell/pull/17813) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command/tests): Refactored more command integration tests | [#17820](https://github.com/nushell/nushell/pull/17820) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Warn on `clippy::needless_raw_strings` | [#17822](https://github.com/nushell/nushell/pull/17822) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Fix clippy issues | [#17825](https://github.com/nushell/nushell/pull/17825) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Apply security updates | [#17852](https://github.com/nushell/nushell/pull/17852) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-command/testing): refactor more command integration tests | [#17858](https://github.com/nushell/nushell/pull/17858) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | refactor(nu-protocol): Replace `ShellError::GenericError` with `ShellError::Generic(GenericError)` | [#17864](https://github.com/nushell/nushell/pull/17864) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `GenericError::new_internal_with_location` | [#17868](https://github.com/nushell/nushell/pull/17868) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Allow showing an error source for generic errors | [#17869](https://github.com/nushell/nushell/pull/17869) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `From` conversions for `ErrorSite` | [#17870](https://github.com/nushell/nushell/pull/17870) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Apply `#[doc(no_inline)]` to `prelude` modules | [#17873](https://github.com/nushell/nushell/pull/17873) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Only update PR labels on opened or ready PRs | [#17874](https://github.com/nushell/nushell/pull/17874) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Restructure `nu-test-support` crate and add lots of docs | [#17900](https://github.com/nushell/nushell/pull/17900) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Add `test_cell_path!()` macro | [#17927](https://github.com/nushell/nushell/pull/17927) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Bump `rand` and related to 0.10 | [#17929](https://github.com/nushell/nushell/pull/17929) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Streamline CI Cargo Checks | [#17954](https://github.com/nushell/nushell/pull/17954) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Move conversion between `nu_json::Value` and `nu_protocol::Value` into `nu-json` | [#17980](https://github.com/nushell/nushell/pull/17980) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Let `random choice` behave like `first` | [#17983](https://github.com/nushell/nushell/pull/17983) | +| [@cptpiepmatz](https://github.com/cptpiepmatz) | Mark `CustomValue::is_iterable` as deprecated | [#18003](https://github.com/nushell/nushell/pull/18003) | +| [@dxrcy](https://github.com/dxrcy) | feat: add `config.auto_cd_always` option | [#17651](https://github.com/nushell/nushell/pull/17651) | +| [@fdncred](https://github.com/fdncred) | fix type widening for `describe` | [#17575](https://github.com/nushell/nushell/pull/17575) | +| [@fdncred](https://github.com/fdncred) | Add support for `list-of-records` serialization in `to nuon` command | [#17660](https://github.com/nushell/nushell/pull/17660) | +| [@fdncred](https://github.com/fdncred) | allow `esc` on `:nu` when having `null` response | [#17661](https://github.com/nushell/nushell/pull/17661) | +| [@fdncred](https://github.com/fdncred) | update the sqlite history timestamp and duration with nushell values | [#17680](https://github.com/nushell/nushell/pull/17680) | +| [@fdncred](https://github.com/fdncred) | fix one-off up/down arrow wrapping bug | [#17691](https://github.com/nushell/nushell/pull/17691) | +| [@fdncred](https://github.com/fdncred) | remove bad `which` test, create better one | [#17692](https://github.com/nushell/nushell/pull/17692) | +| [@fdncred](https://github.com/fdncred) | revert 17606 make plugin handling more robust on startup | [#17699](https://github.com/nushell/nushell/pull/17699) | +| [@fdncred](https://github.com/fdncred) | fix the off-by-1 jump scrolling in `explore` when searching | [#17718](https://github.com/nushell/nushell/pull/17718) | +| [@fdncred](https://github.com/fdncred) | fix duplicate custom commands from showing up | [#17727](https://github.com/nushell/nushell/pull/17727) | +| [@fdncred](https://github.com/fdncred) | Add testbin "bins" to nushell help | [#17728](https://github.com/nushell/nushell/pull/17728) | +| [@fdncred](https://github.com/fdncred) | fix re-add support for custom log file path and validation in CLI | [#17732](https://github.com/nushell/nushell/pull/17732) | +| [@fdncred](https://github.com/fdncred) | chore: update Rust version to 1.92.0 and fix clippy warnings in configuration | [#17734](https://github.com/nushell/nushell/pull/17734) | +| [@fdncred](https://github.com/fdncred) | Fix select pushdown column aliasing | [#17737](https://github.com/nushell/nushell/pull/17737) | +| [@fdncred](https://github.com/fdncred) | feat(query_web): add 'document' flag to parse HTML as a full document | [#17759](https://github.com/nushell/nushell/pull/17759) | +| [@fdncred](https://github.com/fdncred) | chore(deps): update dependencies and improve compatibility | [#17779](https://github.com/nushell/nushell/pull/17779) | +| [@fdncred](https://github.com/fdncred) | feat(duration): add support for parsing `hh:mm:ss` formatted strings in `into duration` | [#17781](https://github.com/nushell/nushell/pull/17781) | +| [@fdncred](https://github.com/fdncred) | docs: update command docs to include command type | [#17800](https://github.com/nushell/nushell/pull/17800) | +| [@fdncred](https://github.com/fdncred) | Swap order of user and default library directories, ensure $NU_LIB_DIRS is const | [#17819](https://github.com/nushell/nushell/pull/17819) | +| [@fdncred](https://github.com/fdncred) | feat: enhance script argument parsing to handle newlines and whitespace correctly | [#17826](https://github.com/nushell/nushell/pull/17826) | +| [@fdncred](https://github.com/fdncred) | Upgrade `glob` to use the latest wax crate version 0.7.0 | [#17835](https://github.com/nushell/nushell/pull/17835) | +| [@fdncred](https://github.com/fdncred) | upgrade rmcp to version 1.2.0 | [#17836](https://github.com/nushell/nushell/pull/17836) | +| [@fdncred](https://github.com/fdncred) | fix(datetime): enhance timezone and offset handling in datetime parsing | [#17855](https://github.com/nushell/nushell/pull/17855) | +| [@fdncred](https://github.com/fdncred) | allow par-each to stream except with --keep-order via mspc | [#17884](https://github.com/nushell/nushell/pull/17884) | +| [@fdncred](https://github.com/fdncred) | Refactor error handling for directory removal in rm command | [#17895](https://github.com/nushell/nushell/pull/17895) | +| [@fdncred](https://github.com/fdncred) | Update IDE help text to specify cursor position and file context | [#17905](https://github.com/nushell/nushell/pull/17905) | +| [@fdncred](https://github.com/fdncred) | Update rmcp to version 1.3.0 and adjust session manager configuration | [#17912](https://github.com/nushell/nushell/pull/17912) | +| [@fdncred](https://github.com/fdncred) | feat: add `from md` command to convert markdown text into structured data | [#17937](https://github.com/nushell/nushell/pull/17937) | +| [@fdncred](https://github.com/fdncred) | fix: enhance MCP mode handling and output behavior across commands | [#17945](https://github.com/nushell/nushell/pull/17945) | +| [@fdncred](https://github.com/fdncred) | Revert "detect lexer-stage errors at highlighting" | [#17955](https://github.com/nushell/nushell/pull/17955) | +| [@fdncred](https://github.com/fdncred) | add a new sigil `%` for built-ins like `^` is a sigil for externals | [#17956](https://github.com/nushell/nushell/pull/17956) | +| [@fdncred](https://github.com/fdncred) | feat(input): make input list streamable | [#17966](https://github.com/nushell/nushell/pull/17966) | +| [@fdncred](https://github.com/fdncred) | refactor(parser): consolidate span adjustment for external calls | [#17978](https://github.com/nushell/nushell/pull/17978) | +| [@fdncred](https://github.com/fdncred) | fix(help): enhance help command to prefer built-in help over aliases | [#17979](https://github.com/nushell/nushell/pull/17979) | +| [@fdncred](https://github.com/fdncred) | refactor some commands and add tests | [#17988](https://github.com/nushell/nushell/pull/17988) | +| [@fdncred](https://github.com/fdncred) | deps: bump uu\_\* packages to 0.8.0 | [#17994](https://github.com/nushell/nushell/pull/17994) | +| [@galuszkak](https://github.com/galuszkak) | use strict comparison for float sorting to avoid panics - fixes #16750 | [#17930](https://github.com/nushell/nushell/pull/17930) | +| [@guluo2016](https://github.com/guluo2016) | Add option to save leading-space commands to history.txt | [#17350](https://github.com/nushell/nushell/pull/17350) | +| [@hustcer](https://github.com/hustcer) | Exclude nu-test-support for loongarch64 to avoid build error of release script | [#17821](https://github.com/nushell/nushell/pull/17821) | +| [@hustcer](https://github.com/hustcer) | Fix parser scope leak in where $cond | [#17976](https://github.com/nushell/nushell/pull/17976) | +| [@hustcer](https://github.com/hustcer) | Fix `input list` when stdin is redirected in Unix TTY environments | [#17987](https://github.com/nushell/nushell/pull/17987) | +| [@ian-h-chamberlain](https://github.com/ian-h-chamberlain) | Customize binary hex styles with color_config | [#17887](https://github.com/nushell/nushell/pull/17887) | +| [@kiannidev](https://github.com/kiannidev) | Add full and allow-errors flags to http head | [#17650](https://github.com/nushell/nushell/pull/17650) | +| [@kx0101](https://github.com/kx0101) | feat: add support for custom history file path in config | [#17425](https://github.com/nushell/nushell/pull/17425) | +| [@musicinmybrain](https://github.com/musicinmybrain) | Update lscolors from 0.20 to 0.21 | [#17832](https://github.com/nushell/nushell/pull/17832) | +| [@niklasmarderx](https://github.com/niklasmarderx) | fix(http): handle x- vendor prefix in Content-Type for automatic parsing | [#17967](https://github.com/nushell/nushell/pull/17967) | +| [@pickx](https://github.com/pickx) | fix: reject format strings with tokens after ending quote | [#17777](https://github.com/nushell/nushell/pull/17777) | +| [@pickx](https://github.com/pickx) | feat: `group-by` flag to delete column after grouping by it | [#17787](https://github.com/nushell/nushell/pull/17787) | +| [@pickx](https://github.com/pickx) | detect lexer-stage errors at highlighting | [#17917](https://github.com/nushell/nushell/pull/17917) | +| [@preiter93](https://github.com/preiter93) | refactor(nu-explore): bump edtui to 0.11.2 and remove workarounds | [#17752](https://github.com/nushell/nushell/pull/17752) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in which\_.rs | [#17842](https://github.com/nushell/nushell/pull/17842) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in plugin crates | [#17871](https://github.com/nushell/nushell/pull/17871) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in nu-command filters and strings | [#17872](https://github.com/nushell/nushell/pull/17872) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in nu-cli and main | [#17876](https://github.com/nushell/nushell/pull/17876) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in nu-protocol and nu-mcp | [#17877](https://github.com/nushell/nushell/pull/17877) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in remaining nu-command files | [#17888](https://github.com/nushell/nushell/pull/17888) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with Span::test_data() in test code | [#17893](https://github.com/nushell/nushell/pull/17893) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in nu-engine | [#17938](https://github.com/nushell/nushell/pull/17938) | +| [@rayzeller](https://github.com/rayzeller) | Replace Span::unknown() with real spans in nu_plugin_polars | [#17939](https://github.com/nushell/nushell/pull/17939) | +| [@rbran](https://github.com/rbran) | fix tee truncating input for inner closure if output is ignored | [#17793](https://github.com/nushell/nushell/pull/17793) | +| [@seroperson](https://github.com/seroperson) | fix: allow default argument to have the same name as parameter | [#17697](https://github.com/nushell/nushell/pull/17697) | +| [@seroperson](https://github.com/seroperson) | fix: block captures redundant variables | [#17726](https://github.com/nushell/nushell/pull/17726) | +| [@sholderbach](https://github.com/sholderbach) | Fix confusing double negation with empty `else if` | [#16708](https://github.com/nushell/nushell/pull/16708) | +| [@smartcoder0777](https://github.com/smartcoder0777) | feat(url): add --base support to url parse | [#17833](https://github.com/nushell/nushell/pull/17833) | +| [@smartcoder0777](https://github.com/smartcoder0777) | fix(group-by): correct grouping for lists/records | [#17837](https://github.com/nushell/nushell/pull/17837) | +| [@smartcoder0777](https://github.com/smartcoder0777) | fix http head http options missing full and allow error | [#17841](https://github.com/nushell/nushell/pull/17841) | +| [@smartcoder0777](https://github.com/smartcoder0777) | Preserve pipeline metadata in first and last for list/range streams | [#17875](https://github.com/nushell/nushell/pull/17875) | +| [@smartcoder0777](https://github.com/smartcoder0777) | Fix known external name lookup under alias shadowing | [#17878](https://github.com/nushell/nushell/pull/17878) | +| [@smartcoder0777](https://github.com/smartcoder0777) | Fix parsing of braced-value optional cell paths | [#17897](https://github.com/nushell/nushell/pull/17897) | +| [@smartcoder0777](https://github.com/smartcoder0777) | Fix experimental-options consuming script path | [#17943](https://github.com/nushell/nushell/pull/17943) | +| [@stuartcarnie](https://github.com/stuartcarnie) | feat(repl): add configurable external hinter closure | [#17566](https://github.com/nushell/nushell/pull/17566) | +| [@tauanbinato](https://github.com/tauanbinato) | Fix `hash md5` and `hash sha256` output type signatures | [#17811](https://github.com/nushell/nushell/pull/17811) | +| [@weirdan](https://github.com/weirdan) | `ansi` completions | [#17761](https://github.com/nushell/nushell/pull/17761) | +| [@weirdan](https://github.com/weirdan) | `char` completions | [#17762](https://github.com/nushell/nushell/pull/17762) | +| [@weirdan](https://github.com/weirdan) | `reject`: preserve metadata | [#17775](https://github.com/nushell/nushell/pull/17775) | +| [@weirdan](https://github.com/weirdan) | Completions for `into binary --endian` | [#17788](https://github.com/nushell/nushell/pull/17788) | +| [@xtqqczze](https://github.com/xtqqczze) | fix: update Cargo.toml files to use workspace edition and rust-version | [#17931](https://github.com/nushell/nushell/pull/17931) | +| [@xtqqczze](https://github.com/xtqqczze) | fix: failed to parse manifest error | [#17950](https://github.com/nushell/nushell/pull/17950) | +| [@xtqqczze](https://github.com/xtqqczze) | deps: update git2 minimum to 0.20.4 | [#17984](https://github.com/nushell/nushell/pull/17984) | +| [@ymcx](https://github.com/ymcx) | Drop mode preservation in order to fix copying of read-only directories | [#17791](https://github.com/nushell/nushell/pull/17791) | +| [@ysthakur](https://github.com/ysthakur) | Bump reedline to latest main | [#17834](https://github.com/nushell/nushell/pull/17834) | +| [@zhiburt](https://github.com/zhiburt) | nu-table: Change width estimation in case of header_on_border | [#17812](https://github.com/nushell/nushell/pull/17812) |