@daugasauron/dolly

中文文档
0.1.5发布于 2026/11/07MITES Module零依赖近 30 天下载 2718

Dolly's runtime: a POSIX-like userspace for wasm64 in a browser tab. Run images with boot().

原始使用文档
文档目录7 节
  1. A page
  2. More host modules
  3. Colours
  4. Popups
  5. Serving
  6. Your own image
  7. Host modules

Embedding Dolly

Dolly is a POSIX-like userspace for wasm64 that runs in a browser tab: a Wasm kernel, programs in private Wasm memories, and host modules that bridge it to the browser. These npm packages put it in a page of your own. Their first use is an agent in place of a web frontend (docs/agent-frontend.md in the repository).

PackageWhat it holds
@daugasauron/dollyThe runtime: boot(), the kernel, the process runtime, its image builder, and the host modules that are its own machinery (runtime, http, threads, dso, stack, nena, snapshot, packages)
@daugasauron/dolly-host-NAMEOne device host module each: display (Ghostty's terminal and programs' frames), input, gpu, audio, microphone, touch, download (as dolly-host-save: npm takes no new name with the word), upload, html, sockets, pty
@daugasauron/dolly-image-NAMEAn image's directory for boot(): default (a shell, its text tools, the terminal, curl, amy, nena, ps, html), pi-minimal (the Pi coding agent with JavaScript, a shell, POSIX tools, curl, ripgrep and fd, on display, input, download and html alone: the README's "Pi with npm"), python-data (default with Python 3.14, pip, the C compiler, NumPy, pandas, Matplotlib and seaborn). Its README gives the install line and the FROM row of a recipe built on it. Its amy-index.txt lists the packages the image holds, so amy list and amy info describe them
@daugasauron/dolly-package-NAMEA package for an image of your own: git (with diff and patch), cc (the C and C++ compiler with Make), python (3.14 with pip; it brings libffi and cc), numpy, pandas, matplotlib, seaborn and python-dateutil. Its directory holds its catalog, metadata, packs and recipes, as an image's does, and nothing to boot; it depends on the packages it installs, so npm installs them with it
@daugasauron/dolly-buildThe dolly-build command: a project with an image of your own, FROM pi-minimal with the packages it INSTALLs, built in a browser into a site a static host serves ("Your own image" below)
npm install @daugasauron/dolly @daugasauron/dolly-image-default \
  @daugasauron/dolly-host-display @daugasauron/dolly-host-input @daugasauron/dolly-host-save \
  @daugasauron/dolly-host-upload @daugasauron/dolly-host-html

Each host module and image depends on the runtime alone, at its own version, and a package also on the packages it installs. An image or package does not depend on the host modules it declares: install them with it (its README names them), so that all lie side by side under node_modules/@daugasauron/. npm, pnpm and Yarn 1 install them so. Yarn 2 and later need nodeLinker: node-modules in .yarnrc.yml: Plug'n'Play leaves no files to serve.

A page

<!doctype html>
<meta charset="utf-8">
<main id="dolly" style="position:fixed;inset:0"></main>
<script type="module">
  import { boot } from "./node_modules/@daugasauron/dolly/src/browser.mjs";
  import { images, image, modules } from "./node_modules/@daugasauron/dolly-image-default/index.mjs";
  const dolly = await boot(document.querySelector("#dolly"), { images, image, modules });
</script>

boot(element, options) runs an image in element, which the page sizes. It resolves once the image's program starts, to the page's handle on the session (hostModules, visibleTerminalText(), waitForInteractiveTerminal(pattern), then submit(command) at the shell's prompt, and what each module adds), and shows its own failure in the element. What Dolly shows, its modules' buttons, dialogs and indicators among them, stays inside element, and its styles select only there; keys typed outside it, into the page's own controls, are the page's.

OptionMeaning
imagesURL of an image directory: dist/dolly-images.json, the images' metadata and packs, their recipes, all data. @daugasauron/dolly-image-default's index.mjs exports its own. A page has one image directory. The packs an image reads stay in the origin's private storage, so it starts again without downloading them (src/pack-store.mjs)
imageThe image to run, by name
modulesURLs of the module.json of each host module the page has. The registry loads these and no other; an image's REQUIRES HOST must be among them
siteOptional: the URL of a site that serves Dolly's own pages (session/, sessions/, docs/), as Dolly's site does. Given, a saved session names itself in the tab's URL as the site's session route and modules link to those pages
httpOptional { policy, relays } for the HTTP broker, the page's one network edge (docs/http.md). Without a policy a program may fetch any HTTPS URL
filesOptional { "/absolute/path": text or Uint8Array }, written over the image before its program starts: Pi's instructions and skills (docs/agent-frontend.md), a start script. Programs can read them; they are not for secrets
sessionOptional: the name of a session saved in this browser, opened as it was saved in place of a fresh start (files are not written over it). It needs snapshot@0, whose Save (Ctrl+Shift+S) keeps a session in the browser's storage for the page's origin and, on a page without a site, names it in the tab's address as ?session=NAME for the page to give back here

The page, not the image, chooses the modules and the policy, before anything of the image runs. A program reaches nothing of the browser but through them.

More host modules

default declares nena@0, so a session can enable a module the page has and the image does not declare. Install its package and add its module.json:

npm install @daugasauron/dolly-host-gpu @daugasauron/dolly-host-microphone @daugasauron/dolly-host-pty
const gpu = new URL("./node_modules/@daugasauron/dolly-host-gpu/module.json", location.href).href;
const dolly = await boot(element, { images, image, modules: [...modules, gpu] });

nena enable gpu then gives a program the GPU, or, where the browser has no WebGPU adapter, a device that fails to open with ENODEV.

Colours

The terminal's colours and the popups' are the page's, not the image's. Set these on the element (or above it) in your style sheet to match your page; unset, they are Dolly's:

#dolly {
  --dolly-background: #262626;          /* the terminal's and the popups' */
  --dolly-color: #e8e3d7;               /* their text */
  --dolly-accent: #f2d45c;              /* the cursor and the selection; the popups' headings, buttons, focus */
  --dolly-display-palette-1: #e8e3d7;   /* -0 to -15: the 16 colours programs name */
}

Unset, of the 16 colours programs name, black (-0) is the background, yellow and bright yellow (-3, -11) the accent, bright black (-8) #77736c and the others the text's colour, so a program's red shows as its text does. A value may be any CSS colour; one that is not counts as unset. The terminal takes them at boot and whenever they change, by any rule or media query; a popup as it opens.

Popups

html@0 shows a program's HTML document in a popup over the terminal, in boot()'s element: a report, or a form whose submitted fields go back to the program (Pi's ask_user and show_html). The popup takes the document's text, headings, lists, tables and forms and nothing else of it; its look is the page's: the colours above and these, unset Dolly's:

#dolly {
  --dolly-html-font: ui-monospace, monospace;
  --dolly-html-color-scheme: dark;       /* the form controls' own colours */
  --dolly-html-font-file: none;          /* or url(…): the font of the first family above */
}

The popup loads nothing itself: the page fetches the font file, once, and hands the popup its bytes; without one, name fonts the system has. The page reads the properties each time a popup opens. Dolly's site sets "Dolly IosevkaTerm SemiBold", monospace and its font file.

Serving

  • Serve the installed packages as they lie: the runtime finds its own files beside itself, and dolly-image-default's index.mjs finds the modules in the packages installed beside it under node_modules/@daugasauron/.
  • Send Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp with the page: Dolly needs shared memory, which a browser gives only to a cross-origin isolated page.
  • Serve .wasm as application/wasm, .mjs as text/javascript and .json as application/json: a browser imports a host module's manifest and an image directory's catalog and metadata only with that type.
  • No bundler is needed: these are ES modules, Workers and Wasm files.

Your own image

dolly-build builds a Dollyfile (docs/dollyfile.md in the repository) FROM the installed pi-minimal, with the packages whose directories are installed beside it, into a site: a directory that any static host serves as it lies. The build runs in a headless browser, with the installed runtime's own builder, as the catalog's images are built; the command serves the packages to it on 127.0.0.1 and writes what it hands back. Nothing of it, nor of the site, the page or the image, fetches from the network: after npm install, the packages hold every file. The build's browser reaches that server and the URLs of the recipe's own SOURCE rows alone; its own requests (its vendor's updates, clock and autofill) go to a proxy of the command's that refuses them.

npm install @daugasauron/dolly-build @daugasauron/dolly-package-git
npx dolly-build init my-pi git
npx dolly-build Dollyfile-my-pi my-pi
  • dolly-build init NAME [PACKAGE…] writes a project where the packages are installed, and refuses to write over a file: Dollyfile-NAME (the host modules of pi-minimal and of each package, FROM pi-minimal and INSTALL of each package at the installed pins, rows for Pi's instructions, a skill, an extension, a tool and the script that starts Pi, and pi-minimal's ENTRY) and public/, the page's files: index.html (the policy, the popups' font, and the files of workspace/ and theme.json for boot()'s files, listed by workspace.json), theme.json (the sandbox's colours: Pi's theme, written over the image's at boot, whose background, text, accent and muted the page sets as the terminal's and the popups') and workspace/README.md; and, unless the project has one, a .gitignore for node_modules/ and the site. It names the host module package to install when a package needs one the page lacks (python's sockets). The repository README's "Pi with npm" says what each file is for.
  • The recipe is the one place that declares the sandbox. Add rows before ENTRY: FILE with a body (indented four spaces) for a file, INSTALL of a package whose directory is installed (every package it needs comes with it, so python brings cc), SLOP to run the image's tools at build time. FROM carries the base's files, environment and exports but not its host modules or ENTRY, so the recipe repeats those; a package's REQUIRES HOST rows must be among the recipe's, and the build names a missing one. A recipe is at most 128 KiB; /workspace is never part of an image (boot()'s files writes the project at each boot).
  • dolly-build Dollyfile-NAME OUT writes the site OUT, replacing the one it wrote there before: the files of public/, workspace.json (the files under public/workspace/), the runtime (dolly/), the device host modules the recipe declares (dolly-host-NAME/), coi-serviceworker.js and image/, the image's directory as an image package lays it out (its catalog, metadata and packs, the recipes it was built from, its amy-index.txt and an index.mjs). The page imports ./dolly/src/browser.mjs and ./image/index.mjs. An image this recipe built on this runtime is kept, so a change to public/ alone takes seconds. --browser chrome (the default: your Chrome), chromium or firefox (Playwright's, after npx playwright-core install chromium or firefox). Both commands run where the packages are installed: the directory whose node_modules/@daugasauron/ holds them (npm, pnpm and Yarn 1 alike). A row that names an image no installed package holds at that pin fails naming the row.
  • Serve OUT with any static file server, python3 -m http.server -d OUT on your machine. Where the host sends the isolation headers ("Serving" above) the page is isolated; where it does not, init's page registers coi-serviceworker.js, which adds them to the site's own responses, and loads again under it.
  • A recipe may start FROM another installed image instead, python-data say: its package's README gives the FROM row, and the recipe repeats the image's REQUIRES HOST rows (a FILE of the project's own script and a SLOP that runs it at build time, for example). init writes Pi's project only; the page in public/index.html is then one as in "A page" above that imports ./dolly/src/browser.mjs and ./image/index.mjs, with the lines of init's page that register coi-serviceworker.js for a host without the headers.
  • An image is built for the installed versions: after the packages update, the rows' pins are others (init in an empty directory writes the new ones), and it is built again. Packages of two versions in one node_modules fail the build, naming both.

Host modules

A host module is a directory with a module.json; its provider receives what it needs from the runtime through the registry, and a device module imports nothing outside its directory. host/README.md in the repository describes the interface.

版本与发布记录

@daugasauron/dolly 共发布 8 个版本,首次发布于 2026/10/30;过去 12 个月发布了 8 个版本。

版本发布日期距今
0.1.5latest2026/11/075 天前
0.1.5-rc.0rc2026/11/066 天前
0.1.42026/10/3112 天前
0.1.4-rc.32026/10/3112 天前
0.1.4-rc.22026/10/3013 天前
0.1.4-rc.12026/10/3013 天前

关于 @daugasauron/dolly 的常见问题

@daugasauron/dolly 是什么?

Dolly's runtime: a POSIX-like userspace for wasm64 in a browser tab. Run images with boot().

如何安装 @daugasauron/dolly?

在项目目录运行 npm install @daugasauron/dolly,或使用 pnpm add / yarn add / bun add。

@daugasauron/dolly 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/daugasauron__dolly 是否存在。

@daugasauron/dolly 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@daugasauron/dolly 可以商用吗?

@daugasauron/dolly 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@daugasauron/dolly 的下载量有多少?

根据 npm 官方下载统计,@daugasauron/dolly 在 2026/10/12 – 2026/11/10 这 30 天内被下载 2,718 次,日均约 91 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@daugasauron/dolly 还在维护吗?

最新版本 0.1.5 发布于 2026/11/07(5 天前);至今共发布 8 个版本,其中过去 12 个月发布了 8 个;首次发布于 2026/10/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。