The case verifies first-boot catalog browsing and an actionable
MISSING_CREDENTIAL, so it follows the default catalog instead of an
unlisted id whose route only proves pass-through.
The shipped DeepSeek catalog keeps V41 Flash and V4 Pro only; the removed
ids still pass through as text-only routes when configured explicitly.
Updates the adapter tests, the Web settings goldens that render the default
catalog, and the regenerated config catalog.
`dsh.title` was a manifest field this branch introduced: the manager read
it for `listBundles` and `inspect`, and the Web page showed it over the
package name. A bundle is named by its package name now, so `DshManifest`
keeps only its shipped fields, the page derives every heading from the
name, and the install dialog's subject line reads the name the Host
answered. The two e2e fixtures drop their titles and the manager lane's
goldens follow.
@deepseek-ai/dsh-experimental-client-ui-agent-team listed react under
dependencies, which the shipped client packages never do: react reaches the
browser through the web build. Now that the agent team web profile is an
optional bundle of @deepseek-ai/dsh, that dependency pulled react into the
npm install layout, where verify-npm-install-layout rejects it.
scaffold.ts required the launcher's built module at import time, so the
unit lane, which runs without a build, failed to load
scaffold-generation.spec.ts for its fixture-name helpers. The built copy
is now resolved on the first launch, which needs the build anyway; the
mounted copy is unchanged.
The info ring and the plugin pinwheel joined the hand-authored product
glyphs without the icon-set inventory following: master's count of 79
stayed after the merge while the barrel exports 81.
The Client entry re-exported ConfirmState, InstallState, ManagerNotice and
PluginManagerState from the controller store although no other package names
them; the page, its tests and the presentation module import them from the
store directly. Only the face, the page props and the locale key stay public.
The dsh manifest gains no description field: a bundle's card shows the
package.json description, and the shipped optional bundles carry no
display title or description of their own until localized metadata is
designed. The plugin author tutorial shows the bundle declaration alone.
OPTIONAL_BUNDLES in app-boot lists the bundles the installation ships
switched off; the plugin manager, the default-product isolation gate,
the workspace constraints, and the packed-install check read that one
list instead of a dsh.optionalBundles field in apps/cli/package.json.
app-boot no longer emits profile/reconciled after a reload, and the plugin
manager no longer turns such a generation into a plugin-manager/changed
notice: the Web page learns of a CLI or hand edit on its next read. The
change event keeps only the reasons a manager operation produces.
The retry that allows blocked install scripts drops the failed run from
the dialog instead of stacking the new run under it. The dialog no longer
grows past the viewport: the card is capped and everything under the
head scrolls, so the close and edit controls stay reachable however long
pnpm's output is.
reconcileProfilePatches finds the root Include only through the registry
the module that mounted it keeps, as it did before the Web page: a tree
mounted by another copy of app-boot was a test-harness situation, not a
product one. The web e2e scaffold now mounts and resolves the profile
through the built app-boot, loaded with Node's own require so it shares
the module map with the Host plugins the profile loads, instead of the
source copy a bare import resolves to.
When pnpm leaves a dependency's install scripts undecided, the failed
screen lists the pending packages and offers to allow them and retry in
place of plain retry; the Host saves the permission in the profile before
running pnpm again, and the installed screen names what was allowed. A
failure the Host could not name falls back to the manual instruction, and
a stale approval is worded like the other refusals. A new web lane drives
the whole flow through a fake pnpm that blocks, then installs.