With HMR, installing, enabling, disabling and removing bundles take effect live. Each profile recomposition compares
the loaded modules below the profile directory and its linked targets with disk, stops the plugins whose files
changed, and recomposes the profile through app-boot's recomposeProfile(): the rows the next generation drops are
removed first, the latest runtime resolution is published once, and the generation is applied and judged. Afterwards
HMR evicts the modules below the mappings the recomposition dropped.
- app-boot: recomposeProfile(); PluginPackages.resolution; ResolutionRestartRequired; the resolver accepts in-place
version changes and relinks, and relocates Node's cached link real paths.
- plugin-manager: with HMR, installBundle refuses an installed package (already-installed), so an upgrade is a
removal and an installation; every restart-required result carries a restartReason; removal uses the registry the
package was installed from.
- ui-plugin-manager: the Official Update removes and then installs; restart prompts name their reason.
The caller-connection work — forwarded-event opt-in, physical socket
ownership, and the Node/MCP artifact-only consumer fixture — moves to a
stacked PR on top of this one. This branch now changes only how Remote
definitions are generated (Typert artifacts, lazy method info,
consumer-selected input strictness, tool-schema projection) and how the
existing Registry consumes them.
Reuse read_image and automatic compaction in the standalone profile without
adding SDK slash-command handling. Update profile guidance, upgrade steps,
and startup and recorded-session coverage.
The analyzer normalizes its root with fs.realpathSync, which keeps a
Windows 8.3 short name such as RUNNER~1 in the runner's TEMP, while
TypeScript reports module-resolution results through
fs.realpathSync.native, which expands it. The guard compared the two
spellings, found the resolved lib/ declaration outside the workspace,
and let a missing alias through on Windows. It now canonicalizes the
root and every file with realpathSync.native and reports paths spelled
under the caller's root; the guard specs also run with the workspace
root spelled through a directory link.
Refs #5852
doc-sync, test:docs, hygiene, and check:all run at most 8 gates in CI as
well; the constant, the development guide, and the Agent Note now say so.
The Note also states that the source-only Typert guard rejects unresolved
workspace imports, so a missing alias fails before or after host-src.
Refs #5852
uniquePrefixMatch is exported and covered for unique, shared, last,
exact, absent, and empty cases, and a fixture repository with two commits
whose names share a seven-digit prefix shows that the shared prefix is
accepted while a longer unique prefix is rejected.
Refs #5852
rejectBuildOutputs caught a missing paths alias only when the package's
lib/types already existed. On a tree whose packages are not yet compiled,
as when host-typert runs beside host-src on a clean checkout, the import
resolved to nothing and checkDiagnostics: false hid it. The guard now also
fails when a face program cannot resolve an import of a workspace package,
found through its node_modules link, and names the paths entry derived
from the package's exports types condition.
Refs #5852
gen-doc-graphs states that its probe memo patches the system and needs a synchronous, non-nested caller; the typecheck graph comments why host-check does not wait for host-typert; the API gateway guide names the CI build lanes as the bundling Typert path; and the build-split Note marks its host-libraries measurement as superseded by host-contracts.
Refs #5852
gen-cli-help launched its twelve source-mode dsh --help processes one
after another, each spending most of its time waiting on profile boot
I/O; they now start concurrently within the default worker budget, each
with its own temporary DSH_HOME, and the existing comparison consumes
them in the original order. gen-doc-graphs memoizes ts.sys file, directory,
realpath, and directory-listing probes for one run. Generated pages are
byte-identical; CLI help drops from about 52 s to 7 s and doc graphs from
about 47 s to 33 s.
Refs #5852
uniqueRepoFiles read every directory once per pattern and ** level and
resolved every file with realpath. One walk now lists each directory
once across patterns, resolves only paths reached through symbolic
links, and lets doc refs skip non-leading lib directories, whose files
it always excluded. markdown wrap, doc refs, and package paths return
the same file lists with about half the directory reads.
Refs #5852
markdown links parsed anchor targets twice more and probed existence
without a cache; translation pairing reparsed every document after link
normalization and globbed four times; the README model-experience and
limitations checks parsed each README three times; type equivalence
parsed all 1,835 documents; Session format references reparsed each pair
four times. Each gate now parses a document once: links and anchors come
from one tree, pairing reuses the original tree when every rewritten
destination keeps the block structure and falls back to a full reparse
otherwise, the README checks share one tree, a text prefilter skips
documents that cannot hold a source-equivalence fence, and the
persistence renderer passes its trees on. Outputs are byte-identical on
the repository, and seeded faults are reported identically.
Refs #5852
Browser inputs make every package source file a generator input, so the
pre-commit job ran the 16-second generator on nearly every commit while
few commits change its output. gen-third-party-notices.spec.ts already
asserts the committed bytes in the test lane, including the required
node 24 / coverage pull-request lane, and names the regeneration command
when they are stale. The generated preamble, the notices decision, and
the development guide now describe that ownership.
Refs #5852
verify-repository-references asked git cat-file for each of about 26,000
abbreviated hexadecimal candidates, which took 135 s on a network
filesystem. One --batch-all-objects listing (about 1.2 million objects,
0.6 s) now feeds an in-memory prefix search; a candidate still counts
only when its prefix names exactly one available object and that object
is a commit. The gate drops from 166.8 s to 15.7 s, and both
implementations classify 27,050 real and synthetic candidates
identically.
Refs #5852
os.availableParallelism() reports host CPUs rather than a container's
CPU quota (256 against a 64-CPU quota here), so local defaults spawned
255 Vitest forks (55 GiB peak RSS) and oversubscribed every scheduler.
scripts/parallelism.ts keeps the CPU count in CI and caps other runs at
12, or 48 for Vitest forks and the local coverage budget; documentation
and hygiene aggregates run up to 8 gates instead of 4. Explicit
DSH_GATE_CONCURRENCY, DSH_OXLINT_THREADS, DSH_COVERAGE_MAX_WORKERS, and
--maxWorkers still win.
Refs #5852
Type checks only need Host declarations and Typert-generated
declarations, but typecheck, lint, lint:fix, doc-typecheck, and the CI
typert-contracts gate rebuilt the whole Host tsdown pass, Desktop bundle
included, to obtain them. A source-only scripts/generate-typert.ts now
runs the same generator and artifact writer as the tsdown plugin, beside
Host package compilation: Typert reads only sources once the missing
@deepseek-ai/dsh-client-file-upload/types path alias exists, and
rejectBuildOutputs fails the pass when a workspace lib/ declaration
enters its program. typecheck runs as a build.ts scope that checks both
aggregates in build mode after their own face compiles.
Refs #5852