@perrylink/dsh-github 0.4.0

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.
Files changed (60) hide show
  1. package/LICENSE +201 -0
  2. package/README.es.md +256 -0
  3. package/README.hi.md +256 -0
  4. package/README.md +257 -0
  5. package/README.pt.md +256 -0
  6. package/README.zh-CN.md +254 -0
  7. package/cordis.patch.yml +9 -0
  8. package/lib/approval-gate.d.ts +25 -0
  9. package/lib/approval-gate.d.ts.map +1 -0
  10. package/lib/approval-gate.js +75 -0
  11. package/lib/approval-gate.js.map +1 -0
  12. package/lib/commands.d.ts +12 -0
  13. package/lib/commands.d.ts.map +1 -0
  14. package/lib/commands.js +228 -0
  15. package/lib/commands.js.map +1 -0
  16. package/lib/config.d.ts +60 -0
  17. package/lib/config.d.ts.map +1 -0
  18. package/lib/config.js +64 -0
  19. package/lib/config.js.map +1 -0
  20. package/lib/credential.d.ts +42 -0
  21. package/lib/credential.d.ts.map +1 -0
  22. package/lib/credential.js +80 -0
  23. package/lib/credential.js.map +1 -0
  24. package/lib/git.d.ts +52 -0
  25. package/lib/git.d.ts.map +1 -0
  26. package/lib/git.js +113 -0
  27. package/lib/git.js.map +1 -0
  28. package/lib/github.d.ts +66 -0
  29. package/lib/github.d.ts.map +1 -0
  30. package/lib/github.js +153 -0
  31. package/lib/github.js.map +1 -0
  32. package/lib/index.d.ts +55 -0
  33. package/lib/index.d.ts.map +1 -0
  34. package/lib/index.js +44 -0
  35. package/lib/index.js.map +1 -0
  36. package/lib/jobs.d.ts +34 -0
  37. package/lib/jobs.d.ts.map +1 -0
  38. package/lib/jobs.js +255 -0
  39. package/lib/jobs.js.map +1 -0
  40. package/lib/present.d.ts +254 -0
  41. package/lib/present.d.ts.map +1 -0
  42. package/lib/present.js +149 -0
  43. package/lib/present.js.map +1 -0
  44. package/lib/review.d.ts +53 -0
  45. package/lib/review.d.ts.map +1 -0
  46. package/lib/review.js +158 -0
  47. package/lib/review.js.map +1 -0
  48. package/lib/state.d.ts +96 -0
  49. package/lib/state.d.ts.map +1 -0
  50. package/lib/state.js +86 -0
  51. package/lib/state.js.map +1 -0
  52. package/lib/tools.d.ts +21 -0
  53. package/lib/tools.d.ts.map +1 -0
  54. package/lib/tools.js +937 -0
  55. package/lib/tools.js.map +1 -0
  56. package/lib/types.d.ts +147 -0
  57. package/lib/types.d.ts.map +1 -0
  58. package/lib/types.js +2 -0
  59. package/lib/types.js.map +1 -0
  60. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.es.md ADDED
@@ -0,0 +1,256 @@
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>
24
+
25
+ ---
26
+
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, comentar y cerrar issues, y buscar** — mientras un humano aprueba cada escritura y el token permanece en secreto.
28
+
29
+ - 🛠 **8 herramientas** — `pr_create` · `gh_review` · `review_post` · `gh_issue` · `issue_open` · `issue_comment` · `issue_close` · `gh_search`, todas con JSON canónico mediante `defineTool`
30
+ - ⌨️ **3 familias de comandos** — `/pr create` · `/review` (start/stop/post) · `/issue open`
31
+ - 📝 **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
32
+ - 🔒 **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
33
+ - 🗝 **Secreto del token** — capa de credenciales → entorno → CLI `gh`, resuelto por operación, nunca en registros, eventos, representaciones ni errores
34
+ - ⏱ **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
35
+ - 🤖 **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
36
+ - 🚦 **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
37
+ - 🌐 **Documentación en 5 idiomas** — English · 中文 · Español · Português · हिन्दी
38
+
39
+ ---
40
+
41
+ ## 📚 Tabla de contenidos
42
+
43
+ - [Inicio rápido](#🚀-inicio-rápido)
44
+ - [Características](#✨-características)
45
+ - [Instalación](#📦-instalación)
46
+ - [Configuración](#⚙️-configuración)
47
+ - [Herramientas](#🛠-herramientas)
48
+ - [Comandos](#⌨️-comandos)
49
+ - [Arquitectura](#🏗-arquitectura)
50
+ - [Límites de seguridad](#🔒-límites-de-seguridad)
51
+ - [Limitaciones conocidas](#⚠️-limitaciones-conocidas)
52
+ - [Desarrollo](#🧪-desarrollo)
53
+ - [Estructura del repositorio](#🗂-estructura-del-repositorio)
54
+ - [Temas](#🏷-temas)
55
+ - [Licencia](#licencia)
56
+
57
+ ## 🚀 Inicio rápido
58
+
59
+ ```sh
60
+ # 1. instalar (registro npm — lo más simple; o usa el canal tarball de abajo)
61
+ dsh plugin --profile <name> add @perrylink/dsh-github
62
+ # canal tarball (sin necesidad de registro):
63
+ pnpm pack # inside this repo → dsh-github-0.4.0.tgz
64
+ dsh plugin --profile <name> add ./dsh-github-0.4.0.tgz
65
+
66
+ # 2. configure a GitHub token (recommended: the credentials seam)
67
+ # $DSH_HOME/.credentials.yaml
68
+ # GITHUB_TOKEN: <your token>
69
+
70
+ # 3. use it — in the dsh web UI or headless
71
+ # /pr create "add dark mode" → agent drafts & opens the PR (approval required)
72
+ # /review 42 → background review job, read it with job_output
73
+ # /review post github-review-1 → publish the review comment (approval required)
74
+ # /issue open "crash on startup" → agent opens the issue (approval required)
75
+ ```
76
+
77
+ Verificación: `dsh --profile <name> --dump-config` debe mostrar la sección `# == dsh-github` con **ninguna línea FAILED**.
78
+
79
+ ## ✨ Características
80
+
81
+ | Área | Qué obtienes |
82
+ |---|---|
83
+ | **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 |
84
+ | **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` |
85
+ | **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 |
86
+ | **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 |
87
+ | **Leer issues** | `gh_issue` lista / obtiene / comenta; los pull requests en los listados se marcan como `kind: "pr"` |
88
+ | **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 |
89
+ | **Buscar** | `gh_search` consulta issues y pull requests con la sintaxis de búsqueda de GitHub, mostrando la cuota de búsqueda independiente |
90
+ | **Aprobación** | `tools/pre-execute` pide `ctx.approval` para cada escritura; la lista blanca `allowedActions` deniega antes de preguntar |
91
+ | **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 |
92
+ | **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 |
93
+ | **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`…) |
94
+
95
+ ## 📦 Instalación
96
+
97
+ Cuatro canales documentados — elige uno.
98
+
99
+ | Canal | Comando | Notas |
100
+ |---|---|---|
101
+ | **npm registry** | `dsh plugin --profile <name> add @perrylink/dsh-github` | Publicado en npm — el canal más simple |
102
+ | **Tarball npm** | `dsh plugin --profile <name> add ./dsh-github-0.4.0.tgz` | Se distribuye con `lib/` compilado — sin permiso de compilación |
103
+ | **Fuente git** | `dsh plugin --profile <name> add "github:PerryLink/dsh-github#<sha>"` | Requiere `prepare` + `allowBuilds` (ver abajo); fija el commit |
104
+ | **Enlace local** | `pnpm link --dir .` y luego `dsh plugin add @perrylink/dsh-github` | Desarrollo |
105
+
106
+ > 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`.
107
+
108
+ 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:
109
+
110
+ ```yaml
111
+ allowBuilds:
112
+ '@perrylink/dsh-github': true
113
+ ```
114
+
115
+ 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.
116
+
117
+ **Desinstalación:** `dsh plugin --profile <name> remove @perrylink/dsh-github`.
118
+
119
+ ## ⚙️ Configuración
120
+
121
+ 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).
122
+
123
+ | Clave | Por defecto | Significado |
124
+ |---|---|---|
125
+ | `tokenSource` | `auto` | `auto` (credenciales → env → gh) o uno de `credentials` / `env` / `gh` |
126
+ | `tokenRef` | `GITHUB_TOKEN` | Referencia de la capa de credenciales / nombre de la variable de entorno |
127
+ | `defaultOwnerRepo` | — | `owner/repo` de respaldo cuando una llamada no indica ninguno y git no tiene origen |
128
+ | `autoCommit` | `false` | Si `/pr create` puede indicar al modelo que haga commit+push primero |
129
+ | `maxDiffChars` | `8000` | Límite de caracteres para los diffs de PR leídos en las revisiones |
130
+ | `renderExcerptChars` | `2000` | Límite de caracteres para el extracto de diff representado en la salida de la herramienta |
131
+ | `maxComments` | `20` | Límite para los comentarios de PR listados por `gh_review` |
132
+ | `reviewJobTimeoutMs` | `600000` | Plazo para un trabajo de revisión en segundo plano (falla con `timeout`) |
133
+ | `maxReviewRecords` | `50` | Límite para los registros en memoria de trabajos de revisión; los registros finalizados más antiguos se eliminan primero |
134
+ | `reviewMode` | `static` | Motor de revisión: `static` (analizador determinista) o `model` (subagente de un solo uso a través de la seam `subagents` del host; falla de forma evidente si la seam no está presente) |
135
+ | `modelReviewProvider` | — | Nombre del proveedor de subagente para `reviewMode: "model"`; por defecto, el primer proveedor registrado |
136
+ | `maxRetries` | `3` | Intentos de reintento 429 por solicitud |
137
+ | `retryBaseMs` | `500` | Base del retroceso de reintento (se duplica por intento) |
138
+ | `retryMaxWaitMs` | `60000` | Tope del retroceso de reintento |
139
+ | `apiBaseUrl` | `https://api.github.com` | URL base de la API REST de GitHub (GitHub Enterprise) |
140
+ | `allowedActions` | `['pr.create','review.post','issue.create','issue.comment','issue.close']` | Lista blanca de acciones de escritura; cualquier otra se deniega antes de la aprobación |
141
+ | `workspaceDir` | process cwd | Directorio de trabajo para la inspección de git de solo lectura |
142
+
143
+ ## 🛠 Herramientas
144
+
145
+ | Herramienta | Tipo | Parámetros | Devuelve |
146
+ |---|---|---|---|
147
+ | `pr_create` | escritura | `title*`, `body?`, `base?`, `head?`, `draft?`, `ownerRepo?` | `{status:'created', url, number, title, state, draft, base, head, rateLimit}` o error estructurado |
148
+ | `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 |
149
+ | `gh_issue` | lectura | `action*` (`list`/`get`/`comments`), `ownerRepo?`, `issueNumber?`, `state?`, `limit?` | elementos normalizados (cada uno marcado `kind: issue/pr/comment`) + límite de velocidad |
150
+ | `review_post` | escritura | `jobId*`, `mode?` (`summary`/`inline`), `body?` | `{status:'posted', mode, url, commentId?, reviewId?, findings, rateLimit}` o error estructurado |
151
+ | `issue_open` | escritura | `title*`, `body?`, `labels?`, `ownerRepo?` | `{status:'created', url, number, title, rateLimit}` o error estructurado |
152
+ | `issue_comment` | escritura | `issueNumber*`, `body*`, `ownerRepo?` | `{status:'commented', url, commentId, issueNumber, rateLimit}` o error estructurado |
153
+ | `issue_close` | escritura | `issueNumber*`, `ownerRepo?`, `stateReason?` (`completed`/`not_planned`) | `{status:'closed', url, number, title, rateLimit}` o error estructurado |
154
+ | `gh_search` | lectura | `q*`, `sort?`, `order?`, `perPage?` | `{query, total, items[{number,title,state,kind,author,url,repo,comments,createdAt}], rateLimit}` o error estructurado |
155
+
156
+ `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.
157
+
158
+ ## ⌨️ Comandos
159
+
160
+ | Comando | Efecto |
161
+ |---|---|
162
+ | `/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. |
163
+ | `/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`. |
164
+ | `/review <pr> --max-diff <n> --no-ci --no-comments` | Anulaciones por trabajo: límite de diff y qué secciones suplementarias obtiene el trabajo. |
165
+ | `/review stop <jobId>` | Cancela el trabajo (control local, sin escritura en GitHub). |
166
+ | `/review post <jobId>` | Encola una instrucción `review_post` para el modelo (resumen o en línea); publicar solicita aprobación. |
167
+ | `/issue open <title>` | Encola una instrucción `issue_open` para el modelo; crear solicita aprobación. |
168
+
169
+ ## 🏗 Arquitectura
170
+
171
+ ```
172
+ ┌───────────────────────────────────────────────┐
173
+ │ dsh-github │
174
+ │ │
175
+ humanos ─── /pr ────┼──► git reader (read-only) ──► agent.followup │
176
+ /review ───┼──► ctx.jobs.start("github-review") ──► job │
177
+ /issue ────┼──► agent.followup │
178
+ │ │
179
+ modelo ─── pr_create / gh_review / gh_issue / review_post / │
180
+ issue_open / issue_comment / issue_close / gh_search │
181
+ (defineTool, canonical JSON only) │
182
+ │ │
183
+ └───────┬───────────────┬───────────────┬───────┘
184
+ │ │ │
185
+ tools/pre-execute credential GitHub REST
186
+ approval gate resolution client (fetch,
187
+ (ask | deny) (seam → env → 429 retry,
188
+ gh CLI, per-op) rate-limit)
189
+ ```
190
+
191
+ - **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.
192
+ - **Aprobación.** Todas las escrituras fluyen a través de las herramientas del modelo. Un listener waterfall `tools/pre-execute` devuelve `ask` para las cinco 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 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.
193
+ - **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.
194
+ - **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`.
195
+ - **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.
196
+
197
+ ## 🔒 Límites de seguridad
198
+
199
+ - 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.
200
+ - Cada escritura en GitHub requiere `allowed-once` de `ctx.approval` (política `ask` por defecto); `rejected`, `cancelled` y `unavailable` fallan todas de forma cerrada.
201
+ - `/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).
202
+ - 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.
203
+ - 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.
204
+ - 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.
205
+ - Límites de velocidad: los 429 se reintentan con retroceso y la cuota restante se muestra al modelo en cada resultado, incluidos los fallos.
206
+
207
+ ## ⚠️ Limitaciones conocidas
208
+
209
+ - **Sin eventos de sesión personalizados** — deliberado (ver Arquitectura); las pistas de auditoría se apoyan en el vocabulario de eventos propio del host.
210
+ - **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).
211
+ - **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).
212
+ - **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`.
213
+ - **CI / GitHub Action** (`dsh-github-action`, bucle headless de revisión→comentario en el espíritu de claude-code-action / codex-action) es un repositorio complementario v2 planificado.
214
+
215
+ ## 🧪 Desarrollo
216
+
217
+ ```sh
218
+ pnpm install
219
+ pnpm test # vitest: config, credentials, 429/retry, tools, commands, jobs, approval gate, token non-leakage
220
+ pnpm typecheck
221
+ pnpm build # tsc → lib/ (noEmitOnError)
222
+ pnpm pack # installable tarball
223
+ pnpm run check:readmes # cross-checks TOC anchors in all 5 READMEs
224
+ ```
225
+
226
+ 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 `GITHUB_TOKEN` esté definido (solo endpoints de solo lectura).
227
+
228
+ ## 🗂 Estructura del repositorio
229
+
230
+ ```
231
+ src/index.ts plugin entry (name/inject/apply, applyWithDeps for tests)
232
+ src/config.ts Schemastery Config
233
+ src/types.ts local structural views of host services + Context merging
234
+ src/credential.ts token resolution (seam → env → gh), per operation
235
+ src/github.ts REST client: 429 retry, rate limits, diff media type
236
+ src/git.ts read-only git inspection + origin parsing for any API host
237
+ src/review.ts deterministic diff analyzer + sanitized comment drafting
238
+ src/jobs.ts github-review background job producer (metadata + diff + CI + comments)
239
+ src/approval-gate.ts tools/pre-execute ask/deny gate with write previews
240
+ src/tools.ts the eight model-facing tools
241
+ src/commands.ts /pr, /review, /issue
242
+ src/present.ts pure UI-card presenters
243
+ test/ vitest suite + mock host scaffolding + opt-in e2e smoke
244
+ cordis.patch.yml bundle patch (one insert row)
245
+ scripts/prepare.mjs self-contained git-install build
246
+ ```
247
+
248
+ ## 🏷 Temas
249
+
250
+ 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):
251
+
252
+ `dsh` · `dsh-plugin` · `deepseek-harness` · `github` · `pull-request` · `code-review` · `issue-tracker`
253
+
254
+ ## Licencia
255
+
256
+ [Apache License 2.0](LICENSE)