@unotest/viewer 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,99 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.22.0] - 2026-08-26
4
+
5
+ ### Patch Changes
6
+
7
+ - 80619a9: Run on NestJS 11 and Fastify 5.
8
+
9
+ The viewer's server was pinned to `@nestjs/* ^10.4.0`, which held the whole
10
+ prod tree on an EOL Fastify 4 line: `@fastify/static` 7 (path traversal past
11
+ a route guard — reachable, the viewer serves its SPA through it),
12
+ `@fastify/middie` 8 (unreachable here, but flagged forever by scanners),
13
+ `@nestjs/platform-fastify` 10 (middleware-bypass series) and `ws` 8.18
14
+ (memory-exhaustion DoS on the viewer's live channel).
15
+
16
+ Nest 11 + Fastify 5 retires all of it: `@fastify/middie` leaves the tree
17
+ entirely, `@fastify/static` moves to 10, `ws` to 8.21. `npm audit
18
+ --omit=dev` on a freshly packed tarball reports zero vulnerabilities.
19
+
20
+ No public API change — same server, same endpoints, same `@unotest/viewer`
21
+ surface.
22
+
23
+ - @unotest/dsl@0.22.0
24
+ - @unotest/protocol@0.22.0
25
+
26
+ ## [0.21.0] - 2026-08-25
27
+
28
+ ### Minor Changes
29
+
30
+ - 174d27e: feat: environments are first-class in the viewer — a switcher, per-env run history
31
+
32
+ **Run artifacts are laid out per environment, as folders.** Each
33
+ environment's history lives in its own root, mirroring the env-file
34
+ scheme: `unotest/.runs` (base), `unotest/.runs.<env>` (e.g.
35
+ `.runs.staging` for `--env staging` / `UNOTEST_ENV=staging`); the axes
36
+ compose — `.runs-mobile.staging`. Indexes (`_day.jsonl`, `_latest.json`)
37
+ are per-env automatically: switching environments is a change of root,
38
+ not a filter and not a rebuild. Old runs stay in `.runs` (= base), no
39
+ migration needed. `runsDirFor` / `projectRunsRoot` / `projectRunDirFor`
40
+ gained an optional `envName` parameter; the run manifest carries `env`
41
+ for self-description. Make sure your `.gitignore` uses the wildcard
42
+ form — `unotest/.runs*/` (`init` already writes it that way for new
43
+ projects).
44
+
45
+ **The viewer knows about environments.** A new switcher sits at the top
46
+ of the Variables panel and in the status bar: base plus every
47
+ environment discovered from `unotest/.env.<name>` / `.secrets.<name>`
48
+ (`.env.example` and other templates do not count). The active
49
+ environment is server-side (`GET/POST /api/environments`), and all tabs
50
+ converge via the `env:changed` WS message:
51
+
52
+ - the Variables panel shows layers WITH the active environment's
53
+ overlay (previously base only); values coming from `.env.<name>`
54
+ carry a badge; an edit goes to the file where the key is defined; new
55
+ variables go to base;
56
+ - Overview and the Runs list show only the active environment — tiles
57
+ are colored by the latest run in that environment;
58
+ - a run started from the viewer gets the active environment's
59
+ `UNOTEST_ENV` (`RunRequest.env` is a per-request override);
60
+ - a run opened from another environment still resolves by runId across
61
+ all `.runs*` roots.
62
+
63
+ MCP: `run_test {env}` already switched the child process's environment;
64
+ its artifacts are now correctly found by the server in `.runs.<env>`
65
+ (inspect/step/attach/list_runtimes scan all roots).
66
+
67
+ Four fixes uncovered while shaking this down:
68
+
69
+ - **The `--env` overlay actually reaches the run.** Long-lived hosts
70
+ (viewer, MCP server) flattened the base `.env` into their own
71
+ `process.env` on `loadConfig`; children inherited it as ambient
72
+ (ambient beats files) — the overlay's `APP_BASE_URL` was silently
73
+ clobbered by the base value. The viewer now rolls its env back after
74
+ loading the config; MCP spawns children from a clean pre-flatten
75
+ snapshot.
76
+ - **Pause/Abort from the viewer work again.** Debug commands were
77
+ written to the flat `<root>/<runId>/commands.jsonl`, while runs have
78
+ lived in date shards since 0.19 — the write 404'd and abort was
79
+ silently ignored. Order fixed too: SIGTERM to the own process first
80
+ (tests AND collections), then the command file.
81
+ - **A collection no longer "dies" in the UI after 30 seconds.** The
82
+ parent run wrote no heartbeat — the monitor declared it interrupted,
83
+ the row vanished from ACTIVE and the tail detached. The orchestrator
84
+ now maintains the heartbeat (shared machinery in `@unotest/core`),
85
+ and the viewer additionally treats a flowing steps.jsonl as a sign of
86
+ life (compatibility with older runners).
87
+ - **No phantom `failed` after a clean exit.** The "child exited without
88
+ artifacts" check looked at the flat path and fired bogus
89
+ `run-finished: failed` events plus an error toast on every exit.
90
+
91
+ ### Patch Changes
92
+
93
+ - Updated dependencies [174d27e]
94
+ - @unotest/protocol@0.21.0
95
+ - @unotest/dsl@0.21.0
96
+
3
97
  ## [0.20.0] - 2026-08-24
4
98
 
5
99
  ### Minor Changes
@@ -23,6 +23,9 @@ interface StartViewerOptions {
23
23
  /** Target id selected at boot (`web`/`mobile`/…). Defaults to the first
24
24
  * available runner. */
25
25
  activeTarget?: string;
26
+ /** Environment name selected at boot (M-11 dot axis, `--env` /
27
+ * `UNOTEST_ENV` of the launcher). Blank/unset = base. */
28
+ activeEnv?: string;
26
29
  /** Port to bind. `0` = OS picks a free port. Default 0. */
27
30
  port?: number;
28
31
  /** Host to bind. Default 'localhost' (loopback only). */