96 Commits
Author SHA1 Message Date
zhu1090093659 dc7e26b9f0 refactor(shared): drop dead shared artifacts and realign references
- Remove the sync-manifest entry for shared/host/run-guarded.ts and the three
  generated copies under packages/{dsh-usage,dsh-task-board,dsh-git-graph}/src/host/:
  nothing in this repository imported the module (the satellite repositories
  carry their own copies), so the entry only kept three unread files in sync.
  The shared source and its spec stay.
- Delete the unused mobileBundle helper and its node:module createRequire import
  from shared/tsdown.client.ts; the standalone mobile bundle has been gone since
  0.4.0.
- Update the sync composition guard in scripts/sync-shared.test.mjs (99 -> 96
  copies, 48 -> 45 host copies) and refresh scripts/lib-artifact-fingerprints.json.
- Re-point the notes, READMEs, CONTRIBUTING and docs that still linked the
  skin-center contract files to the dsh-skins repository, and prune the stale
  screenshots.
- Record the decision in
  .agents/notes/implemented/simplification/2026-09-26-dead-shared-artifacts-removed.md
  and correct the run-guarded facts in the aggregate fault-isolation note.
2026-09-27 20:47:07 +08:00
zhu1090093659 32e6a83a39 refactor(panels): render every family panel through the native layout seats
ssh is the last panel that took the center column over at the DOM level. It
now registers a row in the shell's own panel list (sidebar.panellist) and a
keyed page in the layout's main slot, like the task board and the skill
center, so the shell owns the row box, label, highlight, rail and switch.
That retires the whole takeover apparatus:

- shared/client/panel-mount-core.ts and shared/client/sidebar-entry-core.ts
  are deleted along with every synced copy; ssh's mount.tsx, sidebar-entry.ts,
  panel-mount-core.ts and sidebar-entry-core.ts go with them. The
  body-mutations hub now serves only the aggregate shell and the usage card.
- The dsh-panel-activate handshake and PANEL_FAMILY occupancy table are gone:
  the layout's keyed main slot is the single occupancy authority, so the board
  and the skill center no longer coordinate with anyone.
- The terminal survives the move because the PTY session is host-owned (see
  the previous commit): the layout unmounting a deselected page costs the view
  its xterm instance, not the remote shell, and the terminal tab reattaches by
  session id. The panel's tab, connect request and session id live in the
  controller rather than in component state.

Tests move with the design: the takeover specs (center-panel-lifecycle,
center-column-css, sidebar-entry, the layout specs, board/ssh coexistence) are
replaced by native-panel-registry specs that drive the real SlotCore, plus a
controller-state spec for ssh's view state.

Validation: pnpm typecheck; pnpm test (ssh 202, task-board 561, skill-explorer
121, shared 107, all packages green); pnpm test:scripts 342/342;
pnpm test:standards; pnpm docs:check; pnpm i18n:check; pnpm aggregate:check;
pnpm libs:check; pnpm market:check.
2026-09-26 17:23:04 +08:00
zhu1090093659 68b095272b Merge origin/dev into dev: one center-column panel family
Brings in the 11 upstream commits, chiefly 305a3863 (skill-explorer moves
into the center column). Both sides had reworked the same panel subsystem
from opposite directions, so the merge integrates rather than picks a side.

- shared/client/panel-mount-core.ts keeps the upstream PANEL_FAMILY table
  (one occupancy row per panel instead of pairwise sibling options) and
  documents that the task board left the core for the native layout seats.
- The board keeps its native panel registration and its dsh-panel-activate
  handshake, widened from ssh alone to every DOM-takeover family panel:
  coordinateWithFamilyPanels plus TAKEOVER_PANEL_NAMES now cover
  skill-explorer too, so the new third panel can no longer paint over the
  board while its row still looks selected. panel-coexistence.spec.ts
  covers the new direction.
- sync-shared drops the board's body-mutations / sidebar-entry-core /
  panel-mount-core copies and keeps ssh plus skill-explorer for the core;
  copy-count buckets are 105 total / 45 client.
- The panel-mount-core extraction note records the merged design and
  refreshed facts; both sides and the sidecar are re-recorded.

Merge conflicts: 14 files. Validation: pnpm typecheck, pnpm test
(ssh 210, task-board 565+1 skipped, skill-explorer 115), pnpm docs:check,
pnpm i18n:check, pnpm test:scripts 342/342, pnpm libs:check,
pnpm market:check, and the panel suites all pass.

pnpm test:standards reports 3 new violation groups, all in
dsh-plugin-manager gateway specs that another session has unstaged; they
are not part of this merge.
2026-09-26 16:37:10 +08:00
zhu1090093659 da32f628a5 feat(task-board): render the board through the native layout panel
Move the task board off its DOM takeover: the board now registers a
sidebar.panellist row and a keyed main page through the official slots
system, and the package-local panel-mount-core, sidebar-entry-core and
body-mutations copies are retired. The shared panel-mount-core returns to
the single ssh consumer with sibling activation names.

Also folds in the plugin-manager update-patch rework (the settings tab is
replaced by a patch row on the official Plugins page, plus the desktop
launch-profile repair) and the matching Agent Notes.

Committed as a checkpoint before merging origin/dev.
2026-09-26 16:14:14 +08:00
EDDYCRAZY-CC ad90e46b28 fix(settings): bind family cards to the profile entry the Host serves
A family settings card addresses its form by PROFILE ENTRY ID, but each card
knew only its own namespace. When the family binder is not loaded the cards
fell back to ctx.configForms.get(namespace) — an entry the Host does not serve
on an aggregate install. The write was rejected with "No configurable plugin
entry \"liangshen\"" while the card reported "the deployment did not accept
these values", which is what the LiangShen settings page showed for every edit.

The fallback now lives once in shared/client/settings/settings-entry-form.ts
(synced to the six packages whose card binds a family namespace) and binds the
entry id the shared describe mirror justifies, REBINDING when the mirror names
a different one of the package rows. A one-shot guess cannot be right for every
deployment: the mirror answers asynchronously — at plugin activation it usually
holds nothing yet, and the aggregate mounts its client children in order — the
bare namespace is no entry id on an aggregate install, and the aggregate row id
is wrong on a standalone one, whose row id is the namespace or the package own
ui-* row. An unanswered or EMPTY mirror counts as unanswered, not as absence;
only a mirror that answers with other packages rows falls back to the
namespace itself, which is the pre-0.1.7 keying shape.

Affected cards: dsh-liangshen, dsh-remote-web-ui, dsh-task-board, dsh-market,
dsh-usage and dsh-session-archive (the last three carried the same defect).
The aggregate and market specs now model a mirror that names the served row
instead of asserting the namespace.

Verified in the real Web GUI: the save now posts ns "web-ui-liangshen" and the
Host answers ok. The refreshed aggregate lib/ and the new fingerprints ship
with the change; the owning 0.1.7 cohort note records the binding rule.

pnpm typecheck, pnpm test, pnpm docs:check, pnpm i18n:check,
pnpm aggregate:check, pnpm libs:check, pnpm sync-shared:check,
pnpm test:standards, pnpm runtime-deps:check and pnpm emoji:check pass.
pnpm test:scripts fails only in the tar --force-local suites, which Windows
bsdtar rejects (GNU flag) and which this change does not touch.
2026-09-25 15:39:12 +08:00
EDDYCRAZY-CC 305a38634c feat(skill-explorer): move the skill center into the center column
The skill center was a body-level overlay modal and the only family surface
that did not share the center column. It is now a center-column panel like ssh
and the task board: a header with the back-to-conversation control, a
skills/create tab bar, and the family's control vocabulary, still
theme-token-only.

Panels now share one occupancy table: shared/client/panel-mount-core.ts owns
PANEL_FAMILY (activation name and html attribute per panel) instead of the
pairwise sibling options. Opening a panel clears the other rows' attributes and
broadcasts its own name; an open panel closes when the broadcast name is not its
own. The pairwise shape could not express three panels, so a panel that did not
name the third one stayed logically open while invisible and its sidebar row
needed a second click to reopen.

The skills list adopts the family's row treatment, the refresh control hides
while a load is in flight, and the create tab resolves the workspace it needs
when it is the first tab opened. The semantic-attributes contract drops
card/head; the wallpaper-exclusive skin re-anchors its skill center rules on the
panel root plus skill-row (committed in the dsh-skins repository, pinned here).

Generated copies follow their sources: ssh and the task board mounts lose the
sibling options, the skill center gains a panel-mount-core copy, and the
aggregate artifact plus the market dist are rebuilt.

Authored by yupeng.jia <yupeng.jia@momenta.ai> as ad47d3a4 on the contribution
fork; re-applied here on the current dev (the original was based on 53ec2ed1,
108 commits behind) with the generated artifacts rebuilt rather than taken from
the stale base, and the skin-center content re-applied in its own repository.
2026-09-25 14:47:18 +08:00
zhu1090093659 4d5d4e0752 fix(shared): replay a family mount refused while its holder still lives
A Host reload composes the new loader entries before the old ones are torn down, so the reloaded aggregate row asked for a package name the previous entry still held, its mount was dropped, and the previous entry then released the name with nobody left to take it: the row stayed listed as active with no degraded record and served no Host routes until a restart. The guard now queues the refused mount with its own context and replays it one microtask after the release, and a waiter whose fiber dies first is dropped instead of replayed. The Symbol.for registry keeps its Set shape because the satellite repositories compile their own copy of this guard.
2026-09-25 10:22:14 +08:00
zhu1090093659 30ab8692a9 chore(sdk): advance the plugin cohort to 0.1.7-rc.2
Move every family manifest, the plugin scaffold and the shared workspace
package onto the 0.1.7-rc.2 cohort, together with the surfaces that state
the same fact:

- the dsh.engines.dsh floors and the matching @deepseek-ai/dsh host peers
- the release-age exclusion ledger and the two packageExtensions keys
- the root README badges, the CI/release mount-smoke pins and the
  docs/publish-prep.md and docs/plugins.md prose

Two rc.2 facts were verified against the published artifacts rather than
inferred from the version number:

- the shell's frozen static module table is unchanged (the same nine
  specifiers in the dsh-web-frontend rc.2 dist bundle), so
  shared/web-platform.ts keeps its list and only its provenance comment
  moves; the new dsh-client-shortcuts is an ordinary client plugin, not a
  static module
- @deepseek-ai/dsh-client-ui-primitives@0.1.7-rc.2 imports a further
  undeclared face, @deepseek-ai/dsh-util-code-language, so the
  primitives packageExtensions patch gains that pin

The satellite peer floors in pnpm-lock.yaml still read >=0.1.7-rc.1: they
belong to the satellite packages and move when those repositories release
the aligned version.
2026-09-24 22:26:05 +08:00
zhu1090093659 57d1499ddf test(vitest): give the family test setups a usable localStorage
Node 25 defines localStorage on the global object, and without a usable
--localstorage-file its getter returns an empty object: getItem, setItem and
clear are all missing. Vitest's jsdom environment fills in globals only where
the name is still free, and under vitest window is globalThis, so that stub
survived into every DOM test: the packages whose code reads storage took their
degraded paths instead of the code under test, and dsh-task-board's specs failed
outright on window.localStorage.clear.

The shared setup now installs a Storage in a DOM environment and removes the
stub where there is no DOM, which is what Node 22 leaves behind. dsh-git-graph
and dsh-task-board join its copy manifest, and dsh-skill-explorer's own setup
imports the shared source.

Measured on Node 25 against Node 22, the repair is what moves the numbers back:
dsh-git-graph 79.53 -> 81.32 lines, dsh-remote-web-ui 69.66 -> 70.34,
dsh-skill-explorer 77.61 -> 80.22, dsh-web-settings 78.66 -> 82, with branches,
functions and statements following. Coverage no longer depends on the
interpreter that ran the suite, which is what makes one recorded baseline mean
the same thing in both.
2026-09-24 09:54:51 +08:00
zhu1090093659 65de1ace9a chore(sdk): advance the plugin cohort to 0.1.7-rc.1
Move every consumed @deepseek-ai family specifier (272 across 23 manifests),
the dsh.engines.dsh floors and the matching @deepseek-ai/dsh host peers, the
plugin scaffold, the release-age ledger and the packageExtensions keys, the
desktop host payload pin with its regenerated hoisted lock, the root lock,
the CI and release mount pins, the README host badge, the cohort-version
source literals and the cohort prose in docs.

Regenerate the official token contract from the 0.1.7-rc.1 surfaces (293 to
299 names, additive, contractVersion stays 1) and verify the browser platform
seed against the rc.1 shell bundle. Harden the shell-isolation real-boot spec
so it only accepts an app-boot copy whose own non-optional peers resolve: this
cohort pulls an incomplete copy into the workspace for the first time, through
dsh-agent-preset-registry.

Record the cohort decision, the official release-notes and compare evidence,
the published-surface delta and the native-first overlap inventory in
.agents/notes/implemented/architecture/2026-09-23-sdk-cohort-0.1.7-rc.1.
2026-09-23 22:11:06 +08:00
zhu1090093659 62450aedeb fix(host): request identity encoding from every remote fetch
The alpha.2 host import of npm undici costs Node built-in fetch its

content-encoding decompression. shared/host/http.ts now owns the rule as

withIdentityEncoding(init), and every host fetch that parses a remote body

adopts it: the market installer (manifest and assets), the plugin-manager

npm-registry probe, the remote-web-ui registry/GitHub probes and inner

app-shell fetch, and the usage provider probes.
2026-09-23 18:28:54 +08:00
zhu1090093659 66ba8ede6e chore(sdk): advance the plugin cohort to 0.1.7-alpha.2
Bump every @deepseek-ai family specifier (258 specifiers across 25
manifests), every dsh.engines.dsh floor (22 packages), cordis to ^4.0.4
and schemastery to ^3.18.4. Align the shared ledger, the desktop host
runtime seed (overrides, exclude list, regenerated lockfile) and the root
lockfile, plus the CI and release mount pins, the cohort-version docs and
the source literals that name the cohort.

The floors had been written as ">=>=0.1.7-alpha.2"; repair them to
">=0.1.7-alpha.2" so the family-engine regex gate passes again.

dsh-market/lib is rebuilt because its committed bundle embeds the resolved
cordis and schemastery paths; the Skin Center output is rebuilt in the
token-contract change that follows.
2026-09-23 15:45:08 +08:00
EDDYCRAZY-CC 87203e9b36 fix(settings): gracefully render form fields and suppress unexposed banner for web plugin cards 2026-09-23 09:59:27 +08:00
EDDYCRAZY-CC be8077983b fix(market): hide notExposed banner when renderChildrenWhenNotExposed is enabled 2026-09-23 02:41:28 +08:00
EDDYCRAZY-CC b7012f5b45 fix: resolve workshop missing namespace, streaming flicker, and liangshen restore target 2026-09-23 02:33:18 +08:00
EDDYCRAZY-CC 5daf6942e6 chore(sdk): move the family to the 0.1.7-alpha.1 cohort on the permanent alpha branch
The official family published 0.1.7-alpha.1 while the alpha branch stood on
0.1.6-alpha.2, and the machine's DSH moved to the new cohort. Four changes in
the release reach this family:

- The settings subsystem is now keyed by the profile entry: ctx.settingsScope,
  SettingsScope* and SettingsProvider.installSection/register are gone, replaced
  by ctx.configForms, ConfigForm* and SettingsForms. Every family host half
  carries its settings on its own Config with volatile fields, every browser
  half binds through the webUiSettings service (which resolves a family
  namespace to the owning profile entry id and then binds natively, with the
  loopback bridge as the fallback), and the shared card/form layer speaks the
  new contract including its boolean refusal answers.
- The agent-preset domain became declarative: directory discovery is gone, a
  preset is a declaration a plugin registers at runtime. dsh-preset-center now
  declares installed presets from its host half (install = declare) and
  dsh-liangshen declares its own preset instead of syncing files into
  ~/.dsh/.agent-presets.
- Session V4 moved the tool-result failure flag to the message root; dsh-pet
  read the removed content block and silently rendered failed turns as
  successes.
- The client design system renamed its icons and reshaped SessionListState;
  the affected call sites and fixtures follow.

Cohort: every consumed @deepseek-ai/dsh-* range, the scaffold, the README
badges, the CI and release mount-smoke pins, the desktop runtime pin and both
lockfiles, and the docs move together; the vendor pins follow the cohort's own
release (cordis 4.0.3, cosmokit 1.8.4, schemastery 3.18.3,
cordis-plugin-include 1.0.8, cordis-plugin-loader 1.0.4). The workspace
packageExtensions restore @deepseek-ai/dsh-util-workspace-path, which
dsh-client-ui-primitives now imports from its emitted lib while declaring no
dependencies.

scripts/e2e-mount.sh, scripts/e2e-mount-rewrite and its test, and
scripts/publish-legacy-aggregate.mjs pass GNU tar --force-local on the
Windows/MSYS lane, where a C:\ output path is otherwise read as a remote host.

The mount smoke does not pass on this workstation: the local dsh CLI is a
symlink into a DSH checkout whose built lib/ predates this cohort's own
multi-file dsh.bundle.patch support, so profile boot crashes on the official
dsh-web-app array before any family row is evaluated. That is host-side build
staleness outside this repository; the lane passes once the DSH checkout is
rebuilt. Recorded with the rest of the decision in
.agents/notes/implemented/architecture/2026-09-22-sdk-cohort-0.1.7-alpha.1.md.
2026-09-22 22:18:38 +08:00
zhu1090093659 8c8d9e07eb fix(settings): seat family cards in the alpha.2 bundle-configuration slot
The 0.1.6-alpha.2 cohort removed the official keyed seat
`settings.plugin.item` that `ui-settings-plugins` declared; the plugin
manager page now dispatches plugin configuration through
`plugins.item` / `plugins.bundle.config` / `plugins.row.config`.
The shared family card seat therefore had a dead fallback: a profile
installing one family plugin without `dsh-web-settings` registered into
a slot no host declares any more, and the refusal only reached the
console.

The fallback now targets `plugins.bundle.config`, keyed by the
contributing package's own bundle name (every family package ships its
own bundle patch, so a standalone install lists that package as the
bundle whose page renders the card). The family list seat
`web-ui.plugin.item` is unchanged. PluginCardSeat drops the
settings-namespace field for that bundle name, and the five consumers
(dsh-doctor, dsh-liangshen, dsh-remote-web-ui, dsh-task-board,
dsh-tool-describe-image) pass it.

Docs, seat tests and the committed aggregate bundle follow the same
rename.
2026-09-20 21:48:44 +08:00
EDDYCRAZY-CC 0520e8a479 fix(sidebar): align entry rows with the shell panel rows and drop the usage row
The injected sidebar entry rows (task board / SSH / skill explorer) carried their
own box - 10px padding, 8px radius, 13px type - so their icons and labels sat on
different x positions than the shell panel rows next to them. They now reproduce
the shell panel-row geometry: 2px inset, 12px radius, 7px 8px padding, 36px row,
14/22 type, primary ink, and a 16px glyph box (18px on the 56px rail).

The usage sidebar entry and its collapsible panel are removed: the settings
section already renders the same overview, and the row duplicated it in a
permanent navigation slot. With its only consumer gone, the shared entry core
drops the trailing-actions API (SidebarEntryAction, the composite container, the
entryAction/entryMain CSS contract) it had grown for that row.

The pet bubble is untouched: dsh-pet has no changes here, and its announcement
API and bubble rendering are intact.
2026-09-20 21:48:43 +08:00
zhu1090093659 40f5f2927d chore(sdk): move the family to the 0.1.6-alpha.2 cohort on the permanent alpha branch
Adapt dsh-web to the experimental @deepseek-ai/dsh-* 0.1.6-alpha.2 cohort in the
same isolated alpha worktree and DSH home, so the accepted 0.1.5-rc.1 stable
environment, its profile tree and the global dsh CLI stay untouched.

Cohort: every consumed range, the plugin scaffold, the root README badges, the
CI and release mount-smoke pins, the desktop runtime pin and its lockfile, both
release-age exclusion lists and the desktop overrides block move to
0.1.6-alpha.2; the declared host floor becomes dsh.engines.dsh >=0.1.6-alpha.2.
cordis, cosmokit and schemastery keep their independent support pins.
@deepseek-ai/dsh-client-ui-workspace joins the repository exclusion list and the
packages that navigate gained it as a devDependency, because the family now
consumes it directly.

Adaptation of the SDK delta - the multi-instance Client Session model:
- SessionListState.current/currentAddress and SessionSummary.completed are gone,
  and ISessions.open()/openSubagent()/clear() are removed. View selection now
  belongs to the workspace UI, which owns the main-area reference and publishes
  it as retainedBy.mainView; navigation is ctx.uiWorkspace.openSession(target).
- shared/client/main-session.ts adds mainViewSessionId(byId), the catalog-level
  reading of that marker, and sync-shared copies it into the seven consumers.
  Ten call sites across eight packages read the removed faces; two of them
  (git-graph auto-isolation, session-archive) type-checked against local
  structural doubles and never appeared in the compiler's error list, so the
  inventory was built by searching for the removed names rather than by
  trusting tsc.
- dsh-task-board's framework-free controller port changes from a list snapshot
  to { current(), open(), subscribe() }; the wiring resolves current() from the
  marker. dsh-git-graph navigates new worktree sessions through the workspace UI.
  dsh-pet, dsh-plugin-manager, dsh-doctor, dsh-liangshen, dsh-session-id and
  dsh-session-archive read the marker instead of the removed selection.

Upstream packaging defect: dsh-client-ui-primitives@0.1.6-alpha.2 imports
simple-icons from its emitted lib/index.js while the published manifest still
declares no runtime dependencies; packageExtensions restores it at the exact pin
the official source resolves (16.31.0), beside the existing diff/shiki/micromark
restorations. No installed file is patched.

Native-first: no family row registers the new sidebar panel slots, and the
alpha.1 to alpha.2 slot-key comparison is additive only. dsh-plugin-manager
already extends the official Plugins section through settings.plugins.tab rather
than mounting a parallel page, and that stays the right native extension. The
aggregate declares no external npm plugin, so the new runtime plugin dependency
resolution has no external hard-binding to unmask. The inject contract records
dsh-client-ui-workspace as an approved inject module with its rationale.

Testing: pnpm typecheck, sync-shared:check, skin-center:check, community:check,
libs:check, build, test, test:scripts, test:desktop, runtime-deps:check,
aggregate:check, emoji:check, test:standards, docs:check, i18n:check and
market:check pass, and pnpm install --frozen-lockfile --ignore-scripts resolves
the lockfile. The alpha host in ~/.dsh-alpha is upgraded to 0.1.6-alpha.2 and
every profile @deepseek-ai copy is a symlink into it (235 ok, 0 warn, 0 fail);
dsh --profile alpha-web --dump-config composes the family rows with the retired
ui-settings-unarchive-sessions row.
2026-09-20 21:48:39 +08:00
zhu1090093659 3ddca466bc chore(sdk): move the family to the 0.1.6-alpha.1 cohort on a permanent alpha branch
Adapt dsh-web to the experimental @deepseek-ai/dsh-* 0.1.6-alpha.1 cohort on a
permanent alpha branch with its own worktree and DSH home, so the accepted
0.1.5-rc.1 environment, its profile tree and the global dsh CLI stay untouched.

Cohort: every consumed range, the plugin scaffold, the root README badge, the
CI and release mount-smoke pins, the desktop runtime pin and its lockfile all
move to 0.1.6-alpha.1; cordis, cosmokit and schemastery keep their independent
support pins. Both release-age exclusion lists and the desktop overrides block
follow, and stale rc-only entries are dropped rather than carried.

Adaptation of the SDK delta:
- agent/session-start was removed and agent/created became async serial.
  dsh-tool-describe-image awaits its resting verdict inside the listener, so
  the tool mask lands before the first request's toolset is assembled, and the
  listener never rejects because a rejecting listener now aborts agent
  creation. dsh-liangshen merges its two stale, mis-shaped registrations into
  one correctly-shaped listener.
- ctx.codeRuntime was renamed to ctx.ptcRuntime; reading the old key would have
  silently disabled PTC staging in the liangshen preset.
- dsh-tools now statically imports its new required peer dsh-sandbox, carried
  as a root host face; dsh-client-ui-primitives imports diff, restored through
  packageExtensions.
- The deprecated synchronous session readers still ship, so existing uses are
  recorded rather than migrated.

Native-first: dsh-session-archive replaces its private requireState/setState
workaround with the new public workspace.unarchiveSession verb, while keeping
the inventory, batch operations, cascade physical delete and auto-maintenance
policies that the native archived-sessions page does not provide. The native
SSH remote-workspace provider is recorded as complementary to dsh-ssh, which
covers host management, SFTP, tunnels and cluster execution instead.

Validation: the full CI-equivalent gate sequence passes in the alpha worktree
(typecheck, sync-shared, skin-center, community, libs, build, test,
test:scripts, test:desktop, runtime-deps, aggregate, docs, i18n, market), and
dsh --profile alpha-web --dump-config composes the alpha host with the family
rows from the isolated home. Live GUI acceptance against a running alpha
instance remains open and is recorded in the Agent Note.
2026-09-20 21:48:24 +08:00
zhu1090093659 fea0041020 feat(usage): seat panel controls on the entry row and add a collapsed usage strip
- The shared sidebar-entry core gains an optional actions array (composite
  row only when actions exist, so sibling plugins render byte-identical
  rows); dsh-usage seats a refresh command (3 s cooldown) and a collapse
  chevron on the entry row, replacing the duplicated panel header, and the
  mount owns the single persisted open state mirrored to the row and the
  React body.
- The pet announce pipeline and the bubbleMode setting leave dsh-usage
  entirely; the overview document carries the strip-ready current view
  (resolved displayName and adapter-family today totals), and the collapsed
  sidebar renders a one-line strip with the current session provider's
  tokens, calls, and priced cost, with a client-side derivation for older
  hosts. Polling runs at 10 s expanded, 30 s collapsed, and pauses while
  the page is hidden.
- dsh-pet keeps its announce contract with docs no longer naming dsh-usage
  as the consumer. READMEs, the semantic-attrs contract, and the affected
  Agent Notes updated; the decoupling decision is recorded in a new
  simplification note.
2026-09-17 17:36:48 +08:00
EDDYCRAZY-CC f8e375416e fix(dsh-web): seat family plugin cards from the loaded settings group
The "Web 插件" section rendered its heading and zero cards: seat selection
asked whether the official keyed seat settings.plugin.item is declared, but
ui-settings-plugins declares it in every web bundle before any external
plugin applies, so every family card went to the official Plugins tab and the
group's own section stayed permanently empty.

installPluginCard now keys on the settings group being loaded
(ctx.get('webUiSettings')) and re-evaluates on slots/changed, so a group that
applies later still takes the cards. The move is guarded against the
registry's synchronous re-entrant change event, which otherwise registered the
card a second time into the seat it was leaving.

Five packages ship the regenerated shared copy; the aggregate bundle and its
lib fingerprint are refreshed, and the superseded #1589 seat rule is
cross-linked from its Agent Note.
2026-09-17 12:41:37 +08:00
EDDYCRAZY-CC 8ad234c0dc fix(dsh-web): resolve issues #1587, #1588, #1589, #1592, #1597, #1600
- task-board: pick the newest SETTLED execution for session reuse; the
  launch path appends this run's open record before the rule reads it
  (#1587)
- plugin-manager: resolve the packaged desktop runtime's own lib/bin.js
  and run it through the host interpreter when no PATH entry or .bin shim
  exists (#1588)
- plugin cards: contribute to whichever plugin-card seat the host
  declares (family list seat, else the official keyed settings.plugin.item
  seat) and log a refused registration instead of swallowing it (#1589)
- usage: sidebar entry + collapsible panel over the same overview
  document, with the family pairing fence on the host routes (#1592)
- usage: serve the zai route, key plan windows by the provider unit,
  use the exact credit ratio, and skip TIME_LIMIT/unknown units (#1597)
- plugin-manager + remote-web-ui: accumulate child output as bytes and
  decode once, so a Windows CP936 console renders readable text (#1600)
2026-09-17 00:58:01 +08:00
zhu1090093659 5a7ec7a25b perf(client): reduce idle work across plugin combinations 2026-09-12 15:03:45 +08:00
zhu1090093659 7d236e315e perf(web-all,skin-center): share one body mutation observer and coalesce shell DOM syncs
Family plugins each installed their own document.body subtree MutationObserver,
so per-mutation cost grew with the number of installed plugins during chat
streaming. Add shared/client/body-mutations.ts: one page-wide observer
registered on globalThis under Symbol.for, delivering accumulated records to
subscribers at most once per animation frame. sidebar-entry-core,
panel-mount-core and the aggregate shim subscribe to it instead of observing
body themselves.

skin-center: cache the composer seat and skip the unchanged
--dsh-composer-height write, coalesce mutation-driven height and
conversation-content checks to one per frame, and write backdrop markers only
when they differ. The aggregate caches the [data-dsh-frame] lookup instead of
re-querying per mutation batch.

Controlled Chromium harness, 301 frames over 5 s, mean of 3 runs: body observer
callbacks 1503 -> 902, callback time 237 ms -> 2.9 ms, ScriptDuration
69.6 ms -> 13.6 ms, TaskDuration 984 ms -> 725 ms; LayoutCount unchanged
(natural per-frame paint layout). See
.agents/notes/implemented/bug-fix/2026-09-11-combined-plugin-mutation-cost.md.
2026-09-11 11:56:12 +08:00
zhu1090093659 34380e9d6a test(shared): mirror the rc.1 shell module table
The 0.1.5-rc.1 dsh-web-frontend frozen module table adds the
dsh-client-ui-dockkit row next to the existing platform seed. The seed
list and its mirror contract move together; no repository client bundle
imports the new module yet, so artifacts are unchanged.
2026-09-10 12:05:19 +08:00
zhu1090093659 3968cb8134 chore(sdk): move the official cohort to 0.1.5-rc.1
All @deepseek-ai/dsh-* ranges, the dsh.engines.dsh floors, the CI and
release mount-smoke pins, the README host badge, the publish-prep smoke
sentence, and both the root and desktop cohort pins move as one literal
to 0.1.5-rc.1, matching the installed DSH host. The
minimumReleaseAgeExclude lists follow at exact rc.1 versions; the
packageExtensions packaging-defect workarounds stay and are retargeted
to rc.1 (the rc.1 tarballs still omit the declared runtime deps,
verified 2026-09-10). Lockfiles regenerated through pnpm.
2026-09-10 11:59:43 +08:00
zhu1090093659 f34f84dcb1 chore(sdk): move @deepseek-ai cohort to 0.1.5-alpha.2
- devDependencies ^0.1.2-rc.1 -> ^0.1.5-alpha.2 across the family, exact
  pins in shared/ and desktop runtime host included
- dsh.engines.dsh floors, README badges, CI mount-smoke CLI pins and the
  publish-prep smoke-lane sentence move to >=0.1.5-alpha.2 in one change
- root and desktop runtime minimumReleaseAgeExclude rows re-verified
  against the registry (every row has an alpha.2 release) and moved;
  desktop overrides block re-pinned with the same evidence
- lockfiles regenerate in the following install commit
2026-09-09 23:01:36 +08:00
zhu1090093659 9958edbfeb chore(deps): move @deepseek-ai cohort to 0.1.2-rc.1
- devDependency ranges ^0.1.2-alpha.4 -> ^0.1.2-rc.1 (exact pins stay exact)
- dsh.engines.dsh floors >=0.1.2-rc.1 across the family + plugin template
- README DSH badges, CI/release mount pins, publish-prep smoke sentence
- minimumReleaseAgeExclude swaps to the rc.1 exacts (rc.1 published 2026-09-03T06:21Z, inside pnpm 11's 24h gate)
- desktop runtime host pin @deepseek-ai/dsh 0.1.2-rc.1
2026-09-03 23:53:22 +08:00
zhu1090093659 5902cc4987 refactor(shared): extract the center-column panel-mount core
mount.tsx and board-mount.tsx carried ~100 identical lines of the
single-occupant takeover lifecycle (injection, sibling eviction,
remount resilience, sidebar click-out) that the fix history forced
through twice (#243/#107, c0a98c715, 170b3df31, d73bffc2a). The
lifecycle now lives once in shared/client/panel-mount-core.ts with
two sync-shared generated copies; both wrappers keep their public
exports and only wire the seven per-plugin parameters. Attribute
names stay wrapper-supplied: CSS, skins, and the semantic-attrs
contract pin them. Agent note included.
2026-09-02 16:25:19 +08:00
zhu1090093659 eb2e135686 fix(shared): de-collide css module style tags and lift settings card contrast
The aggregate client bundle keyed every injected stylesheet tag by
basename, so the eight same-named settings-card.module.css copies
suppressed each other and seven family packages rendered their settings
cards with UA defaults under every skin. Style tags now carry the full
repo-relative file id. The shared card chrome lifts 12-13px hint text
from label-tertiary to label-secondary (orca-link measures ~3.4:1 on
tertiary) and points the error roles at state-error-primary, which the
suite defines, instead of the nonexistent label-error token. sync-shared
gains dsh-perf for the card chrome pair only: its settings-form.ts still
runs the pre-0.1.2 per-field generation and must not be overwritten.
Live GUI verified on 127.0.0.1:3080 under the orca-link skin and the
default appearance.
2026-09-02 13:06:53 +08:00
zhu1090093659 46d03a10bf chore(sdk): bump cohort to 0.1.2-alpha.4 and drop deprecated better-session
Manifest ranges move to ^0.1.2-alpha.4 across the family with minimumReleaseAgeExclude reconciled to the exact alpha.4 versions; the host floor moves with the cohort (dsh.engines.dsh >=0.1.2-alpha.4 across 21 family packages plus the plugin scaffold, the static README badge, and the @deepseek-ai/dsh@0.1.2-alpha.4 CI/release mount-smoke pins). The published delta brands session sequence numbers (SessionSeq / SessionLogOffset, Session.events replaced by eventAt/ownEvents, fork headers reshaped to isSeeded + inheritedEventCount), formalizes a v0-compatible browser wire header in dsh-api-session-controller, adds the keyed-hooks compartment to dsh-client-ui-slots, reworks the subagent continuation path, and removes the family-internal invariant helper. The only repository consumer is the dsh-pet test fixture, which now brands fixture sequence numbers through the exported SessionSeq() constructor.

The deprecated @morlay/better-session aggregate integration ships no more: the external row, its expanded sub-plugin rows and disabled overrides, the devDependency, the release-age exclusions, the patchedDependency with its patch file, and the scripts/dsh-better-session.mjs CLI are removed; the aggregate test flips to a negative guard. dsh-perf's Better Session card and native bsm core stay as the legacy-session migration surface.

The lockfile is regenerated once for both concerns. Full local gate sequence passes (typecheck, build, test, test:scripts, runtime-deps, aggregate, community, skin-center, docs, i18n). Notes: 2026-09-02-drop-deprecated-better-session-integration plus the cohort-note alpha.4 follow-up.
2026-09-02 09:19:09 +08:00
zhu1090093659 ce555932e0 fix(dsh-web-all): mount shell-wrapped children in the aggregate client bundle 2026-09-02 00:46:36 +08:00
zhu1090093659 4b25dd7714 feat(aggregate): isolate per-plugin boot failures behind the dsh-web-all shell
The DSH loader mounts every patch row as one transactional group: a single
plugin that fails to import or start rolls back the whole family and aborts
'dsh web'. Redefine the fault unit to one plugin.

- scripts/aggregate.mjs emits each family insert row with the aggregate's own
  never-failing shell module as the row name and the real plugin package in
  the row config (config.plugin, original config under config.config);
  dsh-i18n and all external npm rows keep mounting directly
- @linxin666/dsh-web-all main entry is the shell: it imports the real module
  at start time, contains import/shape/activation failures to that entry
  (logged + recorded), and mounts the real plugin as a nested plugin so
  cordis service scoping, lifecycle, and retraction semantics stay intact
- loopback-only GET /api/dsh-web-all/degraded reports the degradation ledger
  for doctor/monitoring consumption
- shared/host/run-guarded.ts (+ synced copies in the four packages with
  in-process HTTP/poll faces) converts fire-and-forget rejections into logged
  errors against the host's installFailLoud whole-process exit
- tests: shell-isolation.spec.ts runs the real installed host boot through
  start-failure / import-failure / no-webServer scenarios plus the control
  case proving today's direct-mount shape still kills the boot

Evidence: pnpm typecheck, pnpm test (22 packages), pnpm docs:check,
pnpm i18n:check, pnpm aggregate:check, pnpm test:scripts (234), and full
pnpm build all pass. Bundle-layer change: needs a dsh web restart.
2026-09-01 20:34:14 +08:00
zhu1090093659 82c033ff48 chore(sdk): bump official cohort to 0.1.2-alpha.3
Manifest ranges move to ^0.1.2-alpha.3 across the family; the
minimumReleaseAgeExclude entries reconcile to the exact alpha.3
versions. The published delta (api-session-controller additive
mode/placement/loadThrough, subagent image admission and error-code
rename) has no repository consumers, so no source adaptation is
required; emitted bundles stay byte-identical to the alpha.2 builds.
Full gate sequence and the e2e mount smoke pass unchanged.
2026-09-01 01:25:37 +08:00
zhu1090093659 170b3df318 fix(i18n): route the family sidebar rows through the SDK locale runtime
GUI verification showed the L1 sidebar rows of task-board, dsh-ssh and
dsh-skill-explorer staying Chinese while their settings sections switched
language: those rows read a package-local t/tt helper that picks zh/en
from documentElement.lang, which the SDK Language switch never updates
(the rows also stayed Chinese under English — proven by a live switch
test). The module-level helpers now prefer a wired SDK translate seat
(ctx.locale.bind(NS), set in apply once the dictionaries register) and
fall back to the document-language pick only when unwired; the shared
sidebar-entry core gains an optional refresh subscription (ctx.locale
.subscribe) that re-applies label/aria-label/tooltip on locale changes,
and the board/panel mounts re-render an open view on the same signal.
Verified live: switching to Русский flips the rows to Доска задач /
Центр навыков without a reload.
2026-08-31 09:30:22 +08:00
zhu1090093659 319f141d3e feat(sdk): upgrade the official SDK cohort to 0.1.2-alpha.2
Bump the whole @deepseek-ai cohort to the dsh-v0.1.2-alpha.2 preview:
rebuild the cohort tarball store from the upstream tag, realign cordis
to 4.0.2 per the trimmed peer set, migrate every settings consumer onto
the ctx.settings service seam (installSection), declare the severed
dsh-client-ui-session type-graph edge for git-graph, and refresh the
CI cohort cache, inject-contract pin, docs badges, and cohort-line
comments.
2026-08-30 23:33:20 +08:00
zhu1090093659 7ed689b6e5 fix(sdk): resolve the snapshot-store engine across host cohorts
The 0.1.2-alpha.1 migration externalized dsh-client-store as a frozen
platform module, so every client bundle hard-required it at evaluation;
the running 0.1.1-rc.2 hosts (npm latest - the preview cohort is
unpublished) cannot answer that require and the loader refused the
family entries (missed the module table). Redirect the store's value
imports in the shared client preset to a generated shim that resolves
the engine through the loader require at bundle evaluation - platform
module first, the identical dsh-client-runtime/client face second - so
one artifact serves both cohorts. Rebuild the committed market artifact
and record the decision.
2026-08-28 20:52:27 +08:00
zhu1090093659 a2ffaa5669 Merge branch 'dev' into sdk/0.1.2-alpha.1
# Conflicts:
#	.agents/notes/implemented/simplification/2026-08-28-remove-dsh-aionui-panel.i18n.yaml
#	README.en.md
#	README.md
#	packages/AGENTS.md
#	packages/dsh-perf/README.i18n.yaml
#	packages/dsh-perf/README.md
#	packages/dsh-perf/README.zh.md
#	packages/dsh-remote-web-ui/README.i18n.yaml
#	packages/dsh-remote-web-ui/README.md
#	packages/dsh-remote-web-ui/README.zh.md
#	packages/dsh-remote-web-ui/src/gate.ts
#	packages/dsh-remote-web-ui/src/index.ts
#	packages/dsh-remote-web-ui/src/mobile-api.ts
#	packages/dsh-remote-web-ui/tests/mobile-api.spec.ts
#	packages/dsh-web-all/README.i18n.yaml
#	packages/dsh-web-all/aggregate.yml
2026-08-28 19:52:20 +08:00
zhu1090093659 c7eb3d4d04 feat(dsh-web-all): remove dsh-aionui-panel completely 2026-08-28 19:23:06 +08:00
zhu1090093659 c3b211f646 chore(sdk): clear the 0.1.2 migration debris found by review
- dsh-web-all READMEs no longer claim the removed aionui-panel ships in
  the aggregate; dsh-perf READMEs and renderDegrade copy stop advertising
  the assistant-step shadow whose slot is gone upstream, and the orphaned
  perf-assistant-shadow.tsx is deleted.
- pet and remote-web-ui notExposed copy adopts the corrected wording (the
  dsh-host-apiproxy WEB_SETTINGS_NAMESPACES allowlist no longer exists).
- Dead libExternal entries for the deleted dsh-client-runtime are removed
  (pet, git-graph, community-plugins), dead client-runtime mocks are
  dropped (describe-image, remote-web-ui), skin-center's unused
  api-workspace-controller inject is trimmed, and the mount e2e comment
  matches the removal.
- shared/host/dsh-home.ts gains its final newline and the ten consumer
  copies are resynced; leftover review debug output and stale aionui
  comments are cleaned.
- Record the review evidence archive and the bug-fix Agent Note
  (.agents/notes/implemented/bug-fix/2026-08-28-descriptor-faithful-wire-contracts).
2026-08-28 15:39:56 +08:00
zhu1090093659 1faa36969d fix(shared): judge settings saves by read-back after the atomic mutate
The 0.1.2 SettingsScope.mutate never rejects: a refused mutation recovers
with a fresh Host view and resolves, so save() reporting success on
resolution dropped the user's staged drafts on any Host refusal. save()
now keeps the single atomic mutate but judges every planned write against
the settled snapshot (set: the user layer holds the value; unset: the
field is gone; one miss fails the whole save and keeps the drafts), while
still surfacing bridge-scope rejections. Secret sets are judged by
settlement because the Host strips role('secret') fields from every wire
view and the snapshot exposes no secrets sidecar (documented). The fake
scope in the tests now encodes the real resolve-on-refusal contract, and
the package copies are regenerated by sync-shared.
2026-08-28 15:39:37 +08:00
zhu1090093659 7797f34b81 wip(sdk): adopt the atomic settings mutation in the shared card form
- CardForm.save dispatches one scope.mutate(path-ops) instead of the
  removed per-field compat batch surface; either every write lands or the
  failure surfaces with its host rejection message
- the describe-image tests import the CallId brand as ToolCallId under
  the 0.1.2 llm faces and drop the client-runtime test imports
- the pet and shared fake scopes gain the mutate contract member
2026-08-28 13:09:27 +08:00
zhu1090093659 3a4c4b114e chore(sdk): refresh sync-shared copy buckets and stale apiproxy wording
- the copy-count buckets lose the four dsh-aionui-panel entries removed
  with the package (98/39/47)
- the not-exposed settings copy and the shared settings-form comment now
  describe the 0.1.2 exposure model (owning plugin settings domain) instead
  of the deleted host-apiproxy allowlist
2026-08-28 10:18:30 +08:00
zhu1090093659 da6fec2934 wip(sdk): migrate dsh-pet off the deleted client-runtime package
- pet store engine imports move to dsh-client-store (same defineStore
  contract, promoted upstream into the frozen platform table)
- settings scope types via dsh-client-ui-settings/client; sessions via
  api-session-controller/client; slots merge via client-ui-renderer/client
- test mocks follow the new module paths; shared settings-form spec
  (now live under the spec include) covers the migrated shared source
- shared devDependencies gain dsh-client-store for its own spec run
2026-08-28 08:52:33 +08:00
zhu1090093659 1c3a89d352 wip(sdk): migrate doctor, git-graph, contracts to the 0.1.2-alpha.1 faces
- doctor: settings scope via ui-settings/client, store engine via
  dsh-client-store, sessions port via api-session-controller/client,
  slots merge via client-ui-renderer/client; inject list follows the
  runtime roster
- git-graph: same remap; SessionSnapshot.composerPhase is gone, the
  blank empty-log mirror plus openState now drives the branch-selector
  seat; worktree session launch moved to ISessions.create
- shared: platform table mirrors the 0.1.2 frozen module table (client-store
  in, client-runtime out), preset drops RUNTIME_STORE_EXEMPTION and the
  dead host-apiproxy branch; the platform contract spec becomes runnable
  (renamed to *.spec.ts so the shared vitest include matches)
- aggregate: freeze dsh-aionui-panel for this cohort (discontinued,
  unbuildable without client-runtime) pending the maintainer's final call
- sync-shared: settings-form shared source migrated, copies resynced
2026-08-28 08:37:18 +08:00
zhu1090093659 054e03c63b chore(sdk): point the official SDK cohort at the 0.1.2-alpha.1 preview
The 0.1.2-alpha.1 cohort is a developer preview that is not published to
npm, so every @deepseek-ai package is resolved from tarballs built from
the official source tag deepseek-harness@dsh-v0.1.2-alpha.1 (commit
cd5ef81) via a pnpm-workspace.yaml overrides block. Remove that block
once the cohort reaches registry.npmjs.org.

- bump every @deepseek-ai/dsh-* range to ^0.1.2-alpha.1 (shared pins exact)
- drop devDependencies on the two removed upstream packages:
  dsh-client-runtime and dsh-host-apiproxy
- refresh minimumReleaseAgeExclude pins; drop the two dead entries
- bump dsh.engines to >=0.1.2-alpha.1 across plugin manifests
- pin packageManager to pnpm@11.24.0: 11.9.0 misapplies overrides for
  transitive dependencies of file: tarballs and hits the registry
2026-08-28 08:07:58 +08:00
zhu1090093659 bc72119eb9 fix(shared): structural ctx type in pair-access so the shared package typechecks standalone
Root pnpm typecheck failed: shared sources must not import
@deepseek-ai/cordis (no such dependency in the shared package). The
fence now reads a structural two-member context shape that cordis
Context satisfies; wrapper signatures and behavior are unchanged.
2026-08-27 01:41:06 +08:00
zhu1090093659 e7c74daefa refactor(shared): consolidate the pairing trust fence into shared/host/pair-access.ts
Git-graph, pet, and skill-explorer carried byte-identical fence logic.
The decision now lives in one shared source distributed as generated
sync-shared copies; each package keeps a self-describing thin wrapper.
Canonical tests added under shared/tests; wrapper specs stay as wiring
tests.
2026-08-27 01:20:12 +08:00
zhu1090093659 f5d779ffa5 fix(settings-card): keep the card header inside the card bounds
The shared PluginSettingsCard header (header / headerStatic) used
width: 100% plus 14px 16px padding without border-box. The suite does not
force a global border-box, so the flex row rendered 32px wider than the
card; the trailing pending (unsaved) badge - the row's last flex item -
hung 15px outside the card's right border, reading as a stray chip at the
panel's top-right. Add box-sizing: border-box to both header rows and
re-sync every family copy. Verified in the GUI: the badge now sits inside
the card with the regular 16px padding.
2026-08-25 16:43:05 +08:00