* feat(preset): declare Agent compositions in profile YAML * fix(preset): share scope binding cleanup and refresh module graph * fix(preset): use host syntax colors in the YAML editor * fix(preset): write new profile declarations as block YAML * fix(preset): align eager activation with browser and worker surfaces * fix(ui-agent-preset): retain the existing preset card layout * fix(preset): keep rows waiting for a Host service mounted and re-audit after settlement A preset row whose Host provider was still activating at declaration time was reported as waiting for a missing service, and the registry recorded the definition as broken for the rest of the process. Split the mount audit into failed and pending rows: failures and root-realm leaks still reject the mount, while pending rows stay mounted and every read and binding re-audits them after the Host Loader tree settles. Remove the accidental self-dependency of @deepseek-ai/dsh-web-app and its lockfile self-link. Archive the copy-only preset authoring note, which the declarative-preset note fully supersedes, and update the ralph note's restore recipe to the profile-patch mechanism. * chore(lint): re-key and prune the unknown-cast baseline after the master merge * refactor(web-app): ship each Agent preset as its own bundle patch file `dsh.bundle.patch` accepts an ordered file list, so the four shipped preset declarations move out of the 1000-line web patch into `presets/<id>.patch.yml`, one insert per file, applied after the host patch. The host patch keeps the preset registry row. Gates and test scaffolds that read the web layer resolve every patch file through `bundlePatchPaths` instead of one hardcoded path. * refactor(preset): drop the save notice injected into live Agents The notice duplicated the save result the Web editor already shows, and after the producer-owned message sources it would have needed its own persisted source kind. Saving now only persists and reports the activation diagnostic; the persistence catalog is unchanged from master. * docs: regenerate the module graph after dropping the registry's llm dependency * test(ui-agent-preset): cover the guide dialog's keyboard handling on the declarative section * fix(preset): address the remaining review comments Apply the lowercase id rule only when creating a declaration, so presets declared with other ids stay editable. Export `isBuiltInPreset` from the display fold and key the client card groups on it. Remove the dead `error` and `retry` locale keys, the JSDoc orphaned by the `trust` removal, the `trust` fields in the plugin-inventory test fixtures, and the stale `dsh-agent-presets` package name in comments and READMEs. * refactor(preset): make the Web preset page view-and-select only Remove the child-plugin YAML editor, the `agent_preset` tool and the registry's read/save Remote methods. Presets are declared and changed only by bundle patches; the settings page keeps the roster, the new-task default and the mode help, and its question icon explains that and offers to start a Creator-mode task. The `editing-cordis-compositions` skill and the Creator persona describe the bundle-based path, and the authored skill-load Session and Web snapshots are refreshed for it. * docs(skill): make the composition skill self-sufficient for preset authoring State where the shipped declarations live, list every declaration field, inline a complete minimal bundle and an override example, and name the verification calls, so Creator mode no longer reads DSH package sources to infer the format. Refresh the authored skill-load Session for the new text. * test(tools): drop the removed agent_preset tool from the catalog expectation
description, kind
| description | kind |
|---|---|
| Browser-worker harness hosting for maintainers building or debugging the experimental Web preview runtime. | package-library |
@deepseek-ai/dsh-experimental-webworker-runtime
English | 中文
Summary
The browser worker host: the whole harness plugin tree runs inside one dedicated Web Worker, for preview deployments and packaging regressions (experimental group). The worker inflates a packed VFS image off its download and mounts it in memory, loads its modules through a CommonJS wrapper loader, and serves the page over a postMessage tunnel that speaks plain HTTP. Use it when a preview must run the packaged harness without a Node host.
Table of Contents
Use this package
The public npm package exposes the runtime library at its root, the self-contained browser Worker at ./worker, and the page connector at ./client. Deployments supply and serve the VFS image separately through the packer; installing this library does not add a profile layer. The root also exports the module-proxy and replacement tables used by the packer.
Three build artifacts and one source-owned process layer:
lib/index.js(assembly library) —createWorkerHost/startWorkerHostmount the base image and any ordered data overlays (storage/), install the module loader (module-system/) and theprocessshim, boot the tree through the image's owndsh-app-boot, and hand the tunnel its serving seams. Overlays may replace files only underhome/andworkspace/; they cannot replace the base manifest, configuration, or modules. The image layout contract (image-layout.ts: virtual root, config/manifest paths, empty directories, theloweredwrapper-contract gate) is shared with the packer. Boot patches select plaintext JSONL session logs. Preset declarations are part of the composed configuration.lib/worker.js(worker bundle) — the assembly plus this package's Node-compatibility layer as one self-contained ES module. The module proxy table (module-proxies.ts) is the only platform fork:node:*builtins over VFS/tunnel/browser primitives, structural stubs that fail loud on the console for what a browser cannot do, and native/binary package replacements.node:modulesuppliescreateRequire().resolveand.resolve.paths()over the image package root, so unchanged packages can discover manifests without evaluating their modules. Thenode:utilJSON-data comparator compares own enumerable properties, preserving Node admission decisions for recorded fields such as__proto__. The globalprocessshim carries Node detection fields includingtitle, preventing Worker execution from entering DOM-only branches. The pack-time parser reports statically named module requests, including module-scope direct calls of the formcreateRequire(import.meta.url)('pkg')through a namednode:moduleormoduleimport, to the packer's reachability walk. Stored, CommonJS-obtained, and rebasedcreateRequirecalls require image entry seeds. VFS mutations drivenode:fscallback, polling, and promise watchers; open descriptors retain file identity and access mode across rename, replacement, and unlink,FileHandle.stat({ bigint: true })reports the same device and inode identity as a path stat while the name still refers to that file, andFileHandle.chmod()updates the opened file identity;readable-streamsupplies the stream state machine used by file streams and unchanged image packages such as Chokidar and readdirp. AsyncLocalStorage carries sync-stack causality acrossawaitthrough the snapshot/restore faces the pack-time lowering injects. The worker holds no compiler: an image the packer did not lower is refused at mount. The callbackfs.realpath.nativealias resolves within the mounted VFS and supportsutil.promisify.src/shell/(the worker's own process layer) — a browser worker cannot fork, sonode:child_processis not a stub but an implementation:spawnstarts the command in its own Web Worker — this same bundle, told by its first frame to be a shell process — and reports it through theChildProcesssurface the subprocess service consumes. The command runs off the host's thread,SIGKILLterminates it whatever it is doing, and it reaches the VFS only by message (the host serves those frames). Worker platform executables preserve native-package protocols such as Landlock without replacing their JavaScript packages or coupling their implementations tonode:child_process; ordinary commands use the package's evaluator and coreutils command table. The grammar is@yarnpkg/parsers'parseShell, whileexecSync/forkstill refuse because they need a real process.lib/client.js(page half) — startup has two independent stages.chooseWorkerHostSource({ image?, fixtureManifest? })optionally owns the boot barrier and fixture manifest: withoutpreview-fixtureit waits at the source chooser, while a valid query selects directly; either path returns ordered overlays.connectWorkerHost(worker, { image?, overlays? })remains the public base-runtime connector; callers that skip the chooser get an empty overlay list.apps/webinvokes both and supplies its statically bundled Worker. The openinginitframe carries the base and ordered overlay URLs, the boot payload delivers the structured index-injection table, andapplyIndexInjectionsexecutes it before the shell entry runs. Script preload rows are advisory and skipped because/pluginsresources resolve only through the tunnel;loadBundlefetches each combo on first demand, embeds its tunnel-only source map as a Base64 data URL, and executes the script as a Blob. The tunnel also exposes fetch-shaped transport, the independent file-upload carrier, and the API client. Request frames preserve Blob bodies through structured clone and transferReadableStream<Uint8Array>ownership. The Host Worker streams both forms into the route, so neither browser thread creates a complete byte array for a generic-file upload. A Remote stream's uplink crosses asstream-uplink-item/stream-uplink-endframes into an unboundedTunnelUplinkthat drops items arriving afterend: the page and its worker are one trusted same-origin boundary, so the Host inbox cap does not apply.
Acceptance lives in apps/web/tests/preview-boot.e2e.ts, which serves the real built pages and drives the pre-boot chooser plus Worker activation in headless Chromium. The empty selection exercises first-run startup. The vfs-example overlay supplies ordinary workspace files and plaintext persistence artifacts for cold Workspace/Session discovery, tool presentation, subagent navigation, and history paging without a model request. The packer prepares current-generation successors from committed historical logs in Node; those source logs remain byte-identical in the overlay. The fixture generator owns the acceptance test's current projection cache. The chooser reserves WebFS as a separate user-authorized source; that provider does not read the built-in fixture.
The built-bundle import sweep checks bare Node imports after the library build. Its Dockkit exception accepts Node’s unknown-.css-extension refusal for any stylesheet rather than one pinned path; another extension, error code, or message, and an unexpectedly successful exempt import, remain errors. See the stylesheet exemption decision.
Model Experience
None, as this package only hosts the tree in a browser worker and answers its node:* calls; every model-facing registration belongs to the plugins it boots.
KV Cache effect
None; this package neither assembles nor sends a provider request.
Known Limitations and Deferred Work
- The worker composition writes plaintext session logs (
compression: 'none'boot patch): it carries no Zstandard codec, so exported logs are.jsonl, never.jsonl.zstd. node:dns/promises,node:vm,node:net,node:sqlite,node:worker_threadsare structural stubs: every call reports its refusal on the console and throws. Rows needing native DNS, a real process, or realm isolation cannot run here.- Host package commands are unavailable:
execareports an explicit worker-host refusal; the preview cannot run pnpm or install native dependencies. - PTC Node programs are unavailable: the process shim exposes
/dsh/bin/nodeas its executable identity so the provider can activate, but the Worker has neither a Node executable norstripTypeScriptTypes. Program execution fails before launching a child. - Office conversion requires a Node Host: the LibreOffice kit replacement rejects converter creation with
unavailable. The browser image excludes the kit and its engine dependencies; the Office preview reports that conversion is unavailable. - Filesystem watchers observe only the mounted VFS: image seeding is silent and the VFS has no symlinks or external writers.
persistent,ref(), andunref()preserve the Node API but cannot control a dedicated Worker's lifetime because browsers expose no ref-counted event loop. - Worker confinement is a VFS boundary, not kernel Landlock:
read-onlyandworkspace-writerun the unchanged@deepseek-ai/node-addon-system/landlock-runJavaScript and launcher argv, but the process layer implements the logicallandlock-runexecutable and enforces its grants on every shell filesystem request.fulltherefore covers the Worker command table and mounted VFS only; it does not claim arbitrary native-process execution or Linux kernel isolation. - The worker bundle pins a path inside
@yarnpkg/parsers— the build resolves the package's ownlib/shell.jsinstead of its root, whose barrel also re-exports the Syml parser and so drags js-yaml into a bundle that never parses that format (around 175 kB, plus its module body at worker start). The path is derived from the package manifest, so a layout change fails the build rather than reinstating the barrel; upgrading the dependency means re-checking that the shell parser still lives there. - The shell is not bash: no loops, functions,
case, job control, or process substitution — the grammar stops at pipelines,&&/||, subshells, groups, redirections, and expansion.&runs its command to completion in place,sedaccepts only substitution scripts, patterns are JavaScript regular expressions, and the command table holds coreutils only (nogit, no network tools). - A shell process has no synchronous filesystem: it reads and writes the host's VFS by message, because blocking on a reply would need
SharedArrayBuffer, which requires a cross-origin isolation GitHub Pages cannot grant. Directory-walking commands therefore cost one round trip per entry, and two concurrent commands can interleave their writes. - Transport, worker-host, and page-half coverage needs a browser-grade harness — the per-file coverage gate is unmet for those modules; unit specs cover storage, ALS, the transform, and the stub contracts.
Dev Note
Working context for maintainers — click to expand
None.
Runtime invariant: No companion is published. This package is pre-Cordis platform glue — the tree it boots runs the product packages' own invariants, and the assembly's contracts (image contract gate, tunnel refusals) fail loud at boot rather than drifting at run time.