@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.
- package/LICENSE +201 -0
- package/README.es.md +256 -0
- package/README.hi.md +256 -0
- package/README.md +257 -0
- package/README.pt.md +256 -0
- package/README.zh-CN.md +254 -0
- package/cordis.patch.yml +9 -0
- package/lib/approval-gate.d.ts +25 -0
- package/lib/approval-gate.d.ts.map +1 -0
- package/lib/approval-gate.js +75 -0
- package/lib/approval-gate.js.map +1 -0
- package/lib/commands.d.ts +12 -0
- package/lib/commands.d.ts.map +1 -0
- package/lib/commands.js +228 -0
- package/lib/commands.js.map +1 -0
- package/lib/config.d.ts +60 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +64 -0
- package/lib/config.js.map +1 -0
- package/lib/credential.d.ts +42 -0
- package/lib/credential.d.ts.map +1 -0
- package/lib/credential.js +80 -0
- package/lib/credential.js.map +1 -0
- package/lib/git.d.ts +52 -0
- package/lib/git.d.ts.map +1 -0
- package/lib/git.js +113 -0
- package/lib/git.js.map +1 -0
- package/lib/github.d.ts +66 -0
- package/lib/github.d.ts.map +1 -0
- package/lib/github.js +153 -0
- package/lib/github.js.map +1 -0
- package/lib/index.d.ts +55 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +44 -0
- package/lib/index.js.map +1 -0
- package/lib/jobs.d.ts +34 -0
- package/lib/jobs.d.ts.map +1 -0
- package/lib/jobs.js +255 -0
- package/lib/jobs.js.map +1 -0
- package/lib/present.d.ts +254 -0
- package/lib/present.d.ts.map +1 -0
- package/lib/present.js +149 -0
- package/lib/present.js.map +1 -0
- package/lib/review.d.ts +53 -0
- package/lib/review.d.ts.map +1 -0
- package/lib/review.js +158 -0
- package/lib/review.js.map +1 -0
- package/lib/state.d.ts +96 -0
- package/lib/state.d.ts.map +1 -0
- package/lib/state.js +86 -0
- package/lib/state.js.map +1 -0
- package/lib/tools.d.ts +21 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +937 -0
- package/lib/tools.js.map +1 -0
- package/lib/types.d.ts +147 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- 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)
|