@backendkit-labs/agent-coding 0.14.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 (193) hide show
  1. package/dist/agents/AgentLoader.d.ts +33 -0
  2. package/dist/agents/AgentLoader.d.ts.map +1 -0
  3. package/dist/agents/AgentLoader.js +167 -0
  4. package/dist/agents/AgentLoader.js.map +1 -0
  5. package/dist/agents/profiles.d.ts +3 -0
  6. package/dist/agents/profiles.d.ts.map +1 -0
  7. package/dist/agents/profiles.js +121 -0
  8. package/dist/agents/profiles.js.map +1 -0
  9. package/dist/agents/prompts/architecture.d.ts +2 -0
  10. package/dist/agents/prompts/architecture.d.ts.map +1 -0
  11. package/dist/agents/prompts/architecture.js +151 -0
  12. package/dist/agents/prompts/architecture.js.map +1 -0
  13. package/dist/agents/prompts/backend.d.ts +2 -0
  14. package/dist/agents/prompts/backend.d.ts.map +1 -0
  15. package/dist/agents/prompts/backend.js +96 -0
  16. package/dist/agents/prompts/backend.js.map +1 -0
  17. package/dist/agents/prompts/coder.d.ts +2 -0
  18. package/dist/agents/prompts/coder.d.ts.map +1 -0
  19. package/dist/agents/prompts/coder.js +50 -0
  20. package/dist/agents/prompts/coder.js.map +1 -0
  21. package/dist/agents/prompts/data.d.ts +2 -0
  22. package/dist/agents/prompts/data.d.ts.map +1 -0
  23. package/dist/agents/prompts/data.js +123 -0
  24. package/dist/agents/prompts/data.js.map +1 -0
  25. package/dist/agents/prompts/frontend.d.ts +2 -0
  26. package/dist/agents/prompts/frontend.d.ts.map +1 -0
  27. package/dist/agents/prompts/frontend.js +91 -0
  28. package/dist/agents/prompts/frontend.js.map +1 -0
  29. package/dist/agents/prompts/general.d.ts +2 -0
  30. package/dist/agents/prompts/general.d.ts.map +1 -0
  31. package/dist/agents/prompts/general.js +93 -0
  32. package/dist/agents/prompts/general.js.map +1 -0
  33. package/dist/agents/prompts/infrastructure.d.ts +2 -0
  34. package/dist/agents/prompts/infrastructure.d.ts.map +1 -0
  35. package/dist/agents/prompts/infrastructure.js +145 -0
  36. package/dist/agents/prompts/infrastructure.js.map +1 -0
  37. package/dist/agents/prompts/project-manager.d.ts +2 -0
  38. package/dist/agents/prompts/project-manager.d.ts.map +1 -0
  39. package/dist/agents/prompts/project-manager.js +66 -0
  40. package/dist/agents/prompts/project-manager.js.map +1 -0
  41. package/dist/agents/prompts/qa.d.ts +2 -0
  42. package/dist/agents/prompts/qa.d.ts.map +1 -0
  43. package/dist/agents/prompts/qa.js +166 -0
  44. package/dist/agents/prompts/qa.js.map +1 -0
  45. package/dist/agents/prompts/security.d.ts +2 -0
  46. package/dist/agents/prompts/security.d.ts.map +1 -0
  47. package/dist/agents/prompts/security.js +129 -0
  48. package/dist/agents/prompts/security.js.map +1 -0
  49. package/dist/config/ConfigLoader.d.ts +27 -0
  50. package/dist/config/ConfigLoader.d.ts.map +1 -0
  51. package/dist/config/ConfigLoader.js +167 -0
  52. package/dist/config/ConfigLoader.js.map +1 -0
  53. package/dist/index.d.ts +160 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +340 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/orchestration/capability-matrix.d.ts +10 -0
  58. package/dist/orchestration/capability-matrix.d.ts.map +1 -0
  59. package/dist/orchestration/capability-matrix.js +48 -0
  60. package/dist/orchestration/capability-matrix.js.map +1 -0
  61. package/dist/providers/AnthropicProvider.d.ts +20 -0
  62. package/dist/providers/AnthropicProvider.d.ts.map +1 -0
  63. package/dist/providers/AnthropicProvider.js +185 -0
  64. package/dist/providers/AnthropicProvider.js.map +1 -0
  65. package/dist/providers/DeepSeekProvider.d.ts +11 -0
  66. package/dist/providers/DeepSeekProvider.d.ts.map +1 -0
  67. package/dist/providers/DeepSeekProvider.js +18 -0
  68. package/dist/providers/DeepSeekProvider.js.map +1 -0
  69. package/dist/providers/OpenAICompatibleProvider.d.ts +22 -0
  70. package/dist/providers/OpenAICompatibleProvider.d.ts.map +1 -0
  71. package/dist/providers/OpenAICompatibleProvider.js +124 -0
  72. package/dist/providers/OpenAICompatibleProvider.js.map +1 -0
  73. package/dist/skills/builtins/global.d.ts +7 -0
  74. package/dist/skills/builtins/global.d.ts.map +1 -0
  75. package/dist/skills/builtins/global.js +208 -0
  76. package/dist/skills/builtins/global.js.map +1 -0
  77. package/dist/skills/builtins/go-pack.d.ts +7 -0
  78. package/dist/skills/builtins/go-pack.d.ts.map +1 -0
  79. package/dist/skills/builtins/go-pack.js +263 -0
  80. package/dist/skills/builtins/go-pack.js.map +1 -0
  81. package/dist/skills/builtins/java-pack.d.ts +7 -0
  82. package/dist/skills/builtins/java-pack.d.ts.map +1 -0
  83. package/dist/skills/builtins/java-pack.js +272 -0
  84. package/dist/skills/builtins/java-pack.js.map +1 -0
  85. package/dist/skills/builtins/kotlin-pack.d.ts +9 -0
  86. package/dist/skills/builtins/kotlin-pack.d.ts.map +1 -0
  87. package/dist/skills/builtins/kotlin-pack.js +292 -0
  88. package/dist/skills/builtins/kotlin-pack.js.map +1 -0
  89. package/dist/skills/builtins/node-pack.d.ts +7 -0
  90. package/dist/skills/builtins/node-pack.d.ts.map +1 -0
  91. package/dist/skills/builtins/node-pack.js +750 -0
  92. package/dist/skills/builtins/node-pack.js.map +1 -0
  93. package/dist/skills/builtins/python-pack.d.ts +7 -0
  94. package/dist/skills/builtins/python-pack.d.ts.map +1 -0
  95. package/dist/skills/builtins/python-pack.js +303 -0
  96. package/dist/skills/builtins/python-pack.js.map +1 -0
  97. package/dist/skills/index.d.ts +7 -0
  98. package/dist/skills/index.d.ts.map +1 -0
  99. package/dist/skills/index.js +16 -0
  100. package/dist/skills/index.js.map +1 -0
  101. package/dist/store/LearningRouter.d.ts +17 -0
  102. package/dist/store/LearningRouter.d.ts.map +1 -0
  103. package/dist/store/LearningRouter.js +165 -0
  104. package/dist/store/LearningRouter.js.map +1 -0
  105. package/dist/store/PersistentMemory.d.ts +10 -0
  106. package/dist/store/PersistentMemory.d.ts.map +1 -0
  107. package/dist/store/PersistentMemory.js +29 -0
  108. package/dist/store/PersistentMemory.js.map +1 -0
  109. package/dist/store/ProjectStore.d.ts +29 -0
  110. package/dist/store/ProjectStore.d.ts.map +1 -0
  111. package/dist/store/ProjectStore.js +191 -0
  112. package/dist/store/ProjectStore.js.map +1 -0
  113. package/dist/store/__tests__/PersistentMemory.test.d.ts +2 -0
  114. package/dist/store/__tests__/PersistentMemory.test.d.ts.map +1 -0
  115. package/dist/store/__tests__/PersistentMemory.test.js +46 -0
  116. package/dist/store/__tests__/PersistentMemory.test.js.map +1 -0
  117. package/dist/tools/__tests__/file-tools.test.d.ts +2 -0
  118. package/dist/tools/__tests__/file-tools.test.d.ts.map +1 -0
  119. package/dist/tools/__tests__/file-tools.test.js +144 -0
  120. package/dist/tools/__tests__/file-tools.test.js.map +1 -0
  121. package/dist/tools/__tests__/path-sandbox.test.d.ts +2 -0
  122. package/dist/tools/__tests__/path-sandbox.test.d.ts.map +1 -0
  123. package/dist/tools/__tests__/path-sandbox.test.js +45 -0
  124. package/dist/tools/__tests__/path-sandbox.test.js.map +1 -0
  125. package/dist/tools/__tests__/run-command.test.d.ts +2 -0
  126. package/dist/tools/__tests__/run-command.test.d.ts.map +1 -0
  127. package/dist/tools/__tests__/run-command.test.js +61 -0
  128. package/dist/tools/__tests__/run-command.test.js.map +1 -0
  129. package/dist/tools/append-log.d.ts +2 -0
  130. package/dist/tools/append-log.d.ts.map +1 -0
  131. package/dist/tools/append-log.js +3 -0
  132. package/dist/tools/append-log.js.map +1 -0
  133. package/dist/tools/edit-file.d.ts +2 -0
  134. package/dist/tools/edit-file.d.ts.map +1 -0
  135. package/dist/tools/edit-file.js +45 -0
  136. package/dist/tools/edit-file.js.map +1 -0
  137. package/dist/tools/list-directory.d.ts +2 -0
  138. package/dist/tools/list-directory.d.ts.map +1 -0
  139. package/dist/tools/list-directory.js +47 -0
  140. package/dist/tools/list-directory.js.map +1 -0
  141. package/dist/tools/path-sandbox.d.ts +31 -0
  142. package/dist/tools/path-sandbox.d.ts.map +1 -0
  143. package/dist/tools/path-sandbox.js +99 -0
  144. package/dist/tools/path-sandbox.js.map +1 -0
  145. package/dist/tools/read-file.d.ts +2 -0
  146. package/dist/tools/read-file.d.ts.map +1 -0
  147. package/dist/tools/read-file.js +28 -0
  148. package/dist/tools/read-file.js.map +1 -0
  149. package/dist/tools/run-command.d.ts +2 -0
  150. package/dist/tools/run-command.d.ts.map +1 -0
  151. package/dist/tools/run-command.js +192 -0
  152. package/dist/tools/run-command.js.map +1 -0
  153. package/dist/tools/save-audit.d.ts +4 -0
  154. package/dist/tools/save-audit.d.ts.map +1 -0
  155. package/dist/tools/save-audit.js +42 -0
  156. package/dist/tools/save-audit.js.map +1 -0
  157. package/dist/tools/save-context.d.ts +2 -0
  158. package/dist/tools/save-context.d.ts.map +1 -0
  159. package/dist/tools/save-context.js +18 -0
  160. package/dist/tools/save-context.js.map +1 -0
  161. package/dist/tools/save-learning.d.ts +2 -0
  162. package/dist/tools/save-learning.d.ts.map +1 -0
  163. package/dist/tools/save-learning.js +41 -0
  164. package/dist/tools/save-learning.js.map +1 -0
  165. package/dist/tools/save-user-preference.d.ts +3 -0
  166. package/dist/tools/save-user-preference.d.ts.map +1 -0
  167. package/dist/tools/save-user-preference.js +22 -0
  168. package/dist/tools/save-user-preference.js.map +1 -0
  169. package/dist/tools/search-files.d.ts +2 -0
  170. package/dist/tools/search-files.d.ts.map +1 -0
  171. package/dist/tools/search-files.js +170 -0
  172. package/dist/tools/search-files.js.map +1 -0
  173. package/dist/tools/secret-scanner.d.ts +15 -0
  174. package/dist/tools/secret-scanner.d.ts.map +1 -0
  175. package/dist/tools/secret-scanner.js +44 -0
  176. package/dist/tools/secret-scanner.js.map +1 -0
  177. package/dist/tools/update-session.d.ts +3 -0
  178. package/dist/tools/update-session.d.ts.map +1 -0
  179. package/dist/tools/update-session.js +49 -0
  180. package/dist/tools/update-session.js.map +1 -0
  181. package/dist/tools/write-file.d.ts +2 -0
  182. package/dist/tools/write-file.d.ts.map +1 -0
  183. package/dist/tools/write-file.js +32 -0
  184. package/dist/tools/write-file.js.map +1 -0
  185. package/dist/workflows/InitWorkflow.d.ts +6 -0
  186. package/dist/workflows/InitWorkflow.d.ts.map +1 -0
  187. package/dist/workflows/InitWorkflow.js +448 -0
  188. package/dist/workflows/InitWorkflow.js.map +1 -0
  189. package/dist/workflows/__tests__/InitWorkflow.test.d.ts +2 -0
  190. package/dist/workflows/__tests__/InitWorkflow.test.d.ts.map +1 -0
  191. package/dist/workflows/__tests__/InitWorkflow.test.js +43 -0
  192. package/dist/workflows/__tests__/InitWorkflow.test.js.map +1 -0
  193. package/package.json +34 -0
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GO_PACK_SKILLS = void 0;
4
+ /**
5
+ * Go skill pack (@bk-go).
6
+ * Activated for projects with go.mod.
7
+ */
8
+ exports.GO_PACK_SKILLS = [
9
+ {
10
+ name: 'go-error-handling',
11
+ version: '1.0.0',
12
+ description: 'Idiomatic Go error handling: wrapping, sentinel errors, errors.Is/As',
13
+ scope: 'pack',
14
+ pack: '@bk-go',
15
+ language: ['go'],
16
+ triggers: [
17
+ 'error', 'errors', 'manejo de errores', 'error handling',
18
+ 'fmt.Errorf', 'errors.Is', 'errors.As', 'sentinel', 'wrap',
19
+ ],
20
+ systemPromptAddition: `## Go Error Handling
21
+
22
+ NUNCA ignores errores. Siempre verifica el valor de retorno de error.
23
+
24
+ ### Wrapping (conserva la cadena de contexto)
25
+ \`\`\`go
26
+ if err != nil {
27
+ return fmt.Errorf("userService.FindByID %q: %w", id, err)
28
+ }
29
+ \`\`\`
30
+
31
+ ### Sentinel errors (errores de dominio)
32
+ \`\`\`go
33
+ var (
34
+ ErrNotFound = errors.New("not found")
35
+ ErrConflict = errors.New("conflict")
36
+ ErrValidation = errors.New("validation failed")
37
+ )
38
+
39
+ // Verificar en el caller:
40
+ if errors.Is(err, ErrNotFound) { ... }
41
+ \`\`\`
42
+
43
+ ### Errores con datos (implementar error interface)
44
+ \`\`\`go
45
+ type ValidationError struct {
46
+ Field string
47
+ Message string
48
+ }
49
+ func (e *ValidationError) Error() string {
50
+ return fmt.Sprintf("validation: %s — %s", e.Field, e.Message)
51
+ }
52
+
53
+ // Extraer en el caller:
54
+ var ve *ValidationError
55
+ if errors.As(err, &ve) { ... }
56
+ \`\`\`
57
+
58
+ ### Reglas
59
+ - Usa \`%w\` para wrapping (permite errors.Is/As upstream)
60
+ - Usa \`%v\` solo para logging, nunca para propagar
61
+ - Los mensajes de error en minúscula, sin punto final
62
+ - No uses \`panic\` para errores de negocio — solo para invariantes rotos`,
63
+ },
64
+ {
65
+ name: 'go-concurrency',
66
+ version: '1.0.0',
67
+ description: 'Goroutines, channels, context propagation and sync primitives',
68
+ scope: 'pack',
69
+ pack: '@bk-go',
70
+ language: ['go'],
71
+ triggers: [
72
+ 'goroutine', 'channel', 'chan', 'concurrencia', 'concurrency',
73
+ 'context', 'ctx', 'sync', 'mutex', 'waitgroup', 'select', 'timeout',
74
+ ],
75
+ systemPromptAddition: `## Go Concurrency
76
+
77
+ ### Context — siempre el primer parámetro
78
+ \`\`\`go
79
+ func (s *UserService) FindByID(ctx context.Context, id string) (*User, error) {
80
+ // Propaga ctx a toda operación I/O
81
+ return s.repo.FindByID(ctx, id)
82
+ }
83
+ \`\`\`
84
+
85
+ ### Timeout y cancelación
86
+ \`\`\`go
87
+ ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
88
+ defer cancel()
89
+ \`\`\`
90
+
91
+ ### Goroutines: siempre controla el ciclo de vida
92
+ \`\`\`go
93
+ var wg sync.WaitGroup
94
+ errCh := make(chan error, len(items)) // buffered para evitar goroutine leak
95
+
96
+ for _, item := range items {
97
+ wg.Add(1)
98
+ go func(item Item) {
99
+ defer wg.Done()
100
+ if err := process(ctx, item); err != nil {
101
+ errCh <- err
102
+ }
103
+ }(item)
104
+ }
105
+
106
+ wg.Wait()
107
+ close(errCh)
108
+ for err := range errCh { ... }
109
+ \`\`\`
110
+
111
+ ### Select con timeout
112
+ \`\`\`go
113
+ select {
114
+ case result := <-resultCh:
115
+ return result, nil
116
+ case <-ctx.Done():
117
+ return nil, ctx.Err()
118
+ }
119
+ \`\`\`
120
+
121
+ ### Reglas
122
+ - Nunca lances una goroutine sin controlar su ciclo de vida
123
+ - Usa canales buffered cuando el producer no debe bloquearse
124
+ - \`sync.Mutex\` para estado compartido simple; \`sync.RWMutex\` si hay muchas lecturas
125
+ - Nunca copies un Mutex — pásalo siempre por puntero`,
126
+ },
127
+ {
128
+ name: 'go-http-server',
129
+ version: '1.0.0',
130
+ description: 'HTTP server patterns: handlers, middleware, routing with net/http or chi',
131
+ scope: 'pack',
132
+ pack: '@bk-go',
133
+ language: ['go'],
134
+ triggers: [
135
+ 'http', 'handler', 'middleware', 'router', 'endpoint', 'api rest',
136
+ 'net/http', 'chi', 'gin', 'echo', 'mux', 'servidor', 'server',
137
+ ],
138
+ systemPromptAddition: `## Go HTTP Server
139
+
140
+ ### Handler con dependencias inyectadas
141
+ \`\`\`go
142
+ type UserHandler struct {
143
+ service UserService
144
+ }
145
+
146
+ func NewUserHandler(service UserService) *UserHandler {
147
+ return &UserHandler{service: service}
148
+ }
149
+
150
+ func (h *UserHandler) GetByID(w http.ResponseWriter, r *http.Request) {
151
+ id := chi.URLParam(r, "id") // o r.PathValue("id") en Go 1.22+
152
+ user, err := h.service.FindByID(r.Context(), id)
153
+ if err != nil {
154
+ writeError(w, err)
155
+ return
156
+ }
157
+ writeJSON(w, http.StatusOK, user)
158
+ }
159
+ \`\`\`
160
+
161
+ ### Middleware (adaptar al router usado)
162
+ \`\`\`go
163
+ func LoggingMiddleware(next http.Handler) http.Handler {
164
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
165
+ start := time.Now()
166
+ next.ServeHTTP(w, r)
167
+ slog.Info("request", "method", r.Method, "path", r.URL.Path,
168
+ "elapsed", time.Since(start))
169
+ })
170
+ }
171
+ \`\`\`
172
+
173
+ ### Helpers JSON
174
+ \`\`\`go
175
+ func writeJSON(w http.ResponseWriter, status int, v any) {
176
+ w.Header().Set("Content-Type", "application/json")
177
+ w.WriteHeader(status)
178
+ json.NewEncoder(w).Encode(v)
179
+ }
180
+
181
+ func writeError(w http.ResponseWriter, err error) {
182
+ switch {
183
+ case errors.Is(err, ErrNotFound):
184
+ writeJSON(w, http.StatusNotFound, map[string]string{"error": err.Error()})
185
+ case errors.Is(err, ErrValidation):
186
+ writeJSON(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
187
+ default:
188
+ writeJSON(w, http.StatusInternalServerError, map[string]string{"error": "internal server error"})
189
+ }
190
+ }
191
+ \`\`\`
192
+
193
+ ### Reglas
194
+ - Siempre propaga \`r.Context()\` a las llamadas de servicio
195
+ - Nunca escribas al ResponseWriter después de llamar a otro handler
196
+ - Usa \`slog\` (stdlib Go 1.21+) para logging estructurado
197
+ - Valida y deserializa el body antes de llamar al servicio`,
198
+ },
199
+ {
200
+ name: 'go-testing',
201
+ version: '1.0.0',
202
+ description: 'Table-driven tests, testify, interfaces for mocking',
203
+ scope: 'pack',
204
+ pack: '@bk-go',
205
+ language: ['go'],
206
+ triggers: [
207
+ 'test', 'tests', 'testing', 'prueba', 'mock', 'testify',
208
+ 'table driven', 'table-driven', 'assert', 'require', 'coverage',
209
+ ],
210
+ systemPromptAddition: `## Go Testing
211
+
212
+ ### Table-driven tests (patrón estándar)
213
+ \`\`\`go
214
+ func TestUserService_FindByID(t *testing.T) {
215
+ tests := []struct {
216
+ name string
217
+ id string
218
+ want *User
219
+ wantErr error
220
+ }{
221
+ {name: "found", id: "1", want: &User{ID: "1"}},
222
+ {name: "not found", id: "999", wantErr: ErrNotFound},
223
+ }
224
+
225
+ for _, tt := range tests {
226
+ t.Run(tt.name, func(t *testing.T) {
227
+ svc := NewUserService(newMockRepo(tt.want, tt.wantErr))
228
+ got, err := svc.FindByID(context.Background(), tt.id)
229
+ require.ErrorIs(t, err, tt.wantErr)
230
+ assert.Equal(t, tt.want, got)
231
+ })
232
+ }
233
+ }
234
+ \`\`\`
235
+
236
+ ### Mock via interface (sin frameworks externos)
237
+ \`\`\`go
238
+ type mockUserRepo struct {
239
+ user *User
240
+ err error
241
+ }
242
+ func (m *mockUserRepo) FindByID(_ context.Context, _ string) (*User, error) {
243
+ return m.user, m.err
244
+ }
245
+ func newMockRepo(u *User, err error) UserRepository { return &mockUserRepo{u, err} }
246
+ \`\`\`
247
+
248
+ ### Subtests y helpers
249
+ \`\`\`go
250
+ func TestIntegration(t *testing.T) {
251
+ if testing.Short() { t.Skip("skipping integration test") }
252
+ // ...
253
+ }
254
+ \`\`\`
255
+
256
+ ### Reglas
257
+ - Usa \`require\` (falla inmediato) para precondiciones; \`assert\` para verificaciones
258
+ - Define interfaces pequeñas para mockear dependencias — no dependas de tipos concretos
259
+ - Nombres: \`Test{Tipo}_{Metodo}_{Condicion}\`
260
+ - Usa \`t.Parallel()\` en tests sin estado compartido para acelerar el suite`,
261
+ },
262
+ ];
263
+ //# sourceMappingURL=go-pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"go-pack.js","sourceRoot":"","sources":["../../../src/skills/builtins/go-pack.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACU,QAAA,cAAc,GAAY;IACnC;QACI,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,sEAAsE;QACnF,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,QAAQ,EAAE;YACN,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,gBAAgB;YACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM;SAC7D;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4EA0C8C;KACvE;IACD;QACI,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,+DAA+D;QAC5E,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,QAAQ,EAAE;YACN,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa;YAC7D,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS;SACtE;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDAkD0B;KACnD;IACD;QACI,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,0EAA0E;QACvF,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,QAAQ,EAAE;YACN,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU;YACjE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ;SAChE;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2DA2D6B;KACtD;IACD;QACI,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,qDAAqD;QAClE,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,QAAQ,EAAE;YACN,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS;YACvD,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU;SAClE;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAkD+C;KACxE;CACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Skill } from '@backendkit-labs/agent-core';
2
+ /**
3
+ * Java / Spring Boot skill pack (@bk-java).
4
+ * Activated for projects with pom.xml or build.gradle.
5
+ */
6
+ export declare const JAVA_PACK_SKILLS: Skill[];
7
+ //# sourceMappingURL=java-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"java-pack.d.ts","sourceRoot":"","sources":["../../../src/skills/builtins/java-pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,EAuQnC,CAAC"}
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JAVA_PACK_SKILLS = void 0;
4
+ /**
5
+ * Java / Spring Boot skill pack (@bk-java).
6
+ * Activated for projects with pom.xml or build.gradle.
7
+ */
8
+ exports.JAVA_PACK_SKILLS = [
9
+ {
10
+ name: 'spring-layered-architecture',
11
+ version: '1.0.0',
12
+ description: 'Spring Boot layered architecture: Controller → Service → Repository',
13
+ scope: 'pack',
14
+ pack: '@bk-java',
15
+ language: ['java'],
16
+ triggers: [
17
+ 'spring', 'springboot', 'spring boot', 'controller', 'service', 'repository',
18
+ 'componente', 'component', 'bean', 'inyeccion', 'injection', 'autowired',
19
+ 'rest api', 'endpoint', 'api rest',
20
+ ],
21
+ systemPromptAddition: `## Spring Boot Layered Architecture
22
+
23
+ ### Capas (dependencias fluyen hacia abajo)
24
+ \`\`\`
25
+ Controller (@RestController) ← HTTP, validación de request, mapeo DTO
26
+ ↓
27
+ Service (@Service) ← lógica de negocio, transacciones
28
+ ↓
29
+ Repository (@Repository) ← acceso a datos, JPA/JDBC
30
+ ↓
31
+ Domain (entities, value objects) ← sin dependencias de Spring
32
+ \`\`\`
33
+
34
+ ### Controller — solo HTTP
35
+ \`\`\`java
36
+ @RestController
37
+ @RequestMapping("/api/users")
38
+ @RequiredArgsConstructor
39
+ public class UserController {
40
+ private final UserService userService;
41
+
42
+ @GetMapping("/{id}")
43
+ public ResponseEntity<UserResponse> findById(@PathVariable UUID id) {
44
+ return ResponseEntity.ok(userService.findById(id));
45
+ }
46
+
47
+ @PostMapping
48
+ @ResponseStatus(HttpStatus.CREATED)
49
+ public UserResponse create(@RequestBody @Valid CreateUserRequest request) {
50
+ return userService.create(request);
51
+ }
52
+ }
53
+ \`\`\`
54
+
55
+ ### Service — lógica de negocio
56
+ \`\`\`java
57
+ @Service
58
+ @RequiredArgsConstructor
59
+ @Transactional(readOnly = true)
60
+ public class UserService {
61
+ private final UserRepository userRepository;
62
+
63
+ public UserResponse findById(UUID id) {
64
+ return userRepository.findById(id)
65
+ .map(UserMapper::toResponse)
66
+ .orElseThrow(() -> new ResourceNotFoundException("User", id));
67
+ }
68
+
69
+ @Transactional
70
+ public UserResponse create(CreateUserRequest request) {
71
+ // validaciones de negocio aquí
72
+ User user = UserMapper.fromRequest(request);
73
+ return UserMapper.toResponse(userRepository.save(user));
74
+ }
75
+ }
76
+ \`\`\`
77
+
78
+ ### Reglas
79
+ - Nunca expongas entidades JPA directamente — usa DTOs (record o class)
80
+ - \`@Transactional(readOnly = true)\` a nivel de clase; \`@Transactional\` en métodos de escritura
81
+ - Usa \`@RequiredArgsConstructor\` (Lombok) para inyección por constructor — nunca \`@Autowired\` en campo
82
+ - Los controllers no llaman a repositories directamente`,
83
+ },
84
+ {
85
+ name: 'spring-exception-handling',
86
+ version: '1.0.0',
87
+ description: 'Global exception handling with @ControllerAdvice and ProblemDetail (RFC 7807)',
88
+ scope: 'pack',
89
+ pack: '@bk-java',
90
+ language: ['java'],
91
+ triggers: [
92
+ 'exception', 'error handling', 'manejo de errores', 'controlleradvice',
93
+ 'exceptionhandler', 'problem detail', 'errorresponse', '404', '400', '500',
94
+ ],
95
+ systemPromptAddition: `## Spring Exception Handling
96
+
97
+ ### Excepciones de dominio
98
+ \`\`\`java
99
+ public class ResourceNotFoundException extends RuntimeException {
100
+ public ResourceNotFoundException(String resource, Object id) {
101
+ super(resource + " not found: " + id);
102
+ }
103
+ }
104
+
105
+ public class BusinessRuleException extends RuntimeException {
106
+ public BusinessRuleException(String message) { super(message); }
107
+ }
108
+ \`\`\`
109
+
110
+ ### Handler global (Spring 6 / Boot 3 — ProblemDetail RFC 7807)
111
+ \`\`\`java
112
+ @RestControllerAdvice
113
+ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
114
+
115
+ @ExceptionHandler(ResourceNotFoundException.class)
116
+ ProblemDetail handleNotFound(ResourceNotFoundException ex) {
117
+ return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
118
+ }
119
+
120
+ @ExceptionHandler(BusinessRuleException.class)
121
+ ProblemDetail handleBusiness(BusinessRuleException ex) {
122
+ return ProblemDetail.forStatusAndDetail(HttpStatus.UNPROCESSABLE_ENTITY, ex.getMessage());
123
+ }
124
+
125
+ @Override
126
+ protected ResponseEntity<Object> handleMethodArgumentNotValid(
127
+ MethodArgumentNotValidException ex, HttpHeaders headers,
128
+ HttpStatusCode status, WebRequest request) {
129
+ ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
130
+ pd.setProperty("errors", ex.getBindingResult().getFieldErrors().stream()
131
+ .map(e -> e.getField() + ": " + e.getDefaultMessage())
132
+ .toList());
133
+ return ResponseEntity.badRequest().body(pd);
134
+ }
135
+ }
136
+ \`\`\`
137
+
138
+ ### Reglas
139
+ - Nunca devuelvas stack traces al cliente — loguéalos internamente
140
+ - Usa \`ProblemDetail\` (Spring 6+) para respuestas de error estándar
141
+ - Las excepciones de dominio son RuntimeException — no checked exceptions
142
+ - Loguea con \`log.warn\` para 4xx y \`log.error\` para 5xx`,
143
+ },
144
+ {
145
+ name: 'spring-testing',
146
+ version: '1.0.0',
147
+ description: 'JUnit 5, Mockito, @WebMvcTest and @DataJpaTest slices',
148
+ scope: 'pack',
149
+ pack: '@bk-java',
150
+ language: ['java'],
151
+ triggers: [
152
+ 'test', 'tests', 'testing', 'junit', 'mockito', 'mock', 'prueba',
153
+ 'webmvctest', 'datajpatest', 'springboottest', 'coverage', 'cobertura',
154
+ ],
155
+ systemPromptAddition: `## Spring Testing
156
+
157
+ ### Test de servicio (puro, sin Spring)
158
+ \`\`\`java
159
+ @ExtendWith(MockitoExtension.class)
160
+ class UserServiceTest {
161
+ @Mock UserRepository userRepository;
162
+ @InjectMocks UserService userService;
163
+
164
+ @Test
165
+ void findById_whenExists_returnsUser() {
166
+ var user = new User(UUID.randomUUID(), "ana@example.com");
167
+ when(userRepository.findById(user.getId())).thenReturn(Optional.of(user));
168
+
169
+ var result = userService.findById(user.getId());
170
+
171
+ assertThat(result.email()).isEqualTo("ana@example.com");
172
+ verify(userRepository).findById(user.getId());
173
+ }
174
+
175
+ @Test
176
+ void findById_whenMissing_throwsNotFound() {
177
+ var id = UUID.randomUUID();
178
+ when(userRepository.findById(id)).thenReturn(Optional.empty());
179
+
180
+ assertThatThrownBy(() -> userService.findById(id))
181
+ .isInstanceOf(ResourceNotFoundException.class);
182
+ }
183
+ }
184
+ \`\`\`
185
+
186
+ ### Test de controller (slice — solo capa HTTP)
187
+ \`\`\`java
188
+ @WebMvcTest(UserController.class)
189
+ class UserControllerTest {
190
+ @Autowired MockMvc mockMvc;
191
+ @MockBean UserService userService;
192
+
193
+ @Test
194
+ void getById_returns200() throws Exception {
195
+ var response = new UserResponse(UUID.randomUUID(), "ana@example.com");
196
+ when(userService.findById(any())).thenReturn(response);
197
+
198
+ mockMvc.perform(get("/api/users/{id}", response.id()))
199
+ .andExpect(status().isOk())
200
+ .andExpect(jsonPath("$.email").value("ana@example.com"));
201
+ }
202
+ }
203
+ \`\`\`
204
+
205
+ ### Reglas
206
+ - Prefiere unit tests de servicio (sin contexto Spring) para lógica de negocio
207
+ - Usa \`@WebMvcTest\` para HTTP layer y \`@DataJpaTest\` para repositorios — no \`@SpringBootTest\` para todo
208
+ - Usa AssertJ (\`assertThat\`) sobre JUnit assertions — más legible
209
+ - Nombra los tests: \`{metodo}_{condicion}_{resultado}\``,
210
+ },
211
+ {
212
+ name: 'spring-jpa',
213
+ version: '1.0.0',
214
+ description: 'JPA entities, Spring Data repositories and transaction management',
215
+ scope: 'pack',
216
+ pack: '@bk-java',
217
+ language: ['java'],
218
+ triggers: [
219
+ 'jpa', 'hibernate', 'entity', 'entidad', 'repository', 'repositorio',
220
+ 'transaction', 'transaccion', 'query', 'jpql', 'migration', 'migracion',
221
+ 'flyway', 'liquibase', 'database', 'base de datos',
222
+ ],
223
+ systemPromptAddition: `## Spring Data JPA
224
+
225
+ ### Entity
226
+ \`\`\`java
227
+ @Entity
228
+ @Table(name = "users")
229
+ @Getter
230
+ @NoArgsConstructor(access = AccessLevel.PROTECTED) // JPA requiere constructor sin args
231
+ public class User {
232
+ @Id
233
+ @GeneratedValue(strategy = GenerationType.UUID)
234
+ private UUID id;
235
+
236
+ @Column(nullable = false, unique = true)
237
+ private String email;
238
+
239
+ @CreationTimestamp
240
+ private Instant createdAt;
241
+
242
+ public User(String email) { // constructor de dominio
243
+ this.email = email;
244
+ }
245
+ }
246
+ \`\`\`
247
+
248
+ ### Repository
249
+ \`\`\`java
250
+ public interface UserRepository extends JpaRepository<User, UUID> {
251
+ Optional<User> findByEmail(String email);
252
+
253
+ @Query("SELECT u FROM User u WHERE u.createdAt >= :since")
254
+ List<User> findRecentUsers(@Param("since") Instant since);
255
+
256
+ // Para updates masivos usa @Modifying + @Transactional
257
+ @Modifying
258
+ @Transactional
259
+ @Query("UPDATE User u SET u.email = :email WHERE u.id = :id")
260
+ int updateEmail(@Param("id") UUID id, @Param("email") String email);
261
+ }
262
+ \`\`\`
263
+
264
+ ### Reglas
265
+ - Usa \`@NoArgsConstructor(access = PROTECTED)\` — JPA lo necesita pero no expongas el constructor vacío
266
+ - No uses \`@Setter\` en entidades — modifica el estado con métodos de dominio
267
+ - Nunca serialices entidades JPA a JSON directamente — usa DTOs (records)
268
+ - Migraciones con Flyway o Liquibase — nunca \`spring.jpa.hibernate.ddl-auto=update\` en producción
269
+ - Fetch LAZY por defecto para colecciones (\`@OneToMany\`)`,
270
+ },
271
+ ];
272
+ //# sourceMappingURL=java-pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"java-pack.js","sourceRoot":"","sources":["../../../src/skills/builtins/java-pack.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACU,QAAA,gBAAgB,GAAY;IACrC;QACI,IAAI,EAAE,6BAA6B;QACnC,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,yEAAyE;QACtF,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,QAAQ,EAAE;YACN,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY;YAC5E,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW;YACxE,UAAU,EAAE,UAAU,EAAE,UAAU;SACrC;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wDA6D0B;KACnD;IACD;QACI,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,+EAA+E;QAC5F,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,QAAQ,EAAE;YACN,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB;YACtE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK;SAC7E;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DA+C8B;KACvD;IACD;QACI,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,uDAAuD;QACpE,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,QAAQ,EAAE;YACN,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ;YAChE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW;SACzE;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAsD2B;KACpD;IACD;QACI,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,mEAAmE;QAChF,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,QAAQ,EAAE;YACN,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa;YACpE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;YACvE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe;SACrD;QACD,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2DA8C6B;KACtD;CACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Skill } from '@backendkit-labs/agent-core';
2
+ /**
3
+ * Kotlin / Android skill pack (@bk-kotlin).
4
+ * Activated for projects with build.gradle containing kotlin plugin,
5
+ * detected via 'kotlin' stack (same indicator as java but differentiated
6
+ * by triggers and stack field).
7
+ */
8
+ export declare const KOTLIN_PACK_SKILLS: Skill[];
9
+ //# sourceMappingURL=kotlin-pack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kotlin-pack.d.ts","sourceRoot":"","sources":["../../../src/skills/builtins/kotlin-pack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,EAyRrC,CAAC"}