@12-apps/desktop-shell

中文文档
1.3.0发布于 2026/11/04MITES Module零依赖构建来源已验证近 30 天下载 3.2万

The reusable half of a desktop AGENT: a background Electron app that signs in against the host's own web sign-in page (no second credential path), keeps working from the tray with every window closed, and starts with the machine on Windows, macOS and Linu

原始使用文档
文档目录7 节
  1. The problem it solves
  2. The rule that shapes everything: no second way to sign in
  3. Surfaces
  4. Two facts, one word
  5. Crashes, updates and releases
  6. It carries no words
  7. Adoption

@12-apps/desktop-shell

The reusable half of a background desktop agent: an Electron app that signs in against the host's own web sign-in page, keeps working with every window closed, and starts with the machine on Windows, macOS and Linux.

pnpm add @12-apps/desktop-shell electron

The problem it solves

Some work cannot be done by a tab, and the list is short and stubborn:

  • reach a device on the shop's own network (a printer, a scale, a drawer);
  • print without a dialog;
  • keep running when the browser is closed;
  • start when the machine does.

A product that needs any of those grows a small desktop companion. That companion is ~90% the same every time — sign in, stay signed in, hold one connection, do the work, survive, say how it is going in one tray icon — and the remaining 10% is the whole point of the app. This package is the 90%.

The rule that shapes everything: no second way to sign in

A desktop app must not collect a password. The moment it does, the product has two authentication paths: the web one — rate limits, lockout, e-mail verification, OAuth buttons, password reset, copy in every language — and a text field in a native window that has none of those and never will be kept level with the first.

So the shell opens the host's own sign-in page in a window and watches for the session cookie to land. A provider added on the web is available to the agent the same day, and there is no credential handling in this package at all: grep -ri password src/ returning nothing is the invariant.

   tray icon ─┐
              ├─ sign-in window ──▶ the host's /sign-in page ──▶ cookie
   the work ──┘                                                   │
        ▲                                                         │
        └──────────── net.fetch bound to the same partition ◀──────┘

Surfaces

ExportWhat it is
@12-apps/desktop-shellThe status a tray draws (deriveShellStatus) and the supervisor that keeps background work alive. Pure.
…/autostart"Start with the machine" across the three platforms — a login item on macOS/Windows, an XDG .desktop file on Linux.
…/sessionThe cookie watch, the local sign-out, and guardSession — a 401 moves the tray, a 403 does not.
…/telemetryCrash reports that outlive the crash: a session marker, breadcrumbs, a disk queue, and lost-run / crash / failed-install detection. Pure.
…/updatesSelf-updating over the host's own electron-updater: createUpdateManager, createAutoInstall, updateBanner, createMenuGate, and the menu bar with the updater under Help (buildAppMenu, updateText). Pure.
…/electronThe adapter: single instance, tray, windows-hide-never-close, background start, startDesktopShell, startCrashReporting, updaterFileLogger, sessionCookieReader, installAppMenu and wireUpdates (the updater joined to the menu, the window strip, breadcrumbs and auto-install through one install path).
…/serverThe web host's half: serveDesktopAsset / serveNamedDesktopAsset (disk first, then a presigned redirect through the host's storage port; the channel .yml streamed; a coded 404 otherwise), platformFor, and the crash-report intake — desktopReportSchema (zod, an optional peer), describeDesktopReport, createReportBudget. Node-only.
bin desktop-shell-upload-releasePuts a release's files in an S3-compatible bucket from any CI runner with Node — no aws binary.

Everything but …/electron and …/server is framework-free and runs in a plain Node test — which is how the autostart quoting and the status ranking are asserted on a machine with no display.

Two facts, one word

A session and a live link fail separately and recover separately. An agent that collapsed them into one boolean could not tell a person which to fix, so they are tracked apart and deriveShellStatus is the one place they become a word.

The ranking is an order of what to do next, not of severity: a missing session outranks a dropped link (the link is a consequence), and a local fault outranks the link (the link recovers on its own; a fault does not).

degraded is not an error. It means the live link is down and the host's fallback poll is carrying the work — slower, not broken. A host that nags somebody over degraded is nagging them over a reconnect.

Crashes, updates and releases

A tray program fails where nobody is looking, and every fix to it would otherwise cost a phone call. So the package also carries the three things that make an agent maintainable from a distance:

  • Telemetry. startCrashReporting() writes a session marker at start and removes it on a clean quit. A marker left behind is reported as a crash only when Crashpad wrote a dump in that run — a Windows shutdown leaves one too, with no dump. A restart to install that came back as the OLD version is reported as install-failed and never retried by itself — but only two minutes after the restart was asked for: on Windows the old binary can come back for a few seconds before the installer closes it and starts the new version, which then reads the restart as planned and reports nothing (FUT-3309). Reports queue on disk and flush(send) delivers them through whatever route the host owns; a 4xx that will not change is dropped instead of blocking the queue.
  • Updates. createUpdateManager checks once a day plus whenever the host asks, downloads in the background, and never lets a skipped check overwrite a version already downloading or ready. The host passes its autoUpdater (this package does not depend on electron-updater) and answers settings() per check with the switch and the feed URL — null while setup is unfinished. A gated feed gets the session as a Cookie header via sessionCookieReader. macOS reports unsupported: Squirrel.Mac refuses an unsigned update after downloading it.
  • Releases. desktop-shell-upload-release <key-prefix> <file>... uploads with @aws-sdk/client-s3 (an optional peer), as a buffer so the object is byte-for-byte the file's size. A missing file is reported and skipped; no bucket configured is exit 0 with a note.

It carries no words

Not one sentence, in any language. A tray menu, a tooltip, a window title and a startup-list entry are all copy, and copy is the host's — so TrayCopy is a required pack and ShellState.fault is a code, not a message. The reader here is a shop owner, and the words are most of the product.

Adoption

See ADOPTING.md.

版本与发布记录

@12-apps/desktop-shell 共发布 8 个版本,首次发布于 2026/09/23;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.3.0latest2026/11/042 天前
1.2.12026/10/1027 天前
1.2.02026/09/261 个月前
1.1.02026/09/261 个月前
1.0.32026/09/241 个月前
1.0.22026/09/231 个月前

关于 @12-apps/desktop-shell 的常见问题

@12-apps/desktop-shell 是什么?

The reusable half of a desktop AGENT: a background Electron app that signs in against the host's own web sign-in page (no second credential path), keeps working from the tray with every window closed, and starts with the machine on Windows, macOS and Linu

如何安装 @12-apps/desktop-shell?

在项目目录运行 npm install @12-apps/desktop-shell,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 desktop-shell-upload-release,可以用 npx desktop-shell-upload-release 直接运行。

@12-apps/desktop-shell 支持 TypeScript 吗?

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

@12-apps/desktop-shell 支持 ESM 还是 CommonJS?

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

@12-apps/desktop-shell 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@12-apps/desktop-shell 可以商用吗?

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

@12-apps/desktop-shell 的下载量有多少?

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

@12-apps/desktop-shell 还在维护吗?

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