DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

DonGeeo87 /

DonGeeo87/cg-shell-janitor

Verified

Closes DeepSeek Harness runner processes that stay alive after their shell command finished, reclaiming ~140 MB each. Windows only.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@6e736129

cg-shell-janitor

A DeepSeek Harness plugin for Windows that closes the runner processes DSH leaves behind after a shell command finished. Each one holds about 140 MB of RAM.

  • Español

The problem

On Windows every dsh shell call starts a private runner process:

"DeepSeek Harness.exe" "...\dsh-subprocess-local\lib\runner.js" -- ...\bash.exe -c "<your command>"

That runner owns the Win32 Job of the command. When the command ends the runner is supposed to exit on its own — its own poll() closes the empty Job and calls finish(0). In practice it often stays alive: measured on DSH Desktop 0.2.x, eight of them had accumulated in a single working session, 1127 MB, the oldest one four and a half hours old and completely idle.

Neither @deepseek-ai/dsh-subprocess-local nor dsh-ops exposes a shell lifetime setting, so there is nothing to configure. This plugin is the workaround.

What it does

Every intervalSeconds it looks for DSH runner processes and closes the ones that are provably doing nothing. Closing a runner releases its Win32 Job, which is the semantics DSH already uses for its own children.

It only acts when all of these hold:

  1. The runner's parent is still the DSH host process.
  2. The runner has no living child — its bash.exe already exited.
  3. None of the children it was ever seen with is still alive, so it is not babysitting a background process. The tree is re-learned on every sample, so a command that left a server running behind & keeps its runner protected.
  4. It is older than idleMinutes.
  5. There are no unattributable daemon-like orphans around. If there are, the plugin enters a conservative mode and closes nothing that cycle.

The first sample after startup only observes, so the plugin learns the tree before deciding anything. Nothing is deleted, and no process is touched other than the leaked runner itself.

Measured effect

Same machine, same session, right after the first real cycle:

Metric Before After
Live runners 8 (1127 MB) 2 (288 MB, both with a live shell)
Free RAM 3.37 GB 5.78 GB
Total processes 298 240

It closed three leaked runners and left the two that were running commands alone.

Configuration

In cordis.patch.yml:

Key Default Meaning
enabled true turn the cycle off without uninstalling
dryRun false only log what it would close
intervalSeconds 180 how often it samples (30–3600)
idleMinutes 5 minimum age before closing (1–1440)
reapOnStartup true first sample 20 s after startup

A cycle costs about 2 seconds of one core every three minutes: it runs one Get-CimInstance query through PowerShell. Raise intervalSeconds if that matters to you.

Log: ~/.dsh/shell-janitor.log, rotated at 256 KB.

Install

From the dsh-market catalog (one click), or from a local checkout:

dsh plugin --profile <your-profile> add <path-to-this-directory>

Then restart the harness.

Remove

dsh plugin --profile <your-profile> remove cg-shell-janitor

Scope and limitations

  • Windows only. The leak is in the Win32 Job-owning runner. On other platforms the plugin logs one line and does nothing.
  • It is a heuristic, not a fix. The real fix belongs upstream: the runner should exit by itself.
  • A runner created before the plugin loaded whose shell already exited has no children on record. It is still closed once it passes idleMinutes, because condition 5 only guards against orphans the plugin cannot attribute at all.
  • If you deliberately keep a daemon alive from a shell command and the plugin never observed that command, the daemon is protected only by the conservative mode, not by an exact match.

License

MIT.


Español

Plugin para DeepSeek Harness en Windows que cierra los procesos runner que DSH deja vivos después de que su comando terminó. Cada uno ocupa unos 140 MB.

En Windows cada llamada a dsh crea un proceso runner que es dueño del Job de Win32 del comando. Cuando el comando termina debería salir solo, pero muchas veces queda vivo: medido en DSH Desktop 0.2.x, en una sola sesión de trabajo se acumularon ocho, 1127 MB, el más viejo con cuatro horas y media de antigüedad y sin hacer nada.

Ni @deepseek-ai/dsh-subprocess-local ni dsh-ops exponen un ajuste de vida del shell, así que no hay nada que configurar. Este plugin es el parche.

Cada intervalSeconds busca runners y cierra los que no están haciendo nada. Solo actúa si el runner no tiene hijo vivo, no supervisa ningún proceso que se le haya conocido, es más viejo que idleMinutes y no hay huérfanos de tipo demonio que no sepa atribuir (si los hay, entra en modo conservador y no cierra nada). La primera muestra después de arrancar solo observa.

Log en ~/.dsh/shell-janitor.log. Configuración en cordis.patch.yml. Solo Windows. Licencia MIT.

—/ 5

No ratings yet

Verified DSH bundle

Commit 6e736129e569

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout