dshbase

插件目录 / UI & Skins / dsh-genie

dsh-genie

已验证 · 实测可装 swaylq

✓ 持续维护

查看 GitHub ↗ ← 返回插件目录

1Stars
0Forks
0未关闭 issue
—语言
2026-08-15最近推送
跨平台平台

功能简介

Wishes that outlive the session — turn a DeepSeek Harness agent's runtime plugins into permanently installed ones. No pnpm, no network, no build authorization.

✅
我们的评价
可用 — 实测通过,早期项目

Wishes that outlive the session — turn a DeepSeek Harness agent's runtime plugins into permanently installed ones. No pnpm, no network, no build authorization. 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

🪔 dsh-genie

Wishes that outlive the session.

DeepSeek Harness can already write its own plugins.
It just can't keep them. This is the other half.

English | 中文


The gap

DeepSeek Harness ships a self-referential toolset — cordis_inspect, cordis_define,
cordis_run — that lets the agent write a plugin and hot-load it into the live process.
You describe a feature, the agent builds it, and it works right now.

Then you restart, and it's gone. From the official README of that toolset:

Dynamic packages live only in the shared DSH process memory. […] They create no Plugin file,
install no package, change no cordis.yml or personal/project configuration, do not survive
restart, and cannot be promoted automatically.
To keep an experiment, ask the Agent to
implement a normal local, project, or repository Plugin through the regular development workflow.

dsh-genie is that "regular development workflow", collapsed into one tool call.

The loop

you  ▸ every time I say "ship it", stage everything and commit with a generated message

     ▸ agent writes the plugin, cordis_run mounts it            ← ships with DSH
     ▸ you try it. it works.
     ▸ "keep it"
     ▸ genie_keep dyn-1 → dsh-wish-ship-it                      ← this package

     ▸ restart
     ▸ still there.

Two extra facts that make this pleasant:

  • No pnpm, no network, no build authorization. A granted wish is written straight into
    $DSH_HOME/genie/ and linked where the launcher already resolves modules. Compare that to
    the normal path for a git-installed plugin, which needs a prepare script from the author
    and an allowBuilds grant from you — arbitrary code execution at install time, outside
    every sandbox the agent runs in.
  • It's just files. Every wish is a readable directory with a package.json, a
    cordis.patch.yml, and an index.js. Read it, edit it, git init it, publish it.
    dsh-genie never rewrites a wish after granting it.

Install

dsh plugin --profile web add github:swaylq/dsh-genie

Then restart dsh. That's it — plain JavaScript, no build step, so there is no prepare
script and nothing to authorize.

Already have your own @deepseek-ai/dsh-tool-cordis row? See Composition.

What you get

genie_keep Take a dynamic package the agent just proved out and make it permanent. Only appears when the dynamic-package runner is composed.
genie_wish Same, for code the agent wrote directly — no prototype step.
genie_list Every wish on this machine, and whether it's live in this profile.
genie_revoke Unlist and unlink a wish. Keeps the source unless you ask otherwise.
/wish The human view: what's granted, what's active, where the code lives.

The bundle also mounts @deepseek-ai/dsh-tool-cordis, DeepSeek Harness's own
self-modification toolset. It ships inside every install but the stock web profile
doesn't mount it — its runner already is, so switching it on costs no install.

How it works

Three facts about the launcher, none of them private API:

  1. A profile resolves bundles through two anchors — the dsh installation, then the profile
    directory. Node's ordinary parent walk from <profile>/package.json reaches
    $DSH_HOME/profiles/node_modules, the flat fallback directory the launcher maintains so
    in-box plugins resolve from any profile.
  2. That directory is append-only in practice. healProfilesModuleFallback keeps correct
    links, re-points moved ones, and never prunes what it doesn't own — so a link planted there
    survives every later boot.
  3. dsh plugin won't reclaim the layer. Its reconcile pass only removes a bundle whose name
    is (or was) a profile dependencies key. dsh-genie writes to dsh.profile.bundles and never
    to dependencies, so dsh plugin add anything-else leaves your wishes alone.

So granting a wish is: write the package → symlink it into the fallback → append one name to
the profile's ordered bundle list. No installer, no registry, no build.

One wrinkle worth knowing, because it bites everyone once: Node resolves a package's imports
from its real directory, not from the symlink used to find it.
A wish in $DSH_HOME/genie/
would walk genie → $DSH_HOME → ~ and never see the fallback, so dsh-genie plants
$DSH_HOME/genie/node_modules → $DSH_HOME/profiles/node_modules beside the wishes. That
puts every in-box package back on the walk. For the same reason dsh-genie itself declares no
runtime dependency at all — it loads @deepseek-ai/dsh-tools through the profile, the way
the launcher resolves its own bundles, so it works from a link: checkout, a git install, an
npm install, or a directory you dropped in by hand.

Trust stance

Read this before you install it, not after.

A granted wish is ordinary code that runs at every boot, with the harness's full context.
That is the point of the package, and it is also the whole risk. dsh-genie does not add a
capability your agent lacked — an agent with bash access could already write these files — but
it does make it one tool call instead of a visible sequence of them, which is exactly the kind
of convenience worth being explicit about.

What the design does about it:

  • Nothing runs in the session that wrote it. A grant writes files and edits one manifest.
    The code loads on the next restart, which only you can perform. That restart is the
    checkpoint, and every tool result says so.
  • Nothing is executed to be validated. Generated modules are parse-checked with
    node --check, which parses without evaluating. A wish that doesn't parse installs nothing.
  • Everything is listable and reversible. /wish and genie_list show every wish and its
    source path; genie_revoke removes it. Revoke only accepts dsh-wish-* names, so a
    mistyped argument cannot unlist dsh-base.
  • Wish names are one validated path segment. No scopes, no dots, no traversal.

What it does not do: sandbox the wish, review the code for you, or ask a second time. If you
would not run a script an agent wrote without reading it, read the wish before you restart —
the tool result hands you the exact path for that reason.

Upstream's stance on the toolset this builds on is the same one, and worth repeating: the vm
sandbox behind cordis_run "isolates globals but is not a security boundary […] treat this
toolset like bash access."

Composition

The bundle inserts two rows: genie-tool-cordis and genie. If something else in your profile
already mounts @deepseek-ai/dsh-tool-cordis, both registrations claim the same tool names and
the load fails loudly (as DSH intends). Disable ours from your profile's cordis.patch.yml:

- id: genie-tool-cordis
  disabled: true

Config on the genie row:

key default meaning
allowUpdate true whether mode: "update" may overwrite an existing wish

Caveats

  • A kept dynamic package changes realms. cordis_define bodies run in a vm sandbox where
    Node globals are absent or redirected to Cordis services. A kept wish runs in ordinary Node,
    so a body written against those facades may need adjusting. genie_keep tells the model to
    say so when the code touches them; it cannot rewrite the code for you.
  • Layer order is append. A wish patches on top of dsh-base, the mode bundle, and every
    plugin installed before it. A patch replaces a row's whole config rather than deep-merging,
    so a wish that overrides an existing row must restate every key that row needs.
  • DSH is a developer preview. Upstream says breaking changes are coming. This package leans
    on documented launcher behavior rather than internals, but "documented" and "stable" are not
    the same thing yet.
  • The client half is stored, not mounted. genie_keep saves a client.js beside the host
    half for reference; wiring a browser half into the web UI is still manual work.

Development

npm test          # 19 tests, real throwaway Harness homes, no network

lamp.js is the whole install mechanism and imports nothing from DSH — it is plain node:fs
and testable on its own. index.js is the plugin surface.

License

MIT

Built on DeepSeek Harness (MIT) and
Cordis. Not affiliated with DeepSeek.

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-genie」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:swaylq/dsh-genie

Headless(CLI)profile:

dsh plugin --profile headless add github:swaylq/dsh-genie

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

UI & Skins 里更多

浏览全部 7819 个插件 →