…ng the workspace via symlinks
The schematics `Tree` and `ScopedHost` confine writes to the workspace only
lexically: `_normalizePath` rejects `..` escapes, and `ScopedHost._resolve`
joins paths to the workspace root. But the real-filesystem commit
(`NodeJsSyncHost.write`/`delete`/`rename`) uses `writeFileSync`/`rmSync`/
`renameSync`, which follow symlinks, with no realpath check. So if a workspace
contains a symlinked directory pointing outside it (e.g. from a cloned repo),
a built-in schematic or `ng update` migration writing a lexically in-workspace
path can create/overwrite/delete a file outside the workspace.
This wraps the NodeWorkflow's host so write/delete/rename assert that the
real (symlink-resolved) path stays within the workspace root, mirroring the
realpath-based restriction already used by the MCP host
(`createRootRestrictedHost`). In-workspace operations are unaffected.
Verified against the published packages: a real `use-application-builder`
migration whose `karmaConfig` resolves through a symlinked directory no longer
overwrites the outside target, while the same migration on an in-workspace
config still applies.