agent-rules-init 0.2.1 → 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 +21 -0
- package/README.md +21 -0
- package/dist/cli.d.ts +38 -1
- package/dist/cli.js +203 -40
- package/dist/core/canonical-commands.d.ts +4 -0
- package/dist/core/canonical-commands.js +169 -0
- package/dist/core/config.d.ts +25 -0
- package/dist/core/config.js +125 -0
- package/dist/core/i18n.d.ts +47 -0
- package/dist/core/i18n.js +207 -0
- package/dist/core/llm-bridge.d.ts +5 -1
- package/dist/core/llm-bridge.js +56 -4
- package/dist/core/project-unit-output.d.ts +13 -0
- package/dist/core/project-unit-output.js +25 -0
- package/dist/core/project-units.d.ts +16 -0
- package/dist/core/project-units.js +95 -0
- package/dist/core/prompt-engine.d.ts +3 -1
- package/dist/core/prompt-engine.js +19 -14
- package/dist/core/repo-facts.d.ts +30 -0
- package/dist/core/repo-facts.js +420 -0
- package/dist/core/scanner.js +153 -27
- package/dist/core/templates.d.ts +6 -4
- package/dist/core/templates.js +127 -29
- package/dist/core/types.d.ts +84 -2
- package/dist/core/writer.d.ts +1 -1
- package/dist/core/writer.js +6 -4
- package/dist/packs/cpp.js +33 -27
- package/dist/packs/csharp.js +32 -27
- package/dist/packs/dart.js +30 -31
- package/dist/packs/elixir.js +31 -27
- package/dist/packs/go.js +31 -27
- package/dist/packs/java.js +82 -30
- package/dist/packs/js-ts.js +150 -37
- package/dist/packs/kotlin.js +56 -31
- package/dist/packs/php.js +30 -27
- package/dist/packs/python.js +107 -34
- package/dist/packs/r.js +30 -27
- package/dist/packs/ruby.js +36 -27
- package/dist/packs/rust.js +33 -27
- package/dist/packs/scala.js +32 -27
- package/dist/packs/swift.js +31 -27
- package/package.json +7 -4
package/dist/packs/cpp.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
1
2
|
const FRAMEWORKS = [
|
|
2
3
|
["find_package(qt", "qt"],
|
|
3
4
|
["find_package(boost", "boost"],
|
|
@@ -46,39 +47,44 @@ function detect(signals) {
|
|
|
46
47
|
: { value: "make", confidence: "high" };
|
|
47
48
|
return { packId: "cpp", language: "C/C++", framework, testRunner, packageManager };
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"Sigue el estilo de formato ya usado en el proyecto (revisa si hay un `.clang-format`).",
|
|
55
|
-
`Compila y ejecuta los tests con ${detection.packageManager?.value === "cmake" ? "cmake --build . && ctest" : "make test"} antes de terminar una tarea.`,
|
|
56
|
-
"Gestiona la memoria con cuidado: prefiere RAII/smart pointers sobre `new`/`delete` manuales cuando el proyecto ya lo haga.",
|
|
57
|
-
],
|
|
58
|
-
architectureNotes: [
|
|
50
|
+
const TEXTS = {
|
|
51
|
+
es: {
|
|
52
|
+
style: "Sigue el estilo de formato ya usado en el proyecto (revisa si hay un `.clang-format`).",
|
|
53
|
+
memory: "Gestiona la memoria con cuidado: prefiere RAII/smart pointers sobre `new`/`delete` manuales cuando el proyecto ya lo haga.",
|
|
54
|
+
arch: [
|
|
59
55
|
"Mantén los headers con guardas de inclusión (`#pragma once` o include guards) consistentes con el resto del proyecto.",
|
|
60
56
|
"Declara toda dependencia nueva en el sistema de build existente (CMakeLists.txt o Makefile).",
|
|
61
57
|
],
|
|
58
|
+
reviewFocus: "fugas de memoria, punteros colgantes",
|
|
59
|
+
},
|
|
60
|
+
en: {
|
|
61
|
+
style: "Follow the formatting style already used in the project (check for a `.clang-format`).",
|
|
62
|
+
memory: "Manage memory carefully: prefer RAII/smart pointers over manual `new`/`delete` when the project already does.",
|
|
63
|
+
arch: [
|
|
64
|
+
"Keep header include guards (`#pragma once` or include guards) consistent with the rest of the project.",
|
|
65
|
+
"Declare every new dependency in the existing build system (CMakeLists.txt or Makefile).",
|
|
66
|
+
],
|
|
67
|
+
reviewFocus: "memory leaks, dangling pointers",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
function rules(detection, lang) {
|
|
71
|
+
const t = TEXTS[lang];
|
|
72
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
73
|
+
const testCmd = detection.packageManager?.value === "cmake" ? "cmake --build . && ctest" : "make test";
|
|
74
|
+
return {
|
|
75
|
+
summary: summarySentence(lang, "C/C++", framework, detection.packageManager?.value),
|
|
76
|
+
conventions: [t.style, runTestsConvention(lang, testCmd), t.memory],
|
|
77
|
+
architectureNotes: t.arch,
|
|
62
78
|
};
|
|
63
79
|
}
|
|
64
|
-
function promptTemplates(detection) {
|
|
65
|
-
const
|
|
80
|
+
function promptTemplates(detection, lang) {
|
|
81
|
+
const t = TEXTS[lang];
|
|
82
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
83
|
+
const runner = detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : undefined;
|
|
66
84
|
return [
|
|
67
|
-
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
body: `Revisa el diff actual buscando fugas de memoria, punteros colgantes y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
id: "refactor",
|
|
74
|
-
title: "Refactor (C/C++)",
|
|
75
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
id: "testing",
|
|
79
|
-
title: "Testing (C/C++)",
|
|
80
|
-
body: `Escribe tests con ${detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : "el framework de tests del proyecto"} para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
81
|
-
},
|
|
85
|
+
{ id: "review", title: "Code Review (C/C++)", body: reviewBody(lang, t.reviewFocus, framework) },
|
|
86
|
+
{ id: "refactor", title: "Refactor (C/C++)", body: refactorBody(lang) },
|
|
87
|
+
{ id: "testing", title: "Testing (C/C++)", body: testingBody(lang, runner) },
|
|
82
88
|
];
|
|
83
89
|
}
|
|
84
90
|
export const cppPack = { id: "cpp", detect, rules, promptTemplates };
|
package/dist/packs/csharp.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
1
2
|
function detect(signals) {
|
|
2
3
|
const source = signals.csproj;
|
|
3
4
|
if (!source)
|
|
@@ -21,39 +22,43 @@ function detect(signals) {
|
|
|
21
22
|
packageManager: { value: "nuget", confidence: "high" },
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"Sigue las convenciones de nombrado de .NET (PascalCase para clases/métodos públicos, camelCase para variables locales).",
|
|
30
|
-
`Ejecuta los tests con \`dotnet test\` antes de terminar una tarea.`,
|
|
31
|
-
"Declara toda dependencia nueva vía NuGet en el .csproj, nunca la añadas manualmente sin registrarla.",
|
|
32
|
-
],
|
|
33
|
-
architectureNotes: [
|
|
25
|
+
const TEXTS = {
|
|
26
|
+
es: {
|
|
27
|
+
naming: "Sigue las convenciones de nombrado de .NET (PascalCase para clases/métodos públicos, camelCase para variables locales).",
|
|
28
|
+
deps: "Declara toda dependencia nueva vía NuGet en el .csproj, nunca la añadas manualmente sin registrarla.",
|
|
29
|
+
arch: [
|
|
34
30
|
"Respeta la separación en capas (controller/service/repository) si el proyecto ya la usa.",
|
|
35
31
|
"Prefiere inyección de dependencias sobre instanciación manual cuando el framework ya la ofrezca.",
|
|
36
32
|
],
|
|
33
|
+
reviewFocus: "null-safety",
|
|
34
|
+
},
|
|
35
|
+
en: {
|
|
36
|
+
naming: ".NET naming conventions apply (PascalCase for classes/public methods, camelCase for local variables).",
|
|
37
|
+
deps: "Declare every new dependency via NuGet in the .csproj; never add it manually without registering it.",
|
|
38
|
+
arch: [
|
|
39
|
+
"Respect the layered separation (controller/service/repository) if the project already uses it.",
|
|
40
|
+
"Prefer dependency injection over manual instantiation when the framework already provides it.",
|
|
41
|
+
],
|
|
42
|
+
reviewFocus: "null-safety",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
function rules(detection, lang) {
|
|
46
|
+
const t = TEXTS[lang];
|
|
47
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
48
|
+
return {
|
|
49
|
+
summary: summarySentence(lang, "C#/.NET", framework, "NuGet"),
|
|
50
|
+
conventions: [t.naming, runTestsConvention(lang, "`dotnet test`"), t.deps],
|
|
51
|
+
architectureNotes: t.arch,
|
|
37
52
|
};
|
|
38
53
|
}
|
|
39
|
-
function promptTemplates(detection) {
|
|
40
|
-
const
|
|
54
|
+
function promptTemplates(detection, lang) {
|
|
55
|
+
const t = TEXTS[lang];
|
|
56
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
57
|
+
const runner = detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : undefined;
|
|
41
58
|
return [
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
body: `Revisa el diff actual buscando bugs, null-safety y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: "refactor",
|
|
49
|
-
title: "Refactor (C#/.NET)",
|
|
50
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: "testing",
|
|
54
|
-
title: "Testing (C#/.NET)",
|
|
55
|
-
body: `Escribe tests con ${detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : "el test runner del proyecto"} para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
56
|
-
},
|
|
59
|
+
{ id: "review", title: "Code Review (C#/.NET)", body: reviewBody(lang, t.reviewFocus, framework) },
|
|
60
|
+
{ id: "refactor", title: "Refactor (C#/.NET)", body: refactorBody(lang) },
|
|
61
|
+
{ id: "testing", title: "Testing (C#/.NET)", body: testingBody(lang, runner) },
|
|
57
62
|
];
|
|
58
63
|
}
|
|
59
64
|
export const csharpPack = { id: "csharp", detect, rules, promptTemplates };
|
package/dist/packs/dart.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
1
2
|
function detect(signals) {
|
|
2
3
|
const source = signals.pubspecYaml;
|
|
3
4
|
if (!source)
|
|
@@ -21,41 +22,39 @@ function detect(signals) {
|
|
|
21
22
|
packageManager: { value: "pub", confidence: "high" },
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const TEXTS = {
|
|
26
|
+
es: {
|
|
27
|
+
style: "Sigue la guía de estilo oficial de Dart (dart.dev/effective-dart/style).",
|
|
28
|
+
deps: "Declara toda dependencia nueva en pubspec.yaml, nunca la instales sin registrarla.",
|
|
29
|
+
archFlutter: "Separa la lógica de negocio de los widgets cuando el proyecto ya siga ese patrón (p. ej. BLoC/Provider/Riverpod).",
|
|
30
|
+
archPlain: "Mantén los módulos con una responsabilidad clara.",
|
|
31
|
+
immutability: "Prefiere `final`/`const` sobre variables mutables cuando sea posible.",
|
|
32
|
+
},
|
|
33
|
+
en: {
|
|
34
|
+
style: "Follow the official Dart style guide (dart.dev/effective-dart/style).",
|
|
35
|
+
deps: "Declare every new dependency in pubspec.yaml; never install one without registering it.",
|
|
36
|
+
archFlutter: "Keep business logic out of widgets when the project already follows that pattern (e.g. BLoC/Provider/Riverpod).",
|
|
37
|
+
archPlain: "Keep modules single-purpose.",
|
|
38
|
+
immutability: "Prefer `final`/`const` over mutable variables when possible.",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
function rules(detection, lang) {
|
|
42
|
+
const t = TEXTS[lang];
|
|
43
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
44
|
+
const runner = detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : undefined;
|
|
26
45
|
return {
|
|
27
|
-
summary:
|
|
28
|
-
conventions: [
|
|
29
|
-
|
|
30
|
-
`Ejecuta los tests con ${detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : "el test runner del proyecto"} antes de terminar una tarea.`,
|
|
31
|
-
"Declara toda dependencia nueva en pubspec.yaml, nunca la instales sin registrarla.",
|
|
32
|
-
],
|
|
33
|
-
architectureNotes: [
|
|
34
|
-
framework === "flutter"
|
|
35
|
-
? "Separa la lógica de negocio de los widgets cuando el proyecto ya siga ese patrón (p. ej. BLoC/Provider/Riverpod)."
|
|
36
|
-
: "Mantén los módulos con una responsabilidad clara.",
|
|
37
|
-
"Prefiere `final`/`const` sobre variables mutables cuando sea posible.",
|
|
38
|
-
],
|
|
46
|
+
summary: summarySentence(lang, "Dart", framework, "pub"),
|
|
47
|
+
conventions: [t.style, runTestsConvention(lang, runner), t.deps],
|
|
48
|
+
architectureNotes: [framework === "flutter" ? t.archFlutter : t.archPlain, t.immutability],
|
|
39
49
|
};
|
|
40
50
|
}
|
|
41
|
-
function promptTemplates(detection) {
|
|
42
|
-
const framework = detection.framework?.value
|
|
51
|
+
function promptTemplates(detection, lang) {
|
|
52
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
53
|
+
const runner = detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : undefined;
|
|
43
54
|
return [
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
body: `Revisa el diff actual buscando bugs y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "refactor",
|
|
51
|
-
title: "Refactor (Dart)",
|
|
52
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
id: "testing",
|
|
56
|
-
title: "Testing (Dart)",
|
|
57
|
-
body: `Escribe tests con ${detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : "el test runner del proyecto"} para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
58
|
-
},
|
|
55
|
+
{ id: "review", title: "Code Review (Dart)", body: reviewBody(lang, "", framework) },
|
|
56
|
+
{ id: "refactor", title: "Refactor (Dart)", body: refactorBody(lang) },
|
|
57
|
+
{ id: "testing", title: "Testing (Dart)", body: testingBody(lang, runner) },
|
|
59
58
|
];
|
|
60
59
|
}
|
|
61
60
|
export const dartPack = { id: "dart", detect, rules, promptTemplates };
|
package/dist/packs/elixir.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
1
2
|
function detect(signals) {
|
|
2
3
|
const source = signals.mixExs;
|
|
3
4
|
if (!source)
|
|
@@ -18,39 +19,42 @@ function detect(signals) {
|
|
|
18
19
|
packageManager: { value: "mix", confidence: "high" },
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"Sigue la guía de estilo oficial de Elixir; ejecuta `mix format` antes de terminar una tarea.",
|
|
27
|
-
"Ejecuta los tests con `mix test` antes de terminar una tarea.",
|
|
28
|
-
"Prefiere pattern matching y pipelines (`|>`) sobre anidar llamadas de función.",
|
|
29
|
-
],
|
|
30
|
-
architectureNotes: [
|
|
22
|
+
const TEXTS = {
|
|
23
|
+
es: {
|
|
24
|
+
style: "Sigue la guía de estilo oficial de Elixir; ejecuta `mix format` antes de terminar una tarea.",
|
|
25
|
+
patterns: "Prefiere pattern matching y pipelines (`|>`) sobre anidar llamadas de función.",
|
|
26
|
+
arch: [
|
|
31
27
|
"Respeta la separación entre contextos (lógica de negocio) y la capa web si el proyecto ya usa Phoenix.",
|
|
32
28
|
"Declara toda dependencia nueva en `mix.exs` y mantén `mix.lock` sincronizado.",
|
|
33
29
|
],
|
|
30
|
+
reviewFocus: "procesos sin supervisar correctamente",
|
|
31
|
+
},
|
|
32
|
+
en: {
|
|
33
|
+
style: "Follow the official Elixir style guide; run `mix format` before finishing a task.",
|
|
34
|
+
patterns: "Prefer pattern matching and pipelines (`|>`) over nesting function calls.",
|
|
35
|
+
arch: [
|
|
36
|
+
"Respect the separation between contexts (business logic) and the web layer if the project already uses Phoenix.",
|
|
37
|
+
"Declare every new dependency in `mix.exs` and keep `mix.lock` in sync.",
|
|
38
|
+
],
|
|
39
|
+
reviewFocus: "improperly supervised processes",
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
function rules(detection, lang) {
|
|
43
|
+
const t = TEXTS[lang];
|
|
44
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
45
|
+
return {
|
|
46
|
+
summary: summarySentence(lang, "Elixir", framework, "mix"),
|
|
47
|
+
conventions: [t.style, runTestsConvention(lang, "`mix test`"), t.patterns],
|
|
48
|
+
architectureNotes: t.arch,
|
|
34
49
|
};
|
|
35
50
|
}
|
|
36
|
-
function promptTemplates(detection) {
|
|
37
|
-
const
|
|
51
|
+
function promptTemplates(detection, lang) {
|
|
52
|
+
const t = TEXTS[lang];
|
|
53
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
38
54
|
return [
|
|
39
|
-
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
body: `Revisa el diff actual buscando bugs, procesos sin supervisar correctamente y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
id: "refactor",
|
|
46
|
-
title: "Refactor (Elixir)",
|
|
47
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "testing",
|
|
51
|
-
title: "Testing (Elixir)",
|
|
52
|
-
body: `Escribe tests con \`mix test\` (ExUnit) para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
53
|
-
},
|
|
55
|
+
{ id: "review", title: "Code Review (Elixir)", body: reviewBody(lang, t.reviewFocus, framework) },
|
|
56
|
+
{ id: "refactor", title: "Refactor (Elixir)", body: refactorBody(lang) },
|
|
57
|
+
{ id: "testing", title: "Testing (Elixir)", body: testingBody(lang, "`mix test` (ExUnit)") },
|
|
54
58
|
];
|
|
55
59
|
}
|
|
56
60
|
export const elixirPack = { id: "elixir", detect, rules, promptTemplates };
|
package/dist/packs/go.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
1
2
|
const FRAMEWORKS = [
|
|
2
3
|
["gin-gonic/gin", "gin"],
|
|
3
4
|
["labstack/echo", "echo"],
|
|
@@ -36,39 +37,42 @@ function detect(signals) {
|
|
|
36
37
|
packageManager: { value: "go modules", confidence: "high" },
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"Sigue el formato estándar de `gofmt`; no introduzcas estilos alternativos.",
|
|
45
|
-
"Ejecuta los tests con `go test ./...` antes de terminar una tarea.",
|
|
46
|
-
"Maneja los errores explícitamente (`if err != nil`); no los ignores en silencio.",
|
|
47
|
-
],
|
|
48
|
-
architectureNotes: [
|
|
40
|
+
const TEXTS = {
|
|
41
|
+
es: {
|
|
42
|
+
style: "Sigue el formato estándar de `gofmt`; no introduzcas estilos alternativos.",
|
|
43
|
+
errors: "Maneja los errores explícitamente (`if err != nil`); no los ignores en silencio.",
|
|
44
|
+
arch: [
|
|
49
45
|
"Mantén los paquetes con una responsabilidad clara; evita paquetes `util` genéricos.",
|
|
50
46
|
"Declara toda dependencia nueva vía `go get` y mantén `go.mod`/`go.sum` sincronizados.",
|
|
51
47
|
],
|
|
48
|
+
reviewFocus: "manejo de errores omitido",
|
|
49
|
+
},
|
|
50
|
+
en: {
|
|
51
|
+
style: "Follow the standard `gofmt` formatting; do not introduce alternative styles.",
|
|
52
|
+
errors: "Handle errors explicitly (`if err != nil`); never ignore them silently.",
|
|
53
|
+
arch: [
|
|
54
|
+
"Keep packages single-purpose; avoid generic `util` packages.",
|
|
55
|
+
"Declare every new dependency via `go get` and keep `go.mod`/`go.sum` in sync.",
|
|
56
|
+
],
|
|
57
|
+
reviewFocus: "missing error handling",
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
function rules(detection, lang) {
|
|
61
|
+
const t = TEXTS[lang];
|
|
62
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
63
|
+
return {
|
|
64
|
+
summary: summarySentence(lang, "Go", framework, "go modules"),
|
|
65
|
+
conventions: [t.style, runTestsConvention(lang, "`go test ./...`"), t.errors],
|
|
66
|
+
architectureNotes: t.arch,
|
|
52
67
|
};
|
|
53
68
|
}
|
|
54
|
-
function promptTemplates(detection) {
|
|
55
|
-
const
|
|
69
|
+
function promptTemplates(detection, lang) {
|
|
70
|
+
const t = TEXTS[lang];
|
|
71
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
56
72
|
return [
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
body: `Revisa el diff actual buscando bugs, manejo de errores omitido y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
id: "refactor",
|
|
64
|
-
title: "Refactor (Go)",
|
|
65
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
id: "testing",
|
|
69
|
-
title: "Testing (Go)",
|
|
70
|
-
body: `Escribe tests con \`go test\` para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
71
|
-
},
|
|
73
|
+
{ id: "review", title: "Code Review (Go)", body: reviewBody(lang, t.reviewFocus, framework) },
|
|
74
|
+
{ id: "refactor", title: "Refactor (Go)", body: refactorBody(lang) },
|
|
75
|
+
{ id: "testing", title: "Testing (Go)", body: testingBody(lang, "`go test`") },
|
|
72
76
|
];
|
|
73
77
|
}
|
|
74
78
|
export const goPack = { id: "go", detect, rules, promptTemplates };
|
package/dist/packs/java.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { refactorBody, reviewBody, runTestsConvention, summarySentence, testingBody, } from "../core/i18n.js";
|
|
2
|
+
import { canonicalOf } from "../core/canonical-commands.js";
|
|
3
|
+
const SPRING_RISK = {
|
|
4
|
+
es: "Presta especial atención a los límites de transacción (@Transactional), la inyección de dependencias y la separación controller/service/repository.",
|
|
5
|
+
en: "Pay special attention to transaction boundaries (@Transactional), dependency injection and the controller/service/repository separation.",
|
|
6
|
+
};
|
|
1
7
|
function detect(signals) {
|
|
2
8
|
const source = signals.pomXml ?? signals.buildGradle;
|
|
3
9
|
if (!source)
|
|
@@ -8,52 +14,98 @@ function detect(signals) {
|
|
|
8
14
|
// (`alias(libs.plugins.kotlin.android)`) rather than the literal `kotlin("jvm")` or
|
|
9
15
|
// `org.jetbrains.kotlin` plugin id, so a plain word-boundary check on "kotlin" is
|
|
10
16
|
// more robust than trying to match every DSL style.
|
|
11
|
-
if (/\bkotlin\b/i.test(
|
|
17
|
+
if ((signals.buildGradle && /\bkotlin\b/i.test(signals.buildGradle)) ||
|
|
18
|
+
(signals.pomXml && /\bkotlin\b/i.test(signals.pomXml)))
|
|
12
19
|
return null;
|
|
13
20
|
const framework = /spring/i.test(source)
|
|
14
21
|
? { value: "spring", confidence: "high" }
|
|
15
22
|
: { value: "none", confidence: "low" };
|
|
16
23
|
const packageManager = signals.pomXml
|
|
17
|
-
?
|
|
18
|
-
|
|
24
|
+
? signals.hasFile("mvnw") || signals.hasFile("mvnw.cmd")
|
|
25
|
+
? { value: "maven wrapper", confidence: "high" }
|
|
26
|
+
: { value: "maven", confidence: "high" }
|
|
27
|
+
: signals.hasFile("gradlew") || signals.hasFile("gradlew.bat")
|
|
28
|
+
? { value: "gradle wrapper", confidence: "high" }
|
|
29
|
+
: { value: "gradle", confidence: "high" };
|
|
19
30
|
const testRunner = /junit/i.test(source)
|
|
20
31
|
? { value: "junit", confidence: "high" }
|
|
21
32
|
: { value: "unknown", confidence: "low" };
|
|
22
33
|
return { packId: "java", language: "Java", framework, packageManager, testRunner };
|
|
23
34
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"Sigue las convenciones de nombrado estándar de Java (PascalCase para clases, camelCase para métodos).",
|
|
30
|
-
`Ejecuta los tests con ${detection.packageManager?.value === "maven" ? "mvn test" : "gradle test"} antes de terminar una tarea.`,
|
|
31
|
-
"No añadas dependencias nuevas sin declararlas en el gestor de build existente.",
|
|
32
|
-
],
|
|
33
|
-
architectureNotes: [
|
|
35
|
+
const TEXTS = {
|
|
36
|
+
es: {
|
|
37
|
+
naming: "Sigue las convenciones de nombrado estándar de Java (PascalCase para clases, camelCase para métodos).",
|
|
38
|
+
deps: "No añadas dependencias nuevas sin declararlas en el gestor de build existente.",
|
|
39
|
+
arch: [
|
|
34
40
|
"Respeta la separación en capas (controller/service/repository) si el proyecto ya la usa.",
|
|
35
41
|
"Prefiere inyección de dependencias sobre instanciación manual cuando el framework ya la ofrezca.",
|
|
36
42
|
],
|
|
43
|
+
reviewFocus: "null-safety",
|
|
44
|
+
},
|
|
45
|
+
en: {
|
|
46
|
+
naming: "Follow standard Java naming conventions (PascalCase for classes, camelCase for methods).",
|
|
47
|
+
deps: "Do not add new dependencies without declaring them in the existing build tool.",
|
|
48
|
+
arch: [
|
|
49
|
+
"Respect the layered separation (controller/service/repository) if the project already uses it.",
|
|
50
|
+
"Prefer dependency injection over manual instantiation when the framework already provides it.",
|
|
51
|
+
],
|
|
52
|
+
reviewFocus: "null-safety",
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
function rules(detection, lang, ctx) {
|
|
56
|
+
const t = TEXTS[lang];
|
|
57
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
58
|
+
const wrapperCmd = detection.packageManager?.value === "maven wrapper"
|
|
59
|
+
? "./mvnw test"
|
|
60
|
+
: detection.packageManager?.value === "maven"
|
|
61
|
+
? "mvn test"
|
|
62
|
+
: detection.packageManager?.value === "gradle wrapper"
|
|
63
|
+
? "./gradlew test"
|
|
64
|
+
: "gradle test";
|
|
65
|
+
const testCmd = canonicalOf(ctx, "test", "java")?.command ?? wrapperCmd;
|
|
66
|
+
return {
|
|
67
|
+
summary: summarySentence(lang, "Java", framework, detection.packageManager?.value),
|
|
68
|
+
conventions: [t.naming, runTestsConvention(lang, testCmd), t.deps],
|
|
69
|
+
architectureNotes: t.arch,
|
|
37
70
|
};
|
|
38
71
|
}
|
|
39
|
-
function promptTemplates(detection) {
|
|
40
|
-
const
|
|
72
|
+
function promptTemplates(detection, lang, ctx) {
|
|
73
|
+
const t = TEXTS[lang];
|
|
74
|
+
const framework = detection.framework?.value !== "none" ? detection.framework?.value : undefined;
|
|
75
|
+
const runner = detection.testRunner?.value !== "unknown" ? detection.testRunner?.value : undefined;
|
|
76
|
+
const test = canonicalOf(ctx, "test", "java");
|
|
77
|
+
const build = canonicalOf(ctx, "build", "java");
|
|
78
|
+
const testDirs = ctx?.facts.testDirs ?? [];
|
|
79
|
+
const es = lang === "es";
|
|
80
|
+
const reviewParts = [];
|
|
81
|
+
reviewParts.push(es
|
|
82
|
+
? `Revisa el diff actual contra las convenciones Java de este repositorio${framework ? ` (${framework})` : ""}.`
|
|
83
|
+
: `Review the current diff against this repository's Java conventions${framework ? ` (${framework})` : ""}.`);
|
|
84
|
+
if (test) {
|
|
85
|
+
reviewParts.push(es ? `Ejecuta \`${test.command}\` antes de dar por buena la revisión.` : `Run \`${test.command}\` before approving the review.`);
|
|
86
|
+
}
|
|
87
|
+
if (build && build.command !== test?.command) {
|
|
88
|
+
reviewParts.push(es ? `CI también ejecuta \`${build.command}\`.` : `CI also runs \`${build.command}\`.`);
|
|
89
|
+
}
|
|
90
|
+
if (framework === "spring")
|
|
91
|
+
reviewParts.push(SPRING_RISK[lang]);
|
|
92
|
+
reviewParts.push(es ? `Busca también bugs: ${t.reviewFocus}.` : `Also look for bugs: ${t.reviewFocus}.`);
|
|
93
|
+
if (testDirs.length > 0) {
|
|
94
|
+
const dirs = testDirs.map((d) => `\`${d}\``).join(", ");
|
|
95
|
+
reviewParts.push(es ? `Los tests viven en ${dirs}.` : `Tests live under ${dirs}.`);
|
|
96
|
+
}
|
|
97
|
+
reviewParts.push(es ? "Señala solo hallazgos concretos con archivo y línea." : "Report only concrete findings with file and line references.");
|
|
98
|
+
const testingParts = [testingBody(lang, runner)];
|
|
99
|
+
if (test)
|
|
100
|
+
testingParts.push(es ? `Verifica la suite con \`${test.command}\` antes de terminar.` : `Verify the suite with \`${test.command}\` before finishing.`);
|
|
101
|
+
if (testDirs.length > 0) {
|
|
102
|
+
const dirs = testDirs.map((d) => `\`${d}\``).join(", ");
|
|
103
|
+
testingParts.push(es ? `Coloca los tests nuevos en ${dirs}.` : `Place new tests under ${dirs}.`);
|
|
104
|
+
}
|
|
41
105
|
return [
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
body: `Revisa el diff actual buscando bugs, null-safety y desviaciones de las convenciones de ${framework}. Señala solo problemas concretos con línea de archivo.`,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: "refactor",
|
|
49
|
-
title: "Refactor (Java)",
|
|
50
|
-
body: `Propón refactors que reduzcan duplicación y mejoren la legibilidad sin cambiar comportamiento observable.`,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: "testing",
|
|
54
|
-
title: "Testing (Java)",
|
|
55
|
-
body: `Escribe tests con ${detection.testRunner?.value ?? "el test runner del proyecto"} para el código señalado. Cubre el camino feliz y al menos un caso límite.`,
|
|
56
|
-
},
|
|
106
|
+
{ id: "review", title: "Code Review (Java)", body: ctx ? reviewParts.join(" ") : reviewBody(lang, t.reviewFocus, framework) },
|
|
107
|
+
{ id: "refactor", title: "Refactor (Java)", body: refactorBody(lang) },
|
|
108
|
+
{ id: "testing", title: "Testing (Java)", body: ctx ? testingParts.join(" ") : testingBody(lang, runner) },
|
|
57
109
|
];
|
|
58
110
|
}
|
|
59
111
|
export const javaPack = { id: "java", detect, rules, promptTemplates };
|