### Apache Airflow version

main (development)

### What happened

asset compilation background thread is not killed when running `stop_airflow`  or `breeze stop`.

Webpack process takes a lot of memory, each `start-airflow` starts 4-5 of them.

After a few breeze start, we end up with 15+ webpack background processes that takes more than 20G RAM

### What you think should happen instead

`run_compile_www_assets` should stop when running `stop_airflow` from tmux. It looks like it spawn a `compile-www-assets-dev` pre-commit in a subprocess, that doesn't get killed when stopping breeze

### How to reproduce

```
breeze start-airflow --backend postgres --python 3.8 --dev-mode
# Wait for tmux session to start
breeze_stop

breeze start-airflow --backend postgres --python 3.8 --dev-mode
# Wait for tmux session to start
breeze_stop

# do a couple more if needed
```

Open tmux and monitor your memory, and specifically webpack processes.

### Operating System

Ubuntu 20.04.6 LTS

### Versions of Apache Airflow Providers

_No response_

### Deployment

Other

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

WWW_ASSET_OUT_DEV_MODE_FILE,
    WWW_ASSET_OUT_FILE,
)
from airflow_breeze.utils.shared_options import get_dry_run, get_verbose
RunCommandResult = Union[subprocess.CompletedProcess, subprocess.CalledProcessError]
OPTION_MATCHER = re.compile(r"^[A-Z_]*=.*$")
def run_command(
    cmd: list[str],
    title: str | None = None,
    *,
    check: bool = True,
    no_output_dump_on_exception: bool = False,
    env: Mapping[str, str] | None = None,
    cwd: Path | str | None = None,
    input: str | None = None,
    output: Output | None = None,
    output_outside_the_group: bool = False,
    verbose_override: bool | None = None,
    dry_run_override: bool | None = None,
    **kwargs,
) -> RunCommandResult:
    """
    Runs command passed as list of strings with some extra functionality over POpen (kwargs from PoPen can
    be used in this command even if not explicitly specified).
    It prints diagnostics when requested, also allows to "dry_run" the commands rather than actually
    execute them.
    An important factor for having this command running tool is to be able (in verbose mode) to directly
    copy&paste the verbose output and run the command manually - including all the environment variables
    needed to run the command.
    :param cmd: command to run