guild-agents 0.1.0 → 0.2.1
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/bin/guild.js +49 -6
- package/package.json +2 -3
- package/src/commands/__tests__/doctor.test.js +85 -0
- package/src/commands/__tests__/list.test.js +82 -0
- package/src/commands/__tests__/new-agent.test.js +40 -0
- package/src/commands/__tests__/status.test.js +35 -0
- package/src/commands/doctor.js +99 -0
- package/src/commands/init.js +5 -6
- package/src/commands/list.js +82 -0
- package/src/commands/new-agent.js +5 -10
- package/src/commands/status.js +1 -2
- package/src/templates/agents/advisor.md +2 -0
- package/src/templates/agents/bugfix.md +2 -0
- package/src/templates/agents/code-reviewer.md +2 -0
- package/src/templates/agents/db-migration.md +2 -0
- package/src/templates/agents/developer.md +2 -0
- package/src/templates/agents/platform-expert.md +89 -0
- package/src/templates/agents/product-owner.md +2 -0
- package/src/templates/agents/qa.md +2 -0
- package/src/templates/agents/tech-lead.md +2 -0
- package/src/templates/skills/build-feature/SKILL.md +114 -14
- package/src/templates/skills/council/SKILL.md +33 -1
- package/src/templates/skills/dev-flow/SKILL.md +15 -1
- package/src/templates/skills/guild-specialize/SKILL.md +44 -1
- package/src/templates/skills/new-feature/SKILL.md +29 -2
- package/src/templates/skills/qa-cycle/SKILL.md +40 -11
- package/src/templates/skills/review/SKILL.md +31 -3
- package/src/templates/skills/session-end/SKILL.md +31 -1
- package/src/templates/skills/session-start/SKILL.md +33 -3
- package/src/templates/skills/status/SKILL.md +20 -1
- package/src/utils/files.js +23 -2
- package/src/utils/generators.js +7 -0
- package/src/utils/github.js +32 -14
|
@@ -20,20 +20,32 @@ Ejecuta un code review independiente sobre los cambios actuales del proyecto. In
|
|
|
20
20
|
|
|
21
21
|
## Proceso
|
|
22
22
|
|
|
23
|
-
### Paso 1 — Obtener diff
|
|
23
|
+
### Paso 1 — Obtener diff y estado de verificacion
|
|
24
24
|
|
|
25
25
|
Obtiene los cambios actuales:
|
|
26
|
+
|
|
26
27
|
1. Primero intenta `git diff --staged` (cambios en staging)
|
|
27
28
|
2. Si no hay cambios en staging, usa `git diff` (cambios sin stage)
|
|
28
29
|
3. Si no hay ningun cambio, informa que no hay nada que revisar
|
|
29
30
|
|
|
31
|
+
Ejecuta verificacion automatizada para dar contexto al reviewer:
|
|
32
|
+
|
|
33
|
+
4. Ejecuta tests del proyecto (ej: `npm test`) — captura resultado
|
|
34
|
+
5. Ejecuta lint del proyecto (ej: `npm run lint`) — captura resultado
|
|
35
|
+
6. Incluye ambos resultados como contexto para el Code Reviewer
|
|
36
|
+
|
|
37
|
+
Nota: El Code Reviewer no tiene acceso a Bash (solo Read, Glob, Grep), por eso los tests y lint se ejecutan aqui antes de invocar al reviewer.
|
|
38
|
+
|
|
30
39
|
### Paso 2 — Invocar Code Reviewer
|
|
31
40
|
|
|
32
41
|
Invoca al agente Code Reviewer usando Task tool:
|
|
42
|
+
|
|
33
43
|
1. Lee `.claude/agents/code-reviewer.md` para asumir el rol
|
|
34
44
|
2. Lee CLAUDE.md para entender las convenciones del proyecto
|
|
35
|
-
3.
|
|
36
|
-
4.
|
|
45
|
+
3. Recibe el diff completo + resultados de tests y lint del Paso 1
|
|
46
|
+
4. Si tests o lint fallaron, esto es automaticamente un hallazgo Blocker
|
|
47
|
+
5. Revisa el diff completo
|
|
48
|
+
6. Clasifica cada hallazgo por severidad:
|
|
37
49
|
- **Blocker**: Debe corregirse antes de merge
|
|
38
50
|
- **Warning**: Deberia corregirse, introduce deuda tecnica
|
|
39
51
|
- **Suggestion**: Mejora opcional
|
|
@@ -41,8 +53,24 @@ Invoca al agente Code Reviewer usando Task tool:
|
|
|
41
53
|
### Paso 3 — Presentar hallazgos
|
|
42
54
|
|
|
43
55
|
Presenta el reporte organizado por severidad:
|
|
56
|
+
|
|
44
57
|
- Cantidad total de hallazgos por tipo
|
|
45
58
|
- Detalle de cada hallazgo: archivo, descripcion, sugerencia de correccion
|
|
46
59
|
- Veredicto final: Aprobado / Aprobado con warnings / Bloqueado
|
|
47
60
|
|
|
48
61
|
Si hay blockers, sugiere corregirlos y ejecutar `/review` de nuevo.
|
|
62
|
+
|
|
63
|
+
## Example Session
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
User: /review
|
|
67
|
+
|
|
68
|
+
Reviewing diff: 4 files changed, +127 -34
|
|
69
|
+
|
|
70
|
+
Findings:
|
|
71
|
+
- [Warning] src/api/users.js:45 — No input validation on email parameter
|
|
72
|
+
- [Suggestion] src/utils/format.js:12 — Consider using Intl.DateTimeFormat
|
|
73
|
+
- [Blocker] src/db/queries.js:78 — SQL injection vulnerability in raw query
|
|
74
|
+
|
|
75
|
+
1 blocker, 1 warning, 1 suggestion.
|
|
76
|
+
```
|
|
@@ -22,6 +22,7 @@ Guarda el estado actual del trabajo en SESSION.md para poder retomarlo en la sig
|
|
|
22
22
|
### Paso 1 — Recopilar estado actual
|
|
23
23
|
|
|
24
24
|
Analiza el estado actual del trabajo:
|
|
25
|
+
|
|
25
26
|
- Que tarea estaba en curso
|
|
26
27
|
- En que fase del pipeline se encuentra (si aplica)
|
|
27
28
|
- Que archivos se modificaron (via `git status`)
|
|
@@ -38,17 +39,46 @@ Actualiza SESSION.md con la siguiente informacion:
|
|
|
38
39
|
- **Estado:** descripcion concreta de donde quedo el trabajo
|
|
39
40
|
|
|
40
41
|
**Contexto relevante:**
|
|
42
|
+
|
|
41
43
|
- Decisiones tomadas en esta sesion
|
|
42
44
|
- Problemas encontrados y como se resolvieron
|
|
43
45
|
- Informacion importante para retomar
|
|
44
46
|
|
|
45
47
|
**Proximos pasos:**
|
|
48
|
+
|
|
46
49
|
- Las 2-3 acciones concretas mas importantes al retomar
|
|
47
50
|
- Skill sugerido para continuar (ej: "ejecutar /build-feature para continuar desde Fase 4")
|
|
48
51
|
|
|
49
|
-
### Paso 3 —
|
|
52
|
+
### Paso 3 — Commit WIP if uncommitted work exists
|
|
53
|
+
|
|
54
|
+
If there are uncommitted changes, create a checkpoint commit:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git add -A
|
|
58
|
+
git commit -m "wip: session paused — [brief description of current state]"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This ensures no work is lost between sessions. Never leave uncommitted changes across session boundaries.
|
|
62
|
+
|
|
63
|
+
## Example Session
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
User: /session-end
|
|
67
|
+
|
|
68
|
+
Saving session state...
|
|
69
|
+
Task: user-preferences
|
|
70
|
+
Phase: 4 — Implementation (in progress)
|
|
71
|
+
Files modified: 3 files
|
|
72
|
+
WIP committed: wip: session paused — user-preferences phase 4
|
|
73
|
+
|
|
74
|
+
SESSION.md updated. Safe to close.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Paso 4 — Confirmar
|
|
50
78
|
|
|
51
79
|
Confirma al usuario:
|
|
80
|
+
|
|
52
81
|
- SESSION.md actualizado con el estado actual
|
|
82
|
+
- WIP committed (if applicable)
|
|
53
83
|
- Proximos pasos registrados
|
|
54
84
|
- Puedes cerrar la sesion con seguridad
|
|
@@ -22,32 +22,62 @@ Carga el contexto del proyecto y retoma el trabajo desde donde se dejo en la ses
|
|
|
22
22
|
### Paso 1 — Cargar contexto
|
|
23
23
|
|
|
24
24
|
Lee los archivos de estado de Guild:
|
|
25
|
+
|
|
25
26
|
- `CLAUDE.md` — instrucciones, convenciones y reglas del proyecto
|
|
26
27
|
- `SESSION.md` — estado de la ultima sesion, tarea en curso, proximos pasos
|
|
27
28
|
- `PROJECT.md` — identidad del proyecto, stack, agentes configurados
|
|
28
29
|
|
|
29
|
-
### Paso 2 —
|
|
30
|
+
### Paso 2 — Detect resumable work
|
|
31
|
+
|
|
32
|
+
Check for `wip:` checkpoint commits on active branches:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git branch --list "feature/*" --list "fix/*" | while read branch; do
|
|
36
|
+
git log --oneline "$branch" -1 | grep "^wip:" && echo "Resumable: $branch"
|
|
37
|
+
done
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If `wip:` commits are found, present them to the user with the phase they were in when interrupted.
|
|
41
|
+
|
|
42
|
+
### Paso 3 — Presentar estado
|
|
30
43
|
|
|
31
44
|
Muestra un resumen de la sesion anterior:
|
|
45
|
+
|
|
32
46
|
- Fecha de la ultima sesion
|
|
33
47
|
- Tarea en curso (si existe)
|
|
34
48
|
- Estado en que quedo el trabajo
|
|
35
49
|
- Decisiones tomadas previamente
|
|
36
50
|
- Proximos pasos registrados
|
|
51
|
+
- **Resumable pipelines** (if wip: commits detected)
|
|
37
52
|
|
|
38
|
-
### Paso
|
|
53
|
+
### Paso 4 — Sugerir como continuar
|
|
39
54
|
|
|
40
55
|
Si hay tarea en curso:
|
|
56
|
+
|
|
41
57
|
- Muestra el estado de la tarea
|
|
42
58
|
- Sugiere continuar con el skill apropiado (ej: `/build-feature` si esta en implementacion)
|
|
43
59
|
- Muestra los proximos pasos registrados en SESSION.md
|
|
44
60
|
|
|
45
61
|
Si no hay tarea en curso, sugiere opciones:
|
|
62
|
+
|
|
46
63
|
- `/build-feature [descripcion]` — para implementar una feature nueva
|
|
47
64
|
- `/new-feature [nombre]` — para preparar el entorno de una feature
|
|
48
65
|
- `/status` — para ver el estado general del proyecto
|
|
49
66
|
- `/council [pregunta]` — para debatir una decision importante
|
|
50
67
|
|
|
51
|
-
### Paso
|
|
68
|
+
### Paso 5 — Actualizar sesion
|
|
52
69
|
|
|
53
70
|
Actualiza SESSION.md con la fecha actual para registrar que la sesion inicio.
|
|
71
|
+
|
|
72
|
+
## Example Session
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
User: /session-start
|
|
76
|
+
|
|
77
|
+
Loading context...
|
|
78
|
+
Last session: 2026-02-22
|
|
79
|
+
Task in progress: user-preferences (Phase 4 — Implementation)
|
|
80
|
+
Resumable: feature/user-preferences (wip: phase 3 complete)
|
|
81
|
+
|
|
82
|
+
Suggested: Continue with /build-feature to resume implementation.
|
|
83
|
+
```
|
|
@@ -23,6 +23,7 @@ Muestra un resumen completo del estado actual del proyecto, la sesion activa y l
|
|
|
23
23
|
### Paso 1 — Leer archivos de estado
|
|
24
24
|
|
|
25
25
|
Lee los archivos de configuracion de Guild:
|
|
26
|
+
|
|
26
27
|
- `CLAUDE.md` — instrucciones y convenciones del proyecto
|
|
27
28
|
- `PROJECT.md` — identidad, stack y agentes configurados
|
|
28
29
|
- `SESSION.md` — estado de la sesion actual
|
|
@@ -31,7 +32,7 @@ Lee los archivos de configuracion de Guild:
|
|
|
31
32
|
|
|
32
33
|
Muestra el resumen con el siguiente formato:
|
|
33
34
|
|
|
34
|
-
```
|
|
35
|
+
```text
|
|
35
36
|
Guild v1 — [nombre del proyecto]
|
|
36
37
|
|
|
37
38
|
Sesion actual:
|
|
@@ -55,8 +56,26 @@ Proximos pasos:
|
|
|
55
56
|
### Paso 3 — Sugerir acciones
|
|
56
57
|
|
|
57
58
|
Si no hay tarea en curso, sugiere:
|
|
59
|
+
|
|
58
60
|
- `/build-feature` para implementar algo nuevo
|
|
59
61
|
- `/new-feature` para preparar el entorno de una feature
|
|
60
62
|
- `/council` para debatir una decision
|
|
61
63
|
|
|
62
64
|
Si hay tarea en curso, sugiere continuar con el skill apropiado segun el estado.
|
|
65
|
+
|
|
66
|
+
## Example Session
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
User: /status
|
|
70
|
+
|
|
71
|
+
Guild — MyProject
|
|
72
|
+
Stack: Node.js 20, React 18, PostgreSQL
|
|
73
|
+
|
|
74
|
+
Session: 2026-02-23
|
|
75
|
+
Task: Implementing user preferences
|
|
76
|
+
State: Phase 4 — Developer implementing
|
|
77
|
+
|
|
78
|
+
Agents: advisor, product-owner, tech-lead, developer, code-reviewer, qa, bugfix, db-migration
|
|
79
|
+
Skills: guild-specialize, build-feature, new-feature, council, qa-cycle, review, dev-flow,
|
|
80
|
+
status, session-start, session-end
|
|
81
|
+
```
|
package/src/utils/files.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { mkdirSync, copyFileSync, existsSync, readdirSync, readFileSync } from 'fs';
|
|
6
|
-
import { join, dirname } from 'path';
|
|
6
|
+
import { join, dirname, resolve } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -12,7 +12,7 @@ const AGENTS_DIR = join('.claude', 'agents');
|
|
|
12
12
|
const SKILLS_DIR = join('.claude', 'skills');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Lista los nombres de los
|
|
15
|
+
* Lista los nombres de los 9 agentes v1.
|
|
16
16
|
*/
|
|
17
17
|
export function getAgentNames() {
|
|
18
18
|
return [
|
|
@@ -24,6 +24,7 @@ export function getAgentNames() {
|
|
|
24
24
|
'qa',
|
|
25
25
|
'bugfix',
|
|
26
26
|
'db-migration',
|
|
27
|
+
'platform-expert',
|
|
27
28
|
];
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -80,3 +81,23 @@ export function readSessionMd() {
|
|
|
80
81
|
if (!existsSync(path)) return null;
|
|
81
82
|
return readFileSync(path, 'utf8');
|
|
82
83
|
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Resuelve la raiz del proyecto Guild caminando hacia arriba desde startDir.
|
|
87
|
+
* Busca .claude/ o PROJECT.md como marcadores de un proyecto Guild.
|
|
88
|
+
* Retorna la ruta absoluta del proyecto o null si no se encuentra.
|
|
89
|
+
*/
|
|
90
|
+
export function resolveProjectRoot(startDir = process.cwd()) {
|
|
91
|
+
let dir = resolve(startDir);
|
|
92
|
+
while (true) {
|
|
93
|
+
if (existsSync(join(dir, '.claude')) || existsSync(join(dir, 'PROJECT.md'))) {
|
|
94
|
+
return dir;
|
|
95
|
+
}
|
|
96
|
+
const parent = dirname(dir);
|
|
97
|
+
if (parent === dir) {
|
|
98
|
+
// Reached filesystem root without finding a project
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
dir = parent;
|
|
102
|
+
}
|
|
103
|
+
}
|
package/src/utils/generators.js
CHANGED
|
@@ -61,6 +61,13 @@ ${data.stack}
|
|
|
61
61
|
- ESModules en todo el codigo
|
|
62
62
|
- path.join() siempre para construir paths
|
|
63
63
|
|
|
64
|
+
## Subagent rules
|
|
65
|
+
- Guild agent roles (advisor, developer, tech-lead, etc.) are NOT Claude Code subagent_types
|
|
66
|
+
- Always use \`subagent_type: "general-purpose"\` when spawning agents via Task tool
|
|
67
|
+
- CLAUDE.md and SESSION.md changes must be committed separately from feature code
|
|
68
|
+
- No \`git stash\` in automated pipelines — use \`wip:\` commits instead
|
|
69
|
+
- Parallel agents must use git worktrees for isolation
|
|
70
|
+
|
|
64
71
|
## Skills disponibles
|
|
65
72
|
- /guild-specialize — enriquecer CLAUDE.md explorando el proyecto real
|
|
66
73
|
- /build-feature — pipeline completo de desarrollo
|
package/src/utils/github.js
CHANGED
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
* Requiere que el usuario tenga gh instalado y autenticado.
|
|
5
5
|
* Todas las operaciones son no-bloqueantes — si gh no está disponible,
|
|
6
6
|
* Guild funciona normalmente sin integración GitHub.
|
|
7
|
+
*
|
|
8
|
+
* Uses execFileSync with array-based arguments to prevent shell injection
|
|
9
|
+
* through user-controlled strings (issue titles, bodies, labels).
|
|
7
10
|
*/
|
|
8
11
|
|
|
9
|
-
import {
|
|
12
|
+
import { execFileSync } from 'node:child_process';
|
|
10
13
|
|
|
11
14
|
const LABELS = [
|
|
12
15
|
{ name: 'backlog', color: '8E8E8E', description: 'Tarea documentada, pendiente de iniciar' },
|
|
@@ -22,7 +25,7 @@ const LABELS = [
|
|
|
22
25
|
*/
|
|
23
26
|
export function isGhAvailable() {
|
|
24
27
|
try {
|
|
25
|
-
|
|
28
|
+
execFileSync('gh', ['auth', 'status'], { stdio: 'ignore' });
|
|
26
29
|
return true;
|
|
27
30
|
} catch {
|
|
28
31
|
return false;
|
|
@@ -43,10 +46,13 @@ export async function setupGithubLabels(repoUrl) {
|
|
|
43
46
|
|
|
44
47
|
for (const label of LABELS) {
|
|
45
48
|
try {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
execFileSync('gh', [
|
|
50
|
+
'label', 'create', label.name,
|
|
51
|
+
'--color', label.color,
|
|
52
|
+
'--description', label.description,
|
|
53
|
+
'--repo', repo,
|
|
54
|
+
'--force',
|
|
55
|
+
], { stdio: 'ignore' });
|
|
50
56
|
} catch {
|
|
51
57
|
// Label ya existe o error no crítico
|
|
52
58
|
}
|
|
@@ -60,8 +66,14 @@ export function assignIssue(issueNumber, fromLabel, toLabel) {
|
|
|
60
66
|
if (!isGhAvailable()) return;
|
|
61
67
|
|
|
62
68
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
69
|
+
execFileSync('gh', [
|
|
70
|
+
'issue', 'assign', String(issueNumber), '--assignee', '@me',
|
|
71
|
+
], { stdio: 'ignore' });
|
|
72
|
+
execFileSync('gh', [
|
|
73
|
+
'issue', 'edit', String(issueNumber),
|
|
74
|
+
'--add-label', toLabel,
|
|
75
|
+
'--remove-label', fromLabel,
|
|
76
|
+
], { stdio: 'ignore' });
|
|
65
77
|
} catch {
|
|
66
78
|
// Non-critical
|
|
67
79
|
}
|
|
@@ -74,7 +86,9 @@ export function commentIssue(issueNumber, body) {
|
|
|
74
86
|
if (!isGhAvailable()) return;
|
|
75
87
|
|
|
76
88
|
try {
|
|
77
|
-
|
|
89
|
+
execFileSync('gh', [
|
|
90
|
+
'issue', 'comment', String(issueNumber), '--body', body,
|
|
91
|
+
], { stdio: 'ignore' });
|
|
78
92
|
} catch {
|
|
79
93
|
// Non-critical
|
|
80
94
|
}
|
|
@@ -87,7 +101,9 @@ export function closeIssue(issueNumber, comment) {
|
|
|
87
101
|
if (!isGhAvailable()) return;
|
|
88
102
|
|
|
89
103
|
try {
|
|
90
|
-
|
|
104
|
+
execFileSync('gh', [
|
|
105
|
+
'issue', 'close', String(issueNumber), '--comment', comment,
|
|
106
|
+
], { stdio: 'ignore' });
|
|
91
107
|
} catch {
|
|
92
108
|
// Non-critical
|
|
93
109
|
}
|
|
@@ -100,10 +116,12 @@ export function createBugIssue(title, body, parentIssueNumber) {
|
|
|
100
116
|
if (!isGhAvailable()) return null;
|
|
101
117
|
|
|
102
118
|
try {
|
|
103
|
-
const result =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
const result = execFileSync('gh', [
|
|
120
|
+
'issue', 'create',
|
|
121
|
+
'--title', title,
|
|
122
|
+
'--body', body,
|
|
123
|
+
'--label', 'bug',
|
|
124
|
+
], { encoding: 'utf8' });
|
|
107
125
|
const issueUrl = result.trim();
|
|
108
126
|
const issueNumber = issueUrl.split('/').pop();
|
|
109
127
|
|