Skip to content
dsh.fish
Bundle

dsh-run

DSH web plugin: the Session header grows a split button that runs one npm script from the workspace's package.json (default: dev, else start, else the first declared).

Source
albertgranados
License
MIT
Updated
Updated 11 hours ago

Readme

# dsh-run

Plugin del **DeepSeek Harness** que añade, arriba a la derecha de la cabecera de
sesión (junto al botón *Open in…*), un **botón compuesto para los scripts de
`npm`** del proyecto abierto.

```
┌──────────────────────┬─┐
│ ▶  npm run dev       │▾│      ← el botón principal ejecuta el script por defecto
└──────────────────────┴─┘      ← la flecha despliega TODOS los scripts del package.json
```

> **English**: a DeepSeek Harness web plugin. The Session header grows a split
> button (play + chevron) that runs one script from the workspace's
> `package.json`: the main button runs the default (`dev`, else `start`, else the
> first declared), the chevron lists and runs every script and makes it the new
> default. It renders nothing when the workspace has no `package.json` scripts,
> turns into a stop button while a script is alive, and shows the failure output
> when a launch dies early. See [English](#english) at the end.

## Qué hace

- **Lee `package.json`** del directorio de trabajo de la sesión (el `cwd`).
- **Solo aparece si hay `package.json` con scripts.** Sin manifiesto, o sin
  `scripts`, el botón no se renderiza: no queda ni un hueco vacío.
- **Botón principal**: muestra el icono de *play* y el comando por defecto
  (`npm run dev`). Al pulsarlo, lo ejecuta. Mientras corre, el icono cambia a
  *stop* y un segundo clic detiene el proceso (grupo de procesos completo:
  `npm → sh → el servidor`).
- **Desplegable**: lista todos los scripts declarados como `npm run <script>`.
  Al elegir uno, **se ejecuta** y pasa a ser **el nuevo por defecto** del botón
  de play. La elección se recuerda por proyecto en el navegador
  (`localStorage`, clave `dsh-run.defaults`).
- **Por defecto automático**: `dev`; si no existe, `start`; si tampoco, el
  primer script del manifiesto.
- **Fallo visible**: si un script muere con código distinto de cero en los
  primeros 30 s, el botón se pinta en rojo y el *tooltip* trae la última línea
  de su salida. Un script ya en marcha no se relanza por doble clic: la petición
  reutiliza la ejecución viva.

## Rutas host

| Ruta | Qué hace |
| --- | --- |
| `GET /dsh-run/scripts?cwd=<abs>` | Scripts del `package.json`, el defecto automático y la tabla de ejecuciones de ese proyecto. |
| `POST /dsh-run/run` | `{ cwd, script }` → `npm run <script>` en ese directorio. |
| `POST /dsh-run/stop` | `{ cwd, script }` → termina el grupo de procesos de esa ejecución. |
| `GET /dsh-run/log?cwd=&script=&bytes=` | Cola de salida recogida (stdout/stderr) de una ejecución. |

Todas pasan primero por el filtro de confianza del harness
(`connection.requestRejection`): mismo cerco Host/Origin y misma cookie de
sesión que el resto de la API. Además, cada ruta con cuerpo valida el JSON en el
borde y **vuelve a resolver el proyecto en el host**: el directorio debe ser
absoluto y existir, y el script pedido debe estar declarado en su propio
`package.json`.

Los procesos se lanzan por el servicio `subprocess` del harness, así que
`terminate()` alcanza a todo el grupo de procesos, la salida queda legible
después de salir y **descargar el plugin detiene lo que él mismo arrancó**.

## Instalación

```bash
# desde GitHub (público)
dsh plugin --profile web add github:albertgranados/dsh-run

# o desde un checkout local (queda enlazado: editar y reiniciar)
dsh plugin --profile web add /ruta/a/dsh-run

# y reinicia el harness
```

El paquete declara `dsh.bundle.patch`, así que el propio `dsh plugin`
reconcilia `dsh.profile.bundles` solo: no hay que editar `package.json` ni
`cordis.patch.yml` a mano. No hay build: `lib/index.js` y `lib/client.js` van
compilados a mano en el repo (el cliente se sirve crudo al navegador, no pasa
por ningún bundler).

Tras reiniciar, recarga la página del navegador (`http://127.0.0.1:3080`). El
botón solo aparece en sesiones cuyo workspace tenga un `package.json`.

### Desinstalar

```bash
dsh plugin --profile web remove dsh-run
```

## Verificación rápida

```bash
# ¿está la fila del plugin en el árbol del perfil?
dsh --profile web --dump-config | grep -A2 dsh-run

# con el harness en marcha (necesita la cookie del navegador para las rutas)
curl -s "http://127.0.0.1:3080/dsh-run/scripts?cwd=$PWD" | head
```

## Notas

- El comando es siempre `npm run <script>`; `npm` se resuelve por el mismo
  mundo de ejecución que usa el resto del harness (`subprocess.resolveExecutable`).
- Variables de entorno: los hijos arrancan con el entorno del harness ya
  depurado por el propio harness (sin credenciales ni `DSH_*`), más
  `FORCE_COLOR=0` / `NO_COLOR=1` para que el log no lleve secuencias ANSI.
- Límites: como mucho 8 ejecuciones concurrentes, 32 KiB de cola en memoria por
  flujo y 4 MiB de *spill* en disco por ejecución (la ruta completa del log
  sale en la cabecera de `/dsh-run/log`).

## English

A DeepSeek Harness web plugin: a Session-header split button for the workspace's
npm scripts.

- **Main button** (play icon + the default command, e.g. `npm run dev`) runs the
  default script — `dev`, else `start`, else the first one declared. While a run
  is alive it turns into a stop button, and a second click terminates the whole
  npm process group (`npm → sh → the dev server`).
- **Chevron** lists every script in `package.json` as `npm run <script>`.
  Picking one runs it and makes it the new default for that workspace, remembered
  in the browser (`localStorage`, key `dsh-run.defaults`).
- **Renders nothing** when the workspace has no `package.json` scripts, or before
  the host answers.
- An early non-zero exit paints the button red and the tooltip carries the last
  line of that run's output; the dress clears after 8 seconds.

Install:

```bash
dsh plugin --profile web add github:albertgranados/dsh-run
# restart the harness, then reload the browser page
```

Host routes (all behind the harness's Host/Origin fence and login cookie):

| Route | Purpose |
| --- | --- |
| `GET /dsh-run/scripts?cwd=<abs>` | Scripts, auto-picked default, live run table. |
| `POST /dsh-run/run` | `{ cwd, script }` → `npm run <script>`. |
| `POST /dsh-run/stop` | `{ cwd, script }` → terminate that run's process group. |
| `GET /dsh-run/log?cwd=&script=&bytes=` | Collected stdout/stderr tail. |

MIT licensed.

Install

dsh plugin --profile web add github:albertgranados/dsh-run

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source