@perrylink/dsh-github 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.es.md CHANGED
@@ -1,129 +1,90 @@
1
- <h1 align="center">dsh-github</h1>
2
-
3
- <p align="center">
4
- <b>Trae GitHub a DeepSeek Harness.</b><br/>
5
- Crea pull requests · revisa PRs con comentarios en línea o de resumen · gestiona issues · busca — cada escritura requiere aprobación humana y el token nunca se registra.
6
- </p>
7
-
8
- <p align="center">
9
- <a href="README.md">English</a> ·
10
- <a href="README.zh-CN.md">中文</a> ·
11
- Español ·
12
- <a href="README.pt.md">Português</a> ·
13
- <a href="README.hi.md">हिन्दी</a>
14
- </p>
15
-
16
- <p align="center">
17
- <img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="License: Apache 2.0">
18
- <img src="https://img.shields.io/badge/dsh-0.1.0--rc.6-4D6BFE" alt="dsh: 0.1.0-rc.6">
19
- <img src="https://img.shields.io/badge/dsh-dsh--plugin-4D6BFE" alt="dsh-plugin">
20
- <img src="https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen" alt="Node: ^22.19 || >=24">
21
- <img src="https://github.com/PerryLink/dsh-github/actions/workflows/ci.yml/badge.svg" alt="CI">
22
- <img src="https://img.shields.io/badge/documents-EN%2FZH%2FES%2FPT%2FHI-8257D0" alt="Documents: EN/ZH/ES/PT/HI">
23
- </p>
1
+ <div align="center">
24
2
 
25
- ---
3
+ # dsh-github
4
+
5
+ **PRs, revisiones, issues y CI de GitHub para DeepSeek Harness — cada escritura aprobada por un humano y el token nunca registrado.**
6
+
7
+ *Crea, revisa, fusiona y busca en GitHub desde el agente, con una acción compuesta de CI, un bot de revisión por sondeo y una puerta de status-check.*
26
8
 
27
- **dsh-github** es un plugin bundle para [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh`) — el agente harness «todo es un plugin». Cubre el vacío de GitHub entre dsh y herramientas como [Claude Code](https://github.com/anthropics/claude-code) (`gh claude` / [claude-code-action](https://github.com/anthropics/claude-code-action)) y [Codex](https://github.com/openai/codex) (`@codex review` / Autofix CI): tu agente puede **leer una PR, revisar una PR, abrir una PR, fusionar y actualizar PRs, leer metadatos de repositorios y archivos, comentar y cerrar issues, y buscar** — mientras un humano aprueba cada escritura y el token permanece en secreto.
9
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
12
+ [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-github/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-github/actions)
13
+ [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-github?label=version)](https://github.com/PerryLink/dsh-github/releases)
14
+ [![npm version](https://img.shields.io/npm/v/%40perrylink%2Fdsh-github)](https://www.npmjs.com/package/@perrylink/dsh-github)
15
+ [![npm downloads](https://img.shields.io/npm/dm/%40perrylink%2Fdsh-github)](https://www.npmjs.com/package/@perrylink/dsh-github)
28
16
 
29
- - 🛠 **12 herramientas** — `pr_create` · `pr_merge` · `pr_update` · `gh_review` · `review_post` · `gh_issue` · `issue_open` · `issue_comment` · `issue_close` · `gh_search` · `gh_repo` · `gh_file`, todas con JSON canónico mediante `defineTool`
30
- - ⌨️ **3 familias de comandos** — `/pr create` · `/review` (start/stop/post) · `/issue open`
31
- - 🔀 **Ciclo de vida completo de PRs** — crear → revisar → actualizar (título/cuerpo/estado/rama base) → fusionar (merge/squash/rebase, borrado opcional de la rama head)
32
- - 📝 **Revisiones en línea** — `review_post` publica un único comentario de resumen o comentarios de revisión anclados por línea contra el commit head de la PR
33
- - 🔒 **Escrituras con aprobación** — cada escritura en GitHub pasa por `ctx.approval` (`ask` por defecto, se cierra ante fallo); los motivos de aprobación previsualizan títulos, tamaños de cuerpo y anulaciones de comentarios
34
- - 🗝 **Secreto del token** — capa de credenciales → entorno → CLI `gh`, resuelto por operación, nunca en registros, eventos, representaciones ni errores
35
- - ⏱ **Trabajos de revisión en segundo plano** — `/review` se ejecuta en `ctx.jobs` con la superficie propia del host `job_list` / `job_output` / `job_kill`, e informa del estado de CI y el recuento de comentarios junto a los hallazgos
36
- - 🤖 **Opción de revisión por modelo** — `reviewMode: "model"` delega el diff limitado a un subagente de un solo uso a través de la seam `subagents` del host; el modo `static` por defecto sigue siendo determinista y sin tokens
37
- - 🚦 **Reintento 429 + visibilidad de cuota** — el modelo ve el límite de velocidad restante en cada resultado, incluidos los fallos; los errores de obtención por sección se muestran en lugar de ocultarse
38
- - 🌐 **Documentación en 5 idiomas** — English · 中文 · Español · Português · हिन्दी
17
+ [English](README.md) · [简体中文](README.zh.md) · [Español](README.es.md) · [Português](README.pt.md) · [हिन्दी](README.hi.md)
18
+
19
+ </div>
39
20
 
40
21
  ---
41
22
 
42
23
  ## 📚 Tabla de contenidos
43
24
 
44
- - [Inicio rápido](#🚀-inicio-rápido)
45
- - [Características](#✨-características)
46
- - [Instalación](#📦-instalación)
47
- - [Configuración](#⚙️-configuración)
48
- - [Herramientas](#🛠-herramientas)
49
- - [Comandos](#⌨️-comandos)
50
- - [Arquitectura](#🏗-arquitectura)
51
- - [Límites de seguridad](#🔒-límites-de-seguridad)
52
- - [Limitaciones conocidas](#⚠️-limitaciones-conocidas)
53
- - [Desarrollo](#🧪-desarrollo)
54
- - [Estructura del repositorio](#🗂-estructura-del-repositorio)
55
- - [Temas](#🏷-temas)
25
+ - [Compatibilidad](#compatibilidad)
26
+ - [Qué obtienes](#qué-obtienes)
27
+ - [Inicio rápido](#inicio-rápido)
28
+ - [Instalación y desinstalación](#instalación-y-desinstalación)
29
+ - [Configuración](#configuración)
30
+ - [Herramientas y superficies](#herramientas-y-superficies)
31
+ - [Arquitectura](#arquitectura)
32
+ - [Permisos y datos](#permisos-y-datos)
33
+ - [Límites de seguridad](#límites-de-seguridad)
34
+ - [Limitaciones conocidas](#limitaciones-conocidas)
35
+ - [Desarrollo](#desarrollo)
36
+ - [Estructura del repositorio](#estructura-del-repositorio)
37
+ - [Temas](#temas)
38
+ - [Contribuidores](#contribuidores)
39
+ - [Familia de plugins DSH de PerryLink](#familia-de-plugins-dsh-de-perrylink)
56
40
  - [Licencia](#licencia)
57
41
 
58
- ## 🚀 Inicio rápido
42
+ ## Compatibilidad
59
43
 
60
- ```sh
61
- # 1. instalar (registro npm — lo más simple; o usa el canal tarball de abajo)
62
- dsh plugin --profile <name> add @perrylink/dsh-github
63
- # canal tarball (sin necesidad de registro):
64
- # pnpm pack → dsh-github-<version>.tgz
65
- # dsh plugin --profile <name> add ./dsh-github-<version>.tgz
66
-
67
- # 2. configure a GitHub token (recommended: the credentials seam)
68
- # $DSH_HOME/.credentials.yaml
69
- # GITHUB_TOKEN: <your token>
70
-
71
- # 3. use it — in the dsh web UI or headless
72
- # /pr create "add dark mode" → agent drafts & opens the PR (approval required)
73
- # /review 42 → background review job, read it with job_output
74
- # /review post github-review-1 → publish the review comment (approval required)
75
- # /issue open "crash on startup" → agent opens the issue (approval required)
76
- ```
44
+ | Superficie | Estado |
45
+ |---|---|
46
+ | Harness | DeepSeek Harness `0.1.0-rc.6` (compatibilidad declarada para `0.1.0-rc.5`–`0.1.0-rc.6`) |
47
+ | Node | `^22.19.0 \|\| >=24.0.0` |
48
+ | Plataformas | Todas (plugin host; red saliente a GitHub) |
49
+ | Modelo | Cualquiera (la revisión estática es determinista; `reviewMode: "model"` es opcional) |
77
50
 
78
- Verificación: `dsh --profile <name> --dump-config` debe mostrar la sección `# == dsh-github` con **ninguna línea FAILED**.
51
+ ## Qué obtienes
79
52
 
80
- ## ✨ Características
53
+ `dsh-github` cubre el vacío de GitHub entre `dsh` y herramientas como Claude Code y Codex: tu agente puede leer, revisar, abrir, actualizar y fusionar pull requests, leer metadatos de repositorios y archivos, comentar y cerrar issues, y buscar — mientras un humano aprueba cada escritura y el token permanece en secreto.
81
54
 
82
- | Área | Qué obtienes |
83
- |---|---|
84
- | **Crear PRs** | `/pr create [title]` lee el estado de git (rama, archivos modificados, commits por delante) y entrega un borrador al agente; `pr_create` abre la PR y devuelve su URL |
85
- | **Actualizar PRs** | `pr_update` edita título, cuerpo, estado o rama de destino — con aprobación como cualquier otra escritura |
86
- | **Fusionar PRs** | `pr_merge` fusiona con `merge`/`squash`/`rebase`, título/mensaje de commit opcionales y borrado de la rama head tras la fusión |
87
- | **Revisar PRs** | `gh_review` resume metadatos, diff limitado (texto completo en el valor canónico, extracto acotado en la representación), comentarios, estado de CI y hallazgos estáticos — los fallos de obtención por sección se informan como `diff.error` / `comments.error` / `ci.error` |
88
- | **Publicar revisiones** | `review_post` publica un comentario agregado a nivel de issue (`mode: "summary"`, por defecto) o comentarios de revisión anclados por línea en el commit head de la PR (`mode: "inline"`); una anulación de `body` permite que el modelo pula primero el comentario — tras la aprobación humana |
89
- | **Revisiones en segundo plano** | `/review <pr>` obtiene metadatos, el diff limitado, las comprobaciones de CI y los comentarios existentes en un job de `ctx.jobs`; la salida de finalización incluye el resumen de hallazgos, el estado de CI y el recuento de comentarios; `reviewMode: "model"` delega el diff a un subagente de un solo uso en lugar del analizador estático |
90
- | **Leer repositorios** | `gh_repo` lee los metadatos del repositorio: descripción, rama por defecto, visibilidad, estrellas, forks, issues abiertas, lenguaje, licencia, temas |
91
- | **Leer archivos** | `gh_file` lee un archivo en una rama/tag/commit con decodificación base64 y un límite configurable; los directorios devuelven un error estructurado |
92
- | **Leer issues** | `gh_issue` lista / obtiene / comenta; los pull requests en los listados se marcan como `kind: "pr"` |
93
- | **Gestionar issues** | `issue_open` crea, `issue_comment` comenta (también funciona en PRs), `issue_close` cierra con un motivo de estado opcional — todas con aprobación |
94
- | **Buscar** | `gh_search` consulta issues y pull requests con la sintaxis de búsqueda de GitHub, mostrando la cuota de búsqueda independiente |
95
- | **Aprobación** | `tools/pre-execute` pide `ctx.approval` para cada escritura; la lista blanca `allowedActions` deniega antes de preguntar |
96
- | **Seguridad del secreto** | El token se lee por operación y se envía solo en el encabezado Authorization; una prueba dedicada verifica que nunca aparece en ninguna salida visible |
97
- | **Resiliencia** | Reintento 429 con retroceso `Retry-After`/`x-ratelimit-reset`; las herramientas de lectura son seguras ante concurrencia; todas las llamadas respetan la cancelación |
98
- | **Observabilidad** | Visible para el modelo ⇔ registrado: todo lo que el modelo ve fluye a través de los eventos de sesión propios del host (`tool/result`, `user/message`, `command/run`, `approval/asked`…) |
99
-
100
- ## 📦 Instalación
101
-
102
- Cuatro canales documentados — elige uno.
103
-
104
- | Canal | Comando | Notas |
105
- |---|---|---|
106
- | **npm registry** | `dsh plugin --profile <name> add @perrylink/dsh-github` | Publicado en npm — el canal más simple |
107
- | **Tarball npm** | `dsh plugin --profile <name> add ./dsh-github-<version>.tgz` | Se distribuye con `lib/` compilado — sin permiso de compilación |
108
- | **Fuente git** | `dsh plugin --profile <name> add "github:PerryLink/dsh-github#<sha>"` | Requiere `prepare` + `allowBuilds` (ver abajo); fija el commit |
109
- | **Enlace local** | `pnpm link --dir .` y luego `dsh plugin add @perrylink/dsh-github` | Desarrollo |
55
+ - **12 herramientas** — `pr_create`, `pr_merge`, `pr_update`, `gh_review`, `review_post`, `gh_issue`, `issue_open`, `issue_comment`, `issue_close`, `gh_search`, `gh_repo`, `gh_file`, todas con JSON canónico mediante `defineTool`.
56
+ - **3 familias de comandos** — `/pr create`, `/review` (start/stop/post), `/issue open`.
57
+ - **Ciclo de vida completo de PRs** — crear → revisar → actualizar (título/cuerpo/estado/rama base) → fusionar (merge/squash/rebase, borrado opcional de la rama head).
58
+ - **Revisiones en línea** — `review_post` publica un único comentario de resumen o comentarios de revisión anclados por línea contra el commit head de la PR.
59
+ - **Escrituras con aprobación** — cada escritura en GitHub pasa por `ctx.approval` (`ask` por defecto, se cierra ante fallo); los motivos de aprobación previsualizan títulos, tamaños de cuerpo y anulaciones de comentarios.
60
+ - **Secreto del token** — capa de credenciales → entorno → CLI `gh`, resuelto por operación, nunca en registros, eventos, representaciones ni errores.
61
+ - **Trabajos de revisión en segundo plano** — `/review` se ejecuta en `ctx.jobs` con la superficie propia del host `job_list` / `job_output` / `job_kill`.
62
+ - **Resiliencia** — reintento 429 con retroceso `Retry-After`/`x-ratelimit-reset`; las herramientas de lectura son seguras ante concurrencia; todas las llamadas respetan la cancelación.
63
+ - **Superficie CI** — la herramienta de un solo uso `ci_run`, un bot de revisión por sondeo y una puerta de status-check (acción compuesta `action.yml`).
110
64
 
111
- > El paquete npm se publica bajo el alcance `@perrylink` porque el nombre sin alcance `dsh-github` pertenece a un proyecto ajeno en el registro. El nombre de módulo del plugin sigue siendo `dsh-github`.
65
+ ## Inicio rápido
112
66
 
113
- Instalaciones git: pnpm ≥10 rechaza el `prepare` de una dependencia git hasta que esté en la lista permitida — `dsh` imprime la clave exacta; cópiala en el `pnpm-workspace.yaml` del perfil:
67
+ ```sh
68
+ # 1. instala el bundle en tu perfil
69
+ dsh plugin --profile web add "github:PerryLink/dsh-github#main"
70
+
71
+ # o desde npm (versiones publicadas)
72
+ dsh plugin --profile web add @perrylink/dsh-github
114
73
 
115
- ```yaml
116
- allowBuilds:
117
- '@perrylink/dsh-github': true
74
+ # 2. reinicia y verifica la fila
75
+ dsh --profile web --dump-config | grep -A3 'id: dsh-github'
118
76
  ```
119
77
 
120
- El script `prepare` (`scripts/prepare.mjs`) es autocontenido: compila con TypeScript cuando hay un compilador disponible; de lo contrario, recurre a los **artefactos `lib/` confirmados** y falla de forma evidente si no hay ninguno.
78
+ ## Instalación y desinstalación
121
79
 
122
- **Desinstalación:** `dsh plugin --profile <name> remove @perrylink/dsh-github`.
80
+ - **canal git** (último `main`): `dsh plugin --profile web add "github:PerryLink/dsh-github#main"` — el script `prepare` compila solo con dependencias de producción.
81
+ - **canal npm** (versiones publicadas): `dsh plugin --profile web add @perrylink/dsh-github`.
82
+ - **canal tarball**: `pnpm pack` en este repositorio y luego `dsh plugin --profile web add ./dsh-github-<version>.tgz`.
83
+ - **desinstalar**: `dsh plugin --profile web remove dsh-github` (o elimina la fila del parche de perfil).
123
84
 
124
- ## ⚙️ Configuración
85
+ ## Configuración
125
86
 
126
- Validado con Schemastery en el momento de carga (falla de forma evidente). Sobrescribe cualquier clave en el `cordis.patch.yml` del perfil (se reemplaza la configuración completa de la fila, nunca se fusiona en profundidad).
87
+ Todos los ajustes son campos `Config` de Schemastery (modificables desde cordis.yml). Una anulación dirigida por id reemplaza toda la fila — vuelve a indicar cada clave que necesites. `cordis.patch.yml` documenta cada clave en línea.
127
88
 
128
89
  | Clave | Por defecto | Significado |
129
90
  |---|---|---|
@@ -150,97 +111,71 @@ Validado con Schemastery en el momento de carga (falla de forma evidente). Sobre
150
111
  | `workspaceDir` | process cwd | Directorio de trabajo para la inspección de git de solo lectura |
151
112
  | `ci` | `{ enabled: false, … }` | Sección de integración CI: bot de revisión por sondeo, puerta de status-check y la herramienta de un solo uso `ci_run` (contiene todas las claves `ci.*`) |
152
113
 
153
- ## 🛠 Herramientas
154
-
155
- | Herramienta | Tipo | Parámetros | Devuelve |
156
- |---|---|---|---|
157
- | `pr_create` | escritura | `title*`, `body?`, `base?`, `head?`, `draft?`, `ownerRepo?` | `{status:'created', url, number, title, state, draft, base, head, rateLimit}` o error estructurado |
158
- | `pr_merge` | escritura | `pr*` (número / `#n` / `o/r#n` / URL), `mergeMethod?`, `commitTitle?`, `commitMessage?`, `deleteBranch?` | `{status:'merged', merged, sha?, message, url, branchDeleted, branchDeleteNote?, rateLimit}` o error estructurado |
159
- | `pr_update` | escritura | `pr*` (número / `#n` / `o/r#n` / URL), `title?`, `body?`, `state?` (`open`/`closed`), `base?` | `{status:'updated', url, number, title, state, base, rateLimit}` o error estructurado |
160
- | `gh_review` | lectura | `pr*` (número / `#n` / `o/r#n` / URL), `fields?`, `maxDiffChars?` | metadatos, diff limitado (texto completo `diff.text` + extracto acotado `diff.excerpt` + estadísticas por archivo), comentarios, CI, hallazgos estáticos, campos de `error` por sección, límite de velocidad |
161
- | `gh_repo` | lectura | `ownerRepo?` | `{repo, description, defaultBranch, visibility, stars, forks, openIssues, language, license, topics, url, updatedAt, rateLimit}` o error estructurado |
162
- | `gh_file` | lectura | `ownerRepo?`, `path*`, `ref?`, `maxChars?` | `{repo, path, ref, size, truncated, content, sha, url, rateLimit}` o error estructurado |
163
- | `gh_issue` | lectura | `action*` (`list`/`get`/`comments`), `ownerRepo?`, `issueNumber?`, `state?`, `limit?` | elementos normalizados (cada uno marcado `kind: issue/pr/comment`) + límite de velocidad |
164
- | `review_post` | escritura | `jobId*`, `mode?` (`summary`/`inline`), `body?` | `{status:'posted', mode, url, commentId?, reviewId?, findings, rateLimit}` o error estructurado |
165
- | `issue_open` | escritura | `title*`, `body?`, `labels?`, `ownerRepo?` | `{status:'created', url, number, title, rateLimit}` o error estructurado |
166
- | `issue_comment` | escritura | `issueNumber*`, `body*`, `ownerRepo?` | `{status:'commented', url, commentId, issueNumber, rateLimit}` o error estructurado |
167
- | `issue_close` | escritura | `issueNumber*`, `ownerRepo?`, `stateReason?` (`completed`/`not_planned`) | `{status:'closed', url, number, title, rateLimit}` o error estructurado |
168
- | `gh_search` | lectura | `q*`, `sort?`, `order?`, `perPage?` | `{query, total, items[{number,title,state,kind,author,url,repo,comments,createdAt}], rateLimit}` o error estructurado |
169
-
170
- `execute` devuelve solo el JSON canónico declarado por `output.schema`. Los fallos por token faltante y por la API de GitHub son variantes de error estructurado que llevan datos del límite de velocidad; los fallos de infraestructura se lanzan (→ `isError`). `exec.signal` se respeta en todas partes.
171
-
172
- ## ⌨️ Comandos
173
-
174
- | Comando | Efecto |
175
- |---|---|
176
- | `/pr create [title]` | Lee el estado de git y encola una instrucción `pr_create` para el modelo (cuerpo del borrador, valores por defecto, sin commit/push salvo `autoCommit`). La creación de la PR solicita aprobación. |
177
- | `/review <pr>` | Inicia un trabajo de revisión en segundo plano; imprime el id del trabajo. El host anuncia la finalización; léelo con `job_output`. |
178
- | `/review <pr> --max-diff <n> --no-ci --no-comments` | Anulaciones por trabajo: límite de diff y qué secciones suplementarias obtiene el trabajo. |
179
- | `/review stop <jobId>` | Cancela el trabajo (control local, sin escritura en GitHub). |
180
- | `/review post <jobId>` | Encola una instrucción `review_post` para el modelo (resumen o en línea); publicar solicita aprobación. |
181
- | `/issue open <title>` | Encola una instrucción `issue_open` para el modelo; crear solicita aprobación. |
182
-
183
- ## 🏗 Arquitectura
114
+ ## Herramientas y superficies
184
115
 
185
- ```
186
- ┌───────────────────────────────────────────────┐
187
- │ dsh-github │
188
- │ │
189
- humanos ─── /pr ────┼──► git reader (read-only) ──► agent.followup │
190
- /review ───┼──► ctx.jobs.start("github-review") ──► job │
191
- /issue ────┼──► agent.followup │
192
- │ │
193
- modelo ─── pr_create / pr_merge / pr_update / gh_review / │
194
- review_post / gh_issue / issue_open / issue_comment / │
195
- issue_close / gh_search / gh_repo / gh_file │
196
- (defineTool, canonical JSON only) │
197
- │ │
198
- └───────┬───────────────┬───────────────┬───────┘
199
- │ │ │
200
- tools/pre-execute credential GitHub REST
201
- approval gate resolution client (fetch,
202
- (ask | deny) (seam → env → 429 retry,
203
- gh CLI, per-op) rate-limit)
204
- ```
205
-
206
- - **Capa de credenciales.** `tokenSource: auto` resuelve por operación en el orden: capa de credenciales (referencia `GITHUB_TOKEN`) → variable de entorno → token de la CLI `gh`. El valor es una variable local entregada al cliente REST; nunca entra en valores canónicos, representaciones, tarjetas, salidas de comandos, avisos inyectados, salidas de trabajos, motivos de aprobación ni mensajes de error.
207
- - **Aprobación.** Todas las escrituras fluyen a través de las herramientas del modelo. Un listener waterfall `tools/pre-execute` devuelve `ask` para las siete herramientas de escritura, de modo que el registro le pregunta al humano mediante `ctx.approval` (el host registra el par de auditoría `approval/asked` + `approval/decided`) y se cierra ante fallo si no hay quien responda. Los motivos de aprobación previsualizan lo que se va a publicar (títulos, tamaños de cuerpo, métodos de fusión y la primera línea de un cuerpo de revisión anulado). Los comandos nunca escriben directamente: los manejadores de comandos se ejecutan sin un turno abierto, por lo que la capa de aprobación está estructuralmente cerrada para ellos — un comando de escritura reúne contexto de solo lectura y luego despierta al agente (`followup` cuando está inactivo, `inject` cuando está ocupado) para que el modelo ejecute la herramienta controlada dentro de un turno.
208
- - **Revisión en segundo plano.** `/review <pr>` inicia un trabajo `github-review` en `ctx.jobs` (etiqueta, propietario, tiempo límite, cancelable). El trabajo resuelve el token por operación, obtiene los metadatos de la PR (capturando el SHA del commit head para la publicación en línea), el diff limitado y —salvo que se desactive— las ejecuciones de comprobación de CI y los comentarios de revisión existentes, y luego ejecuta un analizador multiarchivo determinista (`src/review.ts`: secretos codificados, claves de API de Google, asignaciones de credenciales, artefactos de depuración, eval, marcadores TODO, líneas largas, cambios sobredimensionados) — cero tokens gastados, totalmente comprobable. Con `reviewMode: "model"`, el trabajo entrega el diff limitado a un subagente de un solo uso a través de la seam `subagents` del host (el agente propietario es el padre) y guarda la salida Markdown del hijo como el informe publicable; una seam o proveedor faltante falla de forma evidente. Los fallos de obtención de secciones suplementarias se anotan en la salida sin hacer fallar el trabajo. Los avisos de finalización llegan a la sesión iniciadora a través del consumidor `dsh-tool-jobs` del host; el modelo lee el informe mediante la herramienta existente `job_output` y lo publica con `review_post` — requiere aprobación.
209
- - **Visible para el modelo ⇔ registrado.** El plugin no añade **ningún tipo de evento de sesión personalizado**. Los tipos de eventos fuera del repositorio no están en `KNOWN_SESSION_EVENT_TYPES` del host, por lo que un evento obligatorio desconocido haría ilegible el registro de sesión tras eliminar el plugin (el host difiere deliberadamente una superficie de registro para plugins externos). Por tanto, todo el contenido visible para el modelo fluye a través de superficies registradas por el host: valores canónicos `tool/result`, avisos `user/message` mediante `agent.inject`/`agent.followup`, el par de ciclo de vida `command/run` + `command/done` y el par de auditoría `approval/asked` + `approval/decided`.
210
- - **Presentadores puros.** `presentCall`/`presentResult` son funciones puras de `args` (+ el `result.meta` persistido), idénticas en transmisión en vivo y en reproducción del registro. La creación de una PR muestra una tarjeta genérica con la URL de la PR.
211
-
212
- ## 🔒 Límites de seguridad
213
-
214
- - El token se lee por operación desde la fuente configurada (capa de credenciales, entorno o CLI `gh`) y se envía solo en el encabezado Authorization del cliente REST. Nunca se registra, nunca se representa, nunca se inyecta, nunca se añade al registro de sesión y nunca aparece en los mensajes de error.
215
- - Cada escritura en GitHub requiere `allowed-once` de `ctx.approval` (política `ask` por defecto); `rejected`, `cancelled` y `unavailable` fallan todas de forma cerrada.
216
- - `/pr create` nunca hace commit ni push por sí mismo; con `autoCommit: true`, el modelo realiza esas escrituras a través de la propia puerta de aprobación de la herramienta bash. dsh-github **no** gestiona la identidad de git (tarea de dsh-git-identity) ni los worktrees (tarea de dsh-worktree).
217
- - El trabajo de revisión no realiza escrituras: lee un diff y guarda un informe en la memoria del proceso; solo `review_post` publica, tras la aprobación.
218
- - Los comentarios publicados interpolan nombres de archivo derivados del diff, que son contenido de repositorio no confiable: `formatPostBody` escapa las comillas invertidas y escapa en HTML los nombres de archivo para que una PR hostil no pueda inyectar Markdown en el comentario de revisión.
219
- - El contenido de archivos leído por `gh_file` y los cuerpos de issues/PRs, los comentarios y los resultados de búsqueda leídos de GitHub son contenido externo no confiable que entra en el contexto del modelo — la misma contrapartida inherente que la obtención web; el plugin los marca como contenido externo en sus representaciones.
220
- - Límites de velocidad: los 429 se reintentan con retroceso y la cuota restante se muestra al modelo en cada resultado, incluidos los fallos.
221
-
222
- ## ⚠️ Limitaciones conocidas
223
-
224
- - **Sin eventos de sesión personalizados** — deliberado (ver Arquitectura); las pistas de auditoría se apoyan en el vocabulario de eventos propio del host.
225
- - **Analizador estático por defecto** — reglas deterministas (`src/review.ts`), cero tokens, reproducible. `reviewMode: "model"` delega el diff limitado a un subagente de un solo uso a través de la seam `subagents` del host para una revisión por LLM (consume tokens; requiere la seam y un proveedor registrado).
226
- - **Trabajos y registros locales al proceso** — el informe de revisión vive en la memoria del plugin indexado por el id del trabajo, coincidiendo con el ciclo de vida del registro de trabajos del host; el mapa de registros está limitado por `maxReviewRecords` (los registros finalizados más antiguos se eliminan primero).
227
- - **Las dist-tags `latest` de npm están obsoletas** — el plugin declara rangos de pares `^0.1.0-rc.5` para resolverse contra el cierre de perfil que proporciona `dsh-base`, y fija `0.1.0-rc.6` para desarrollo. Nunca instales con un simple `npm i @deepseek-ai/dsh-tools`.
228
- - **CI / GitHub Action** — incluido en este repositorio (v0.6.0): una acción compuesta (`action.yml`) que revisa PRs, arregla CI y escribe el informe; un bot de revisión por sondeo con comentarios inline idempotentes; y una puerta de status-check. Todas las escrituras siguen sujetas a aprobación.
229
-
230
- ## 🧪 Desarrollo
116
+ | Superficie | Tipo | Notas |
117
+ |---|---|---|
118
+ | `pr_create` | herramienta | Crea una pull request (escritura; con aprobación) |
119
+ | `pr_merge` | herramienta | Fusiona una PR (merge/squash/rebase, borrado opcional de la rama head) |
120
+ | `pr_update` | herramienta | Actualiza una PR (título/cuerpo/estado/rama base) |
121
+ | `gh_review` | herramienta | Lee una PR: metadatos, diff limitado, comentarios, CI, hallazgos estáticos |
122
+ | `review_post` | herramienta | Publica un comentario de revisión (resumen o en línea anclado por línea) |
123
+ | `gh_issue` | herramienta | Lista / obtiene / comenta issues (las PRs se marcan `kind: "pr"`) |
124
+ | `issue_open` | herramienta | Crea un issue |
125
+ | `issue_comment` | herramienta | Comenta un issue o una PR |
126
+ | `issue_close` | herramienta | Cierra un issue (motivo de estado opcional) |
127
+ | `gh_search` | herramienta | Busca issues y PRs (cuota de búsqueda independiente) |
128
+ | `gh_repo` | herramienta | Lee los metadatos del repositorio |
129
+ | `gh_file` | herramienta | Lee un archivo en una rama/tag/commit |
130
+ | `/pr create` | comando | Lee el estado de git y encola una instrucción `pr_create` |
131
+ | `/review` | comando | Inicia / detiene / publica un trabajo de revisión en segundo plano |
132
+ | `/issue open` | comando | Encola una instrucción `issue_open` |
133
+ | `ci_run` | herramienta | Revisión CI de un solo uso ejecutada por la acción compuesta / el driver CI |
134
+ | bot de revisión | superficie | Bot de revisión por sondeo con comentarios inline idempotentes (`ci.*`) |
135
+ | puerta de status-check | superficie | Publica el veredicto `success` / `needs-changes` por commit head de PR (`action.yml`) |
136
+
137
+ ## Arquitectura
138
+
139
+ - **Capa de credenciales.** `tokenSource: auto` resuelve por operación en el orden capa de credenciales (referencia `GITHUB_TOKEN`) → variable de entorno → token de la CLI `gh`. El valor es una variable local entregada al cliente REST; nunca entra en valores canónicos, representaciones, tarjetas, salidas de comandos, avisos inyectados, salidas de trabajos, motivos de aprobación ni mensajes de error.
140
+ - **Puerta de aprobación.** Todas las escrituras fluyen a través de las herramientas del modelo. Un listener waterfall `tools/pre-execute` devuelve `ask` para las herramientas de escritura, de modo que el registro pregunta al humano mediante `ctx.approval` (el host registra el par de auditoría `approval/asked` + `approval/decided`) y se cierra ante fallo sin un respondedor. Los comandos nunca escriben directamente: un comando de escritura reúne contexto de solo lectura y luego despierta al agente para que el modelo ejecute la herramienta controlada dentro de un turno.
141
+ - **Trabajo de revisión en segundo plano.** `/review <pr>` inicia un trabajo `github-review` en `ctx.jobs`; el trabajo obtiene metadatos (capturando el SHA del commit head para la publicación en línea), el diff limitado, las comprobaciones de CI y los comentarios existentes, y luego ejecuta el analizador determinista multiarchivo (`src/review.ts`). Con `reviewMode: "model"`, el trabajo entrega el diff limitado a un subagente de un solo uso a través de la seam `subagents` del host. La finalización llega a la sesión mediante el consumidor `dsh-tool-jobs` del host; el modelo lo lee con `job_output` y lo publica con `review_post`.
142
+ - **Acción compuesta de CI / bot de revisión / puerta de status-check.** El repositorio incluye una acción compuesta (`action.yml`) que revisa PRs, arregla CI y escribe el informe; un bot de revisión por sondeo publica comentarios inline idempotentes; y una puerta de status-check publica el veredicto por commit head de PR. La herramienta de un solo uso `ci_run` impulsa la ejecución headless. Toda escritura permanece sujeta a aprobación.
143
+
144
+ ## Permisos y datos
145
+
146
+ - **Permisos**: las escrituras cabalgan sobre la capa de aprobación oficial; nada se reimplementa ni se elude. El plugin declara `network:outbound` y `filesystem:write` en su manifiesto de workshop.
147
+ - **Datos**: el informe de revisión vive en la memoria del proceso, indexado por el id del trabajo; no se escribe nada duradero en disco.
148
+ - **Registro de sesión**: el plugin no añade tipos de evento de sesión personalizados; todo el contenido visible para el modelo fluye por superficies registradas por el host (`tool/result`, `user/message`, `command/run`, `approval/asked`…).
149
+
150
+ ## Límites de seguridad
151
+
152
+ - **Aprobación, no aplicación.** Las escrituras solo producen decisiones `ask`/deny en la capa oficial; el sandbox y los sistemas de aprobación siguen siendo la autoridad de aplicación.
153
+ - **Se cierra ante fallo.** La ausencia de respondedor de aprobación degrada a la decisión más estricta — nunca a un paso silencioso.
154
+ - **El token nunca sale del proceso.** Se lee por operación y se envía solo en el encabezado Authorization; nunca se registra, representa, inyecta ni aparece en errores.
155
+ - **Sin escrituras fuera de la aprobación.** `/pr create` nunca hace commit ni push por sí mismo; con `autoCommit: true`, el modelo realiza esas escrituras mediante la propia puerta de aprobación de la herramienta bash. El trabajo de revisión no realiza escrituras; solo `review_post` publica, tras la aprobación.
156
+ - **El contenido no confiable se escapa y se marca.** `formatPostBody` escapa en HTML y con comillas invertidas los nombres de archivo derivados del diff, y el contenido externo de GitHub (archivos, cuerpos, comentarios, resultados de búsqueda) se marca como externo en las representaciones.
157
+ - **Trabajo acotado y límites de velocidad.** Los 429 se reintentan con retroceso; la cuota restante se muestra en cada resultado, incluidos los fallos.
158
+
159
+ ## Limitaciones conocidas
160
+
161
+ - **Sin eventos de sesión personalizados** — deliberado (ver Arquitectura); las pistas de auditoría dependen del vocabulario de eventos propio del host.
162
+ - **Analizador estático por defecto** — reglas deterministas (`src/review.ts`), cero tokens, reproducible. `reviewMode: "model"` consume tokens y requiere la seam `subagents` y un proveedor registrado.
163
+ - **Trabajos y registros locales al proceso** — el informe de revisión vive en la memoria del plugin, indexado por el id del trabajo; el mapa de registros está limitado por `maxReviewRecords` (los registros finalizados más antiguos se eliminan primero).
164
+ - **Las dist-tags `latest` de npm están obsoletas** — instala mediante el cierre de perfil que proporciona `dsh-base`; nunca con un simple `npm i @deepseek-ai/dsh-tools`.
165
+
166
+ ## Desarrollo
231
167
 
232
168
  ```sh
233
- pnpm install
234
- pnpm test # vitest: config, credentials, 429/retry, tools, commands, jobs, approval gate, token non-leakage
235
- pnpm typecheck
236
- pnpm build # tsc → lib/ (noEmitOnError)
237
- pnpm pack # installable tarball
238
- pnpm run check:readmes # cross-checks TOC anchors, tools, and config keys in all 5 READMEs
169
+ pnpm install # node ^22.19 || >=24
170
+ pnpm run build # tsc --noEmitOnError → lib/
171
+ pnpm run prepare # compilación autocontenida para instalación git (scripts/prepare.mjs)
172
+ pnpm run prepublishOnly # compilar + probar antes de publicar
173
+ pnpm test # vitest run
174
+ pnpm run typecheck # tsc --noEmit
175
+ pnpm run check:readmes # cruza anclas de TOC, herramientas y claves de configuración en los 5 README
239
176
  ```
240
177
 
241
- Las pruebas simulan la API de GitHub, la CLI `gh` y git mediante runners inyectados — sin red, sin credenciales reales. `test/security.test.ts` verifica que la cadena del token nunca aparece en ninguna salida visible para el modelo o para el humano. `test/e2e.test.ts` contiene pruebas de humo optativas de la API real que se omiten automáticamente salvo que `DSH_GITHUB_E2E_TOKEN` esté definido (solo endpoints de solo lectura).
242
-
243
- ## 🗂 Estructura del repositorio
178
+ ## Estructura del repositorio
244
179
 
245
180
  ```
246
181
  src/index.ts plugin entry (name/inject/apply, applyWithDeps for tests)
@@ -260,12 +195,36 @@ cordis.patch.yml bundle patch (one insert row)
260
195
  scripts/prepare.mjs self-contained git-install build
261
196
  ```
262
197
 
263
- ## 🏷 Temas
264
-
265
- Temas recomendados para el repositorio de GitHub (configúralos en los ajustes del repositorio — impulsan la [página de temas `dsh-plugin`](https://github.com/topics/dsh-plugin) y los mercados de plugins de DSH):
198
+ ## Temas
266
199
 
267
200
  `dsh` · `dsh-plugin` · `deepseek-harness` · `github` · `pull-request` · `code-review` · `issue-tracker`
268
201
 
202
+ ## Contribuidores
203
+
204
+ - [@PerryLink](https://github.com/PerryLink) — creador y mantenedor: la superficie de herramientas de GitHub, la puerta de aprobación, los trabajos de revisión en segundo plano, la acción compuesta de CI, el bot de revisión, la puerta de status-check y la documentación en cinco idiomas.
205
+
206
+ ## Familia de plugins DSH de PerryLink
207
+
208
+ Este proyecto es uno de los [15 plugins de DeepSeek Harness](https://github.com/PerryLink) mantenidos por [PerryLink](https://github.com/PerryLink). Si este te resulta útil, es probable que los demás también:
209
+
210
+ | Plugin | Descripción |
211
+ |---|---|
212
+ | [dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | Panel MCP de solo lectura en tiempo de ejecución: comando /mcp + pestaña de ajustes con estado, herramientas y errores |
213
+ | [dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck) | Guardián de disciplina de ingeniería: interrogatorio de requisitos, puertas de pruebas, revisión adversaria |
214
+ | [dsh-background-agents](https://github.com/PerryLink/dsh-background-agents) | Agentes hijo en segundo plano duraderos con barra lateral web, mensajería e interrupción |
215
+ | [dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions) | Diagnósticos, formato, completado, acciones de código y renombrado LSP sobre servidores de lenguaje |
216
+ | [dsh-output-styles](https://github.com/PerryLink/dsh-output-styles) | Cambio de estilo en tiempo de ejecución equivalente a outputStyles de Claude Code |
217
+ | [dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind) | Equivalente a /rewind de Claude Code: instantáneas, bifurcaciones de sesión, restauración de un solo uso |
218
+ | [dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules) | Reglas de permisos declarativas allow/deny/ask estilo Claude Code con auditoría |
219
+ | [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) | Auto-revisión de un segundo modelo en la cadena de aprobación, cerrada ante fallo por defecto |
220
+ | [dsh-memento](https://github.com/PerryLink/dsh-memento) | Memoria entre sesiones con aprobación: seam ctx.memory + SQLite + herramienta de memoria |
221
+ | [dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security) | Paquete de habilidades de auditoría de seguridad: escaneo de secretos, revisión de dependencias y cadena de suministro |
222
+ | [dsh-session-pin](https://github.com/PerryLink/dsh-session-pin) | Fija sesiones en la barra lateral web con orden duradero |
223
+ | [dsh-composer-history](https://github.com/PerryLink/dsh-composer-history) | Historial de entrada estilo terminal para el compositor web: flechas, búsqueda Ctrl+R |
224
+ | **[dsh-github](https://github.com/PerryLink/dsh-github)** | Integración de PR/issues de GitHub para DSH, cada escritura con aprobación |
225
+ | [dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide) | Base de conocimiento de desarrollo de plugins como habilidad de agente bajo demanda |
226
+ | [dsh-claude-move](https://github.com/PerryLink/dsh-claude-move) | Migra sesiones, memoria, habilidades y CLAUDE.md de Claude Code a DSH |
227
+
269
228
  ## Licencia
270
229
 
271
- [Apache License 2.0](LICENSE)
230
+ [Apache License 2.0](LICENSE) © 2026 dsh-github contributors