From 86af8d68c16d49655850d13154594a5aa0d68122 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Sun, 1 Feb 2026 13:39:39 +0100
Subject: [PATCH 1/3] doc(proposal): un/break `--test`
---
proposals/proposal - unbreak test cli arg.md | 250 +++++++++++++++++++
1 file changed, 250 insertions(+)
create mode 100644 proposals/proposal - unbreak test cli arg.md
diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md
new file mode 100644
index 0000000..227e888
--- /dev/null
+++ b/proposals/proposal - unbreak test cli arg.md
@@ -0,0 +1,250 @@
+# Proposal: un/break `--test`
+
+Currently, this flag's behaviour is very unexpected, often resulting in silent-failure footguns, and precludes command nesting, as demonstrated in a very simple and typical CI setup:
+
+```yaml title="unit & e2e tests"
+- name: tests with coverage
+ run: node --run test -- --test-reporter lcov
+```
+
+That results in
+
+```sh
+node --test --test-reporter lcov
+```
+
+In most cases, `--test-reporter` gets lost (the `lcov` reporter is not enabled); in a worse case, this unexpectedly causes tests within a directory named `lcov` to be run.
+
+## More info
+
+Currently (since always):
+
+`--test` receives everything after it (space-delimited).
+
+`--test` currently does 2 things:
+
+* enables the test runner
+* accepts paths for the runner to consume
+
+This is similar to another existing feature with which we want to improve interop: `watch` mode.
+
+`--watch` currently does 2 things:
+
+* enables `watch` mode
+* optionally accepts 1 value to override the entrypoint
+
+```sh
+node
+ --watch
+ --watch-path ./src/**/*.ts
+ --watch-path ./test/**/*.ts
+```
+
+## Proposed options
+
+### Option: Break all the things
+
+Currently `watch` has 2 flags (which are redundant):
+
+```sh title='reads "main" etc from package.json'
+node --watch
+```
+```sh
+node --watch ./src/not-pjson-main.js
+```
+```sh
+node
+ --watch ./src/not-pjson-main.js
+ --watch-path ./src/**/*.js
+```
+
+This could be simplified into just 1 `--watch` flag (where the default value is a single-element array of the derived entrypoint).
+
+```sh title='reads "main" etc from package.json'
+node --watch
+```
+```sh title='override derived entrypoint'
+node --watch ./src/not-pjson-main.js
+```
+```sh title='package.json "main" + an additional path'
+node --watch ./src/**/*.js
+```
+```sh title='explicit entrypoint + additional paths'
+node
+ --watch ./assets/**
+ --watch ./src/**/*.js
+ ./src/not-pjson-main.js
+```
+
+An explicit entrypoint, like all node commands, must come last and must be a relative or absolute path (not a glob/pattern).
+
+`test` would then work the same way:
+
+```sh title='reads "main" etc from package.json'
+node --test
+```
+```sh title='package.json "main" + an additional path'
+node --test ./src/**/*.test.js
+```
+```sh title='explicit entrypoint + an additional path'
+node
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ ./src/not-pjson-main.js
+```
+
+#### All together
+
+`--watch` receives a clone of `--test`'s resolved value(s) **plus** `--watch`'s own values—with 1 exception: when both `test` and `watch` modes are enabled, `--watch` does not include a default entrypoint (it's irrelevant and it would likely result in perf waste at best, and unexpected behaviour at worst).
+
+All examples are sequence-independent (all within the same heading behave the same).
+
+##### Watch + test paths & main entrypoint:
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ --watch
+ ./src/not-pjson-main.js
+```
+```sh
+node
+ --watch
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ ./src/not-pjson-main.js
+```
+
+##### Without an entrypoint (just paths):
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ --watch
+```
+```sh
+node
+ --watch
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+```
+
+##### _Additional_ watch paths
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ --watch ./src/**/*.js
+```
+```sh
+node
+ --watch ./src/**/*.js
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+```
+
+### Option: Apply `--watch`'s current design to `--test`
+
+`--test` is optional and optionally accepts 1 value, whose value defaults to node's built-in glob defaults (`./src/**/*.test.(c|m)?(j|t)s`, etc). Additional paths are supplied via a new `--test-path` flag:
+
+
+
+
+ | Description |
+ Code sample |
+ Resulting --test value |
+
+
+
+
+
+
+|
+Override default
+ |
+
+
+```sh
+node --test ./src/foo/*.test.js
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+
+ |
+
+
+
+|
+Override default & Set additional path
+ |
+
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --test-path ./src/bar/*.test.js
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+`./src/bar/*.test.js`
+
+ |
+
+
+
+|
+Defaults + Additional paths
+ |
+
+
+```sh
+node
+ --test
+ --test-path ./src/foo/*.test.js
+ --test-path ./src/bar/*.test.js
+```
+
+ |
+
+
+`./src/**/*.test.(c|m)?(j|t)s`
+~`./src/foo/*.test.js`~
+~`./src/bar/*.test.js`~
+
+which reduces to only the default: `./src/**/*.test.(c|m)?(j|t)s`
+
+ |
+
+
+
+|
+No defaults & Additional paths
+ |
+
+
+```sh
+node
+ --test-path ./src/foo/*.test.js
+ --test-path ./src/bar/*.test.js
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+`./src/bar/*.test.js`
+
+ |
+
+
+
+
From f34de603de43b7d0d12e50e969c88b1779690e39 Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Mon, 9 Feb 2026 20:18:49 +0100
Subject: [PATCH 2/3] add "option 3"
---
proposals/proposal - unbreak test cli arg.md | 90 ++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md
index 227e888..b986650 100644
--- a/proposals/proposal - unbreak test cli arg.md
+++ b/proposals/proposal - unbreak test cli arg.md
@@ -42,6 +42,96 @@ node
## Proposed options
+### Option: n-number of `--test`s + `--watch-path`
+
+`--test` is no-longer positional, accepting 1 value per occurrance of the flag. Supplying any value will override the default glob path.
+
+When combined with test mode, `--watch`'s value is ignored (treated as an "on" flag)
+
+`--watch-path` supplies additional paths to trigger the test-runner to re-run.
+
+
+
+
+ | Description |
+ Code sample |
+ Resulting --test value |
+
+
+
+
+
+
+|
+Test & watch modes enabled with defaults
+ |
+
+
+```sh
+node
+ --test
+ --watch
+```
+
+ |
+
+
+`**/*.test.{cjs,cts,mjs,mts,js,ts}`
+etc
+
+https://nodejs.org/api/test.html#running-tests-from-the-command-line
+
+ |
+
+
+
+|
+Test & watch modes enabled, overriding default
+ |
+
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --watch
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+
+ |
+
+
+
+|
+Test & watch modes enabled, multiple test paths & additional watch paths
+ |
+
+
+```sh
+node
+ --test ./src/foo/*.test.js
+ --test ./src/bar/*.test.js
+ --watch
+ --watch-path ./src/quz/fixt.json
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+`./src/bar/*.test.js`
+
+In addition to changes within the graph of those test, tests will also re-run if `./src/quz/fixt.json` changes.
+
+ |
+
+
+
+
+
### Option: Break all the things
Currently `watch` has 2 flags (which are redundant):
From fea8e41c59578005edcb85b8552b95022d9f6fae Mon Sep 17 00:00:00 2001
From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com>
Date: Thu, 12 Feb 2026 23:50:45 +0000
Subject: [PATCH 3/3] remove `entrypoint` from places that don't make sense,
add item for including defaults plus extras
---
proposals/proposal - unbreak test cli arg.md | 86 +++++++++-----------
1 file changed, 39 insertions(+), 47 deletions(-)
diff --git a/proposals/proposal - unbreak test cli arg.md b/proposals/proposal - unbreak test cli arg.md
index b986650..c2dbde3 100644
--- a/proposals/proposal - unbreak test cli arg.md
+++ b/proposals/proposal - unbreak test cli arg.md
@@ -33,6 +33,8 @@ This is similar to another existing feature with which we want to improve intero
* enables `watch` mode
* optionally accepts 1 value to override the entrypoint
+`--watch-path` sets additional paths to include as well as the entrypoint.
+
```sh
node
--watch
@@ -76,10 +78,7 @@ node
-`**/*.test.{cjs,cts,mjs,mts,js,ts}`
-etc
-
-https://nodejs.org/api/test.html#running-tests-from-the-command-line
+`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line)
|
@@ -101,6 +100,29 @@ node
`./src/foo/*.test.js`
+
+
+
+
+
+|
+Test & watch modes enabled, using default & an additional path
+ |
+
+
+```sh
+node
+ --test
+ --test ./src/foo/*.test.js
+ --watch
+```
+
+ |
+
+
+`./src/foo/*.test.js`
+`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line)
+
|
@@ -156,31 +178,24 @@ node --watch
```sh title='override derived entrypoint'
node --watch ./src/not-pjson-main.js
```
-```sh title='package.json "main" + an additional path'
-node --watch ./src/**/*.js
-```
-```sh title='explicit entrypoint + additional paths'
+```sh title='package.json "main" + additional paths'
node
- --watch ./assets/**
+ --watch
--watch ./src/**/*.js
- ./src/not-pjson-main.js
+ --watch ./src/not-pjson-main.js
```
-An explicit entrypoint, like all node commands, must come last and must be a relative or absolute path (not a glob/pattern).
-
-`test` would then work the same way:
-
-```sh title='reads "main" etc from package.json'
+```sh title='use default'
node --test
```
-```sh title='package.json "main" + an additional path'
-node --test ./src/**/*.test.js
+```sh title='override default with one or more paths'
+node --test ./src/bar/*.test.js
```
-```sh title='explicit entrypoint + an additional path'
+```sh title='use default with one or more additional paths'
node
+ --test
--test ./src/foo/*.test.js
--test ./src/bar/*.test.js
- ./src/not-pjson-main.js
```
#### All together
@@ -189,51 +204,28 @@ node
All examples are sequence-independent (all within the same heading behave the same).
-##### Watch + test paths & main entrypoint:
+##### Test & watch mode enabled:
```sh
node
--test ./src/foo/*.test.js
--test ./src/bar/*.test.js
--watch
- ./src/not-pjson-main.js
```
```sh
node
--watch
--test ./src/foo/*.test.js
--test ./src/bar/*.test.js
- ./src/not-pjson-main.js
```
-##### Without an entrypoint (just paths):
+##### Test & watch mode enabled with _additional_ watch path:
```sh
node
--test ./src/foo/*.test.js
--test ./src/bar/*.test.js
- --watch
-```
-```sh
-node
- --watch
- --test ./src/foo/*.test.js
- --test ./src/bar/*.test.js
-```
-
-##### _Additional_ watch paths
-
-```sh
-node
- --test ./src/foo/*.test.js
- --test ./src/bar/*.test.js
- --watch ./src/**/*.js
-```
-```sh
-node
- --watch ./src/**/*.js
- --test ./src/foo/*.test.js
- --test ./src/bar/*.test.js
+ --watch ./src/something-else.js
```
### Option: Apply `--watch`'s current design to `--test`
@@ -306,11 +298,11 @@ node
-`./src/**/*.test.(c|m)?(j|t)s`
+`**/*.test.{cjs,cts,mjs,mts,js,ts}`, [etc](https://nodejs.org/api/test.html#running-tests-from-the-command-line)
~`./src/foo/*.test.js`~
~`./src/bar/*.test.js`~
-which reduces to only the default: `./src/**/*.test.(c|m)?(j|t)s`
+which reduces to only the default
|