claude-code-arcane 1.2.0 → 1.3.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/CHANGELOG.md +9 -0
- package/README.md +2 -0
- package/agents/engineering/dotnet-engineer.md +78 -0
- package/docs/SKILLS-CATALOG.md +26 -3
- package/package.json +1 -1
- package/profiles/backend-dotnet.yaml +54 -0
- package/profiles/job-hunt.yaml +35 -0
- package/profiles/unity-design.yaml +1 -0
- package/profiles/unity-dev.yaml +1 -0
- package/rules/dotnet-code.md +64 -0
- package/skills/cold-outreach/SKILL.md +65 -0
- package/skills/cold-outreach/references/recruiter-playbook.md +65 -0
- package/skills/cover-letter/SKILL.md +66 -0
- package/skills/cv-ats-export/SKILL.md +64 -0
- package/skills/cv-ats-export/scripts/cv_export.py +306 -0
- package/skills/cv-tailor/SKILL.md +70 -0
- package/skills/cv-tailor/references/ats-keywords.md +46 -0
- package/skills/dotnet-architecture/SKILL.md +66 -0
- package/skills/dotnet-architecture/references/anti-patterns.md +12 -0
- package/skills/dotnet-architecture/references/checklist.md +19 -0
- package/skills/dotnet-architecture/references/patterns.md +118 -0
- package/skills/dotnet-architecture/references/project-structure.md +78 -0
- package/skills/dotnet-best-practices/SKILL.md +76 -0
- package/skills/dotnet-best-practices/references/api-design.md +75 -0
- package/skills/dotnet-best-practices/references/architecture.md +62 -0
- package/skills/dotnet-best-practices/references/async.md +62 -0
- package/skills/dotnet-best-practices/references/database.md +69 -0
- package/skills/dotnet-best-practices/references/dependency-injection.md +73 -0
- package/skills/dotnet-best-practices/references/devops.md +76 -0
- package/skills/dotnet-best-practices/references/error-handling.md +72 -0
- package/skills/dotnet-best-practices/references/performance.md +63 -0
- package/skills/dotnet-best-practices/references/security.md +73 -0
- package/skills/dotnet-best-practices/references/testing.md +76 -0
- package/skills/dotnet-scaffold/SKILL.md +99 -0
- package/skills/install-mcp/SKILL.md +107 -0
- package/skills/install-mcp/references/manual-setup.md +92 -0
- package/skills/interview-prep/SKILL.md +69 -0
- package/skills/interview-prep/references/star-framework.md +42 -0
- package/skills/job-hunt/SKILL.md +92 -0
- package/skills/job-hunt/references/templates/Aplicacion.md +48 -0
- package/skills/job-hunt/references/templates/CV Custom.md +53 -0
- package/skills/job-hunt/references/templates/Contacto.md +30 -0
- package/skills/job-hunt/references/templates/Dashboard.md +45 -0
- package/skills/job-hunt/references/templates/Empresa.md +36 -0
- package/skills/job-hunt/references/templates/Entrevista.md +44 -0
- package/skills/job-hunt/references/templates/Perfil.md +38 -0
- package/skills/job-search/SKILL.md +83 -0
- package/skills/job-search/references/scoring-rubric.md +43 -0
- package/skills/linkedin-optimize/SKILL.md +79 -0
- package/skills/master-profile/SKILL.md +69 -0
- package/skills/network-map/SKILL.md +61 -0
- package/skills/network-map/scripts/network_map.py +109 -0
- package/skills/personal-brand/SKILL.md +54 -0
- package/skills/personal-brand/references/post-pillars.md +66 -0
- package/skills/portfolio-site/SKILL.md +59 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# 6. Performance (HIGH)
|
|
2
|
+
|
|
3
|
+
## 6.1 Output Caching & HybridCache — HIGH
|
|
4
|
+
|
|
5
|
+
Cachear respuestas caras evita recomputar en cada request. `HybridCache` combina cache en memoria (L1) y distribuida (L2) con stampede protection.
|
|
6
|
+
|
|
7
|
+
**Incorrecto:**
|
|
8
|
+
```csharp
|
|
9
|
+
app.MapGet("/stats", async (StatsService s) => await s.ComputeAsync()); // recomputa siempre
|
|
10
|
+
```
|
|
11
|
+
**Correcto:**
|
|
12
|
+
```csharp
|
|
13
|
+
builder.Services.AddHybridCache();
|
|
14
|
+
|
|
15
|
+
app.MapGet("/stats", async (HybridCache cache, StatsService s, CancellationToken ct) =>
|
|
16
|
+
await cache.GetOrCreateAsync("stats", async token => await s.ComputeAsync(token), cancellationToken: ct));
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 6.2 Response Compression — HIGH
|
|
20
|
+
|
|
21
|
+
Comprimir respuestas reduce el ancho de banda y la latencia percibida en payloads JSON grandes.
|
|
22
|
+
|
|
23
|
+
**Correcto:**
|
|
24
|
+
```csharp
|
|
25
|
+
builder.Services.AddResponseCompression(o => o.EnableForHttps = true);
|
|
26
|
+
var app = builder.Build();
|
|
27
|
+
app.UseResponseCompression();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 6.3 Never Block on Async (sync-over-async) — HIGH
|
|
31
|
+
|
|
32
|
+
`.Result` o `.Wait()` bloquean un hilo del thread pool y pueden causar deadlocks y thread starvation bajo carga.
|
|
33
|
+
|
|
34
|
+
**Incorrecto:**
|
|
35
|
+
```csharp
|
|
36
|
+
var user = _repo.GetUserAsync(id).Result; // bloquea el hilo
|
|
37
|
+
```
|
|
38
|
+
**Correcto:**
|
|
39
|
+
```csharp
|
|
40
|
+
var user = await _repo.GetUserAsync(id);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 6.4 DbContext Pooling — MEDIUM-HIGH
|
|
44
|
+
|
|
45
|
+
Reusar instancias de `DbContext` desde un pool reduce las allocations y el costo de setup por request.
|
|
46
|
+
|
|
47
|
+
**Correcto:**
|
|
48
|
+
```csharp
|
|
49
|
+
builder.Services.AddDbContextPool<AppDbContext>(o =>
|
|
50
|
+
o.UseNpgsql(builder.Configuration.GetConnectionString("Default")));
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 6.5 Stream Large Results with IAsyncEnumerable — MEDIUM
|
|
54
|
+
|
|
55
|
+
Devolver `IAsyncEnumerable<T>` transmite filas a medida que llegan en vez de materializar toda la colección en memoria.
|
|
56
|
+
|
|
57
|
+
**Correcto:**
|
|
58
|
+
```csharp
|
|
59
|
+
app.MapGet("/orders", (AppDbContext db) =>
|
|
60
|
+
db.Orders.AsNoTracking().AsAsyncEnumerable()); // streaming, server GC ayuda en cargas altas
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
_Ref: https://learn.microsoft.com/en-us/aspnet/core/performance/caching/hybrid · https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression · https://learn.microsoft.com/en-us/ef/core/performance/advanced-performance-topics_
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# 5. Security (HIGH)
|
|
2
|
+
|
|
3
|
+
## 5.1 Short-Lived JWT + Refresh Tokens — CRITICAL
|
|
4
|
+
|
|
5
|
+
Access tokens cortos (5-15 min) limitan la ventana si se filtra uno; el refresh token (revocable, server-side) renueva sin re-login. Tokens de larga vida no se pueden invalidar.
|
|
6
|
+
|
|
7
|
+
```csharp
|
|
8
|
+
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
9
|
+
.AddJwtBearer(o => o.TokenValidationParameters = new()
|
|
10
|
+
{
|
|
11
|
+
ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true,
|
|
12
|
+
ValidateIssuerSigningKey = true, ClockSkew = TimeSpan.FromSeconds(30)
|
|
13
|
+
});
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## 5.2 Secrets in User-Secrets / Key Vault — CRITICAL
|
|
17
|
+
|
|
18
|
+
Nunca claves ni connection strings en `appsettings.json` (van al repo). En dev `dotnet user-secrets`; en prod Azure Key Vault o variables de entorno.
|
|
19
|
+
|
|
20
|
+
**Incorrecto:**
|
|
21
|
+
```json
|
|
22
|
+
{ "Jwt": { "Key": "super-secret-signing-key" } } // en el repo
|
|
23
|
+
```
|
|
24
|
+
**Correcto:**
|
|
25
|
+
```csharp
|
|
26
|
+
// dotnet user-secrets set "Jwt:Key" "..." (dev)
|
|
27
|
+
builder.Configuration.AddAzureKeyVault(vaultUri, new DefaultAzureCredential()); // prod
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 5.3 Authorize by Policies, Not Manual Role Checks — HIGH
|
|
31
|
+
|
|
32
|
+
Las policies centralizan la regla de autorización; los `if (user.Role == "Admin")` dispersos se desincronizan y se olvidan.
|
|
33
|
+
|
|
34
|
+
**Incorrecto:**
|
|
35
|
+
```csharp
|
|
36
|
+
if (!ctx.User.IsInRole("Admin")) return Results.Forbid(); // lógica esparcida
|
|
37
|
+
```
|
|
38
|
+
**Correcto:**
|
|
39
|
+
```csharp
|
|
40
|
+
builder.Services.AddAuthorizationBuilder()
|
|
41
|
+
.AddPolicy("CanManageOrders", p => p.RequireRole("Admin").RequireClaim("scope", "orders:write"));
|
|
42
|
+
app.MapPost("/orders", Handler).RequireAuthorization("CanManageOrders");
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 5.4 HTTPS, HSTS and Rate Limiting — HIGH
|
|
46
|
+
|
|
47
|
+
Forzar HTTPS + HSTS evita downgrade/MITM. El middleware `RateLimiter` integrado protege de abuso y brute-force.
|
|
48
|
+
|
|
49
|
+
```csharp
|
|
50
|
+
builder.Services.AddRateLimiter(o => o.AddFixedWindowLimiter("api", w =>
|
|
51
|
+
{ w.PermitLimit = 100; w.Window = TimeSpan.FromMinutes(1); }));
|
|
52
|
+
app.UseHsts();
|
|
53
|
+
app.UseHttpsRedirection();
|
|
54
|
+
app.UseRateLimiter();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 5.5 Don't Log Sensitive Data; Validate Input — HIGH
|
|
58
|
+
|
|
59
|
+
Nunca loggear passwords, tokens ni PII. Validar todo input con FluentValidation. Las queries de EF Core son parametrizadas por defecto (no concatenar SQL crudo) y `[ValidateAntiForgeryToken]` donde haya cookies/formularios.
|
|
60
|
+
|
|
61
|
+
```csharp
|
|
62
|
+
public sealed class CreateOrderValidator : AbstractValidator<CreateOrderRequest>
|
|
63
|
+
{
|
|
64
|
+
public CreateOrderValidator()
|
|
65
|
+
{
|
|
66
|
+
RuleFor(x => x.CustomerId).NotEmpty();
|
|
67
|
+
RuleFor(x => x.Items).NotEmpty();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// EF Core parametriza: db.Users.Where(u => u.Email == input) — nunca string-interpolated FromSqlRaw
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
_Ref: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/configure-jwt-bearer-authentication · https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit_
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# 8. Testing (MEDIUM-HIGH)
|
|
2
|
+
|
|
3
|
+
## 8.1 Integration Tests with WebApplicationFactory — HIGH
|
|
4
|
+
|
|
5
|
+
`WebApplicationFactory<T>` levanta la app en memoria con el pipeline real (DI, middleware, routing), probando el comportamiento de verdad y no mocks.
|
|
6
|
+
|
|
7
|
+
**Correcto:**
|
|
8
|
+
```csharp
|
|
9
|
+
public class OrdersApiTests(WebApplicationFactory<Program> factory)
|
|
10
|
+
: IClassFixture<WebApplicationFactory<Program>>
|
|
11
|
+
{
|
|
12
|
+
[Fact]
|
|
13
|
+
public async Task GetOrders_ReturnsOk()
|
|
14
|
+
{
|
|
15
|
+
var client = factory.CreateClient();
|
|
16
|
+
var response = await client.GetAsync("/api/v1/orders");
|
|
17
|
+
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 8.2 Real Postgres via Testcontainers — HIGH
|
|
23
|
+
|
|
24
|
+
El provider in-memory miente sobre el comportamiento relacional (transacciones, constraints, SQL). Testcontainers levanta un Postgres real y desechable.
|
|
25
|
+
|
|
26
|
+
**Incorrecto:**
|
|
27
|
+
```csharp
|
|
28
|
+
options.UseInMemoryDatabase("test"); // no valida FKs, constraints ni SQL real
|
|
29
|
+
```
|
|
30
|
+
**Correcto:**
|
|
31
|
+
```csharp
|
|
32
|
+
var pg = new PostgreSqlBuilder().WithImage("postgres:17").Build();
|
|
33
|
+
await pg.StartAsync();
|
|
34
|
+
options.UseNpgsql(pg.GetConnectionString());
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 8.3 Don't Mock DbContext — MEDIUM-HIGH
|
|
38
|
+
|
|
39
|
+
Mockear `DbContext` o `IQueryable` reimplementa LINQ-to-SQL en LINQ-to-Objects y da falsos verdes. Probar handlers/slices contra una base real.
|
|
40
|
+
|
|
41
|
+
**Incorrecto:**
|
|
42
|
+
```csharp
|
|
43
|
+
var mock = new Mock<AppDbContext>(); // no traduce queries como el provider real
|
|
44
|
+
```
|
|
45
|
+
**Correcto:**
|
|
46
|
+
```csharp
|
|
47
|
+
var handler = new CreateOrderHandler(realDbContext);
|
|
48
|
+
var result = await handler.Handle(command, CancellationToken.None);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 8.4 Arrange-Act-Assert with FluentAssertions — MEDIUM
|
|
52
|
+
|
|
53
|
+
Estructurar cada test en AAA y usar `FluentAssertions` para aserciones legibles y mensajes de error claros.
|
|
54
|
+
|
|
55
|
+
**Correcto:**
|
|
56
|
+
```csharp
|
|
57
|
+
[Fact]
|
|
58
|
+
public void Discount_AppliesPercentage()
|
|
59
|
+
{
|
|
60
|
+
var order = new Order(100m); // Arrange
|
|
61
|
+
order.ApplyDiscount(0.10m); // Act
|
|
62
|
+
order.Total.Should().Be(90m); // Assert
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 8.5 Deterministic Tests — MEDIUM
|
|
67
|
+
|
|
68
|
+
Evitar `DateTime.Now`, GUIDs aleatorios o dependencias de orden: inyectar `TimeProvider` para que los tests sean reproducibles.
|
|
69
|
+
|
|
70
|
+
**Correcto:**
|
|
71
|
+
```csharp
|
|
72
|
+
var time = new FakeTimeProvider(new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero));
|
|
73
|
+
var service = new SubscriptionService(time); // sin reloj real, resultado estable
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
_Ref: https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests · https://learn.microsoft.com/en-us/dotnet/core/testing/ · https://learn.microsoft.com/en-us/dotnet/architecture/microservices/multi-container-microservice-net-applications/test-aspnet-core-services-web-apps_
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dotnet-scaffold
|
|
3
|
+
description: "Scaffold de API ASP.NET Core (.NET 10) production-ready: Vertical Slice o Clean Architecture, Minimal APIs, EF Core + PostgreSQL, JWT + Identity, ProblemDetails, health checks y testing. Usar para iniciar un backend .NET nuevo."
|
|
4
|
+
category: "backend"
|
|
5
|
+
argument-hint: "[project-name]"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash, Write, Edit, Task
|
|
8
|
+
---
|
|
9
|
+
# dotnet-scaffold — ASP.NET Core API Scaffolder
|
|
10
|
+
|
|
11
|
+
## MANDATORY WORKFLOW
|
|
12
|
+
|
|
13
|
+
**Antes de generar cualquier código, completar estos pasos en orden.** Confirmar las decisiones del Step 0 con el usuario antes de escribir archivos (Question → Decision → Approval).
|
|
14
|
+
|
|
15
|
+
### Step 0: Gather Requirements
|
|
16
|
+
1. **Nombre del servicio** (PascalCase para la solución, ej. `OrdersApi`)
|
|
17
|
+
2. **Arquitectura:** Vertical Slice (default) / Clean Architecture — ver skill `dotnet-architecture` para elegir
|
|
18
|
+
3. **Transport:** Web API REST con Minimal APIs (default) / Controllers / gRPC
|
|
19
|
+
4. **ORM:** EF Core (default) / Dapper
|
|
20
|
+
5. **DB:** PostgreSQL (default) / SQL Server
|
|
21
|
+
6. **Auth:** JWT + ASP.NET Identity (default) / OAuth / ninguna
|
|
22
|
+
7. **Deploy:** Docker (default) / Azure App Service
|
|
23
|
+
|
|
24
|
+
> Si el dominio es CRUD/simple → **Vertical Slice**. Si es complejo y long-lived con varios devs → **Clean Architecture**.
|
|
25
|
+
|
|
26
|
+
### Step 1: Crear base
|
|
27
|
+
```bash
|
|
28
|
+
dotnet new sln -n <Name>
|
|
29
|
+
dotnet new webapi -n <Name>.Api # Minimal APIs (default en .NET 8+); para Controllers: --use-controllers
|
|
30
|
+
dotnet sln add <Name>.Api
|
|
31
|
+
dotnet new xunit -n <Name>.Tests && dotnet sln add <Name>.Tests
|
|
32
|
+
cd <Name>.Api
|
|
33
|
+
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
|
|
34
|
+
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
|
|
35
|
+
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
|
|
36
|
+
dotnet add package FluentValidation.DependencyInjectionExtensions # core + DI; FluentValidation.AspNetCore (auto-validation) está deprecado
|
|
37
|
+
dotnet add package Serilog.AspNetCore
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Step 2: Estructura
|
|
41
|
+
|
|
42
|
+
**Vertical Slice (default)** — un folder por feature/use-case:
|
|
43
|
+
```
|
|
44
|
+
src/
|
|
45
|
+
Features/
|
|
46
|
+
Orders/ { CreateOrder.cs, GetOrder.cs, OrderEndpoints.cs } # request+handler+validator+endpoint por slice
|
|
47
|
+
Users/ { ... }
|
|
48
|
+
Infrastructure/ { AppDbContext.cs, Migrations/ }
|
|
49
|
+
Common/ { Behaviors/, Results/, ProblemDetails/ }
|
|
50
|
+
Program.cs
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Clean Architecture** — proyectos por capa (deps apuntan hacia adentro):
|
|
54
|
+
```
|
|
55
|
+
<Name>.Domain/ # entities, value objects — cero deps externas
|
|
56
|
+
<Name>.Application/ # use cases, interfaces (IAppDbContext), DTOs
|
|
57
|
+
<Name>.Infrastructure/ # EF Core, Identity, implementaciones
|
|
58
|
+
<Name>.Api/ # endpoints/controllers, DI, Program.cs
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Step 3: Defaults no negociables (`Program.cs` / `.csproj`)
|
|
62
|
+
- `<Nullable>enable</Nullable>` + `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` en el `.csproj`
|
|
63
|
+
- **Async end-to-end**: handlers `async Task<>`, `CancellationToken` propagado a EF Core y HTTP; nunca `.Result`/`.Wait()`
|
|
64
|
+
- **DI por constructor** (primary constructors); registrar servicios con scope correcto (`AddScoped` para DbContext/handlers)
|
|
65
|
+
- **Validación**: FluentValidation por slice, invocada manualmente (pipeline behavior MediatR o endpoint filter — no auto-validation) → responder `ValidationProblemDetails` (RFC 7807)
|
|
66
|
+
- **Errores**: `AddProblemDetails()` + exception handler global → `ProblemDetails` consistente, sin filtrar stack traces
|
|
67
|
+
- **EF Core**: migraciones versionadas (`dotnet ef migrations add`), **nunca** `EnsureCreated()` en prod; `DbContext` como Unit of Work (sin repos genéricos salvo necesidad)
|
|
68
|
+
- **Auth**: JWT de vida corta + refresh, secretos en `user-secrets`/secret manager, authorization por policies declarativas
|
|
69
|
+
- **Observabilidad**: Serilog structured logging (JSON) + health checks (`AddHealthChecks`) + OpenTelemetry opcional
|
|
70
|
+
- **Graceful shutdown**: respetar `IHostApplicationLifetime` / `CancellationToken` del host
|
|
71
|
+
|
|
72
|
+
### Step 4: Agregar piezas (invocar skills relacionadas)
|
|
73
|
+
- `dotnet-architecture` — estructura de slices/capas en detalle
|
|
74
|
+
- `database` / `data-migrations` — modelado EF Core + migraciones
|
|
75
|
+
- `jwt-strategy` / `auth-strategy` / `rbac-abac` — auth y authorization
|
|
76
|
+
- `api-design` / `api-versioning` / `api-docs` — contrato REST + OpenAPI
|
|
77
|
+
- `testing` / `contract-testing` — xUnit + Testcontainers (Postgres real en tests)
|
|
78
|
+
|
|
79
|
+
### Step 5: Verificar
|
|
80
|
+
`dotnet build` + `dotnet test`. Revisar contra la rule `dotnet-code` y el skill `dotnet-best-practices`. Build + tests verdes → scaffold **READY**.
|
|
81
|
+
|
|
82
|
+
## Stack Defaults
|
|
83
|
+
|
|
84
|
+
| Componente | Default |
|
|
85
|
+
|------------|---------|
|
|
86
|
+
| Runtime | .NET 10 LTS (C# 14) |
|
|
87
|
+
| Framework | ASP.NET Core — Minimal APIs |
|
|
88
|
+
| Arquitectura | Vertical Slice (Clean opcional) |
|
|
89
|
+
| ORM | EF Core 10 |
|
|
90
|
+
| DB | PostgreSQL (Npgsql) |
|
|
91
|
+
| Auth | JWT + ASP.NET Identity |
|
|
92
|
+
| Validación | FluentValidation → ProblemDetails |
|
|
93
|
+
| Logging | Serilog (JSON) |
|
|
94
|
+
| Testing | xUnit + Testcontainers |
|
|
95
|
+
| Deploy | Docker |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
_Inspirado en [dotnet/skills](https://github.com/dotnet/skills) (oficial Microsoft), [github/awesome-copilot](https://github.com/github/awesome-copilot) (dotnet-best-practices) y los templates [ardalis/CleanArchitecture](https://github.com/ardalis/CleanArchitecture) y [nadirbad/VerticalSliceArchitecture](https://github.com/nadirbad/VerticalSliceArchitecture). Adaptado al formato Arcane._
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: install-mcp
|
|
3
|
+
description: "Instala y registra el MCP de Unity (CoplayDev MCP for Unity) en un proyecto Unity + Claude Code: agrega el package UPM, registra el server MCP y verifica la conexion. Usar para: instalar mcp unity, conectar Claude con Unity, setup MCP Unity."
|
|
4
|
+
category: "gamedev"
|
|
5
|
+
argument-hint: "[--secondary] [project-path]"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Bash, Write, Edit
|
|
8
|
+
---
|
|
9
|
+
# install-mcp — Unity MCP Setup
|
|
10
|
+
|
|
11
|
+
Instala el package MCP del lado Unity y registra el server MCP en Claude Code, replicando el setup usado en los proyectos de tesis (TesisUade).
|
|
12
|
+
|
|
13
|
+
- **Package primario:** `com.coplaydev.unity-mcp` (CoplayDev "MCP for Unity"). Server Python vía `uv`/`uvx`, transport HTTP en `127.0.0.1:8080`. El server se levanta y auto-configura desde Unity en `Window → MCP for Unity`.
|
|
14
|
+
- **Package secundario (opcional, flag `--secondary`):** `com.gamelovers.mcp-unity` (CoderGamester). Server Node.
|
|
15
|
+
|
|
16
|
+
> El flujo de Unity (`Window → MCP for Unity`) requiere la GUI del Editor — Claude no puede manejarla. La skill automatiza lo que sí puede (editar `manifest.json`, registrar el cliente MCP, verificar) y **guía** el paso del Editor.
|
|
17
|
+
|
|
18
|
+
## Input
|
|
19
|
+
|
|
20
|
+
- `project-path` (opcional): raíz del proyecto Unity. Default: directorio actual.
|
|
21
|
+
- `--secondary` (opcional): además del primario, instala el package CoderGamester.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Workflow
|
|
26
|
+
|
|
27
|
+
### 1. Detectar proyecto Unity
|
|
28
|
+
|
|
29
|
+
Desde `project-path` (o cwd), confirmar que existen:
|
|
30
|
+
- `Packages/manifest.json`
|
|
31
|
+
- `ProjectSettings/ProjectVersion.txt`
|
|
32
|
+
|
|
33
|
+
Si falta alguno, **abortar** con: "No parece un proyecto Unity (falta Packages/manifest.json o ProjectSettings/ProjectVersion.txt). Pasá la ruta del proyecto con `/install-mcp <project-path>`."
|
|
34
|
+
|
|
35
|
+
### 2. Verificar prerrequisitos
|
|
36
|
+
|
|
37
|
+
- `uv --version` y `uvx --version` (server del primario). Si falta `uv`, **no abortar**: avisar y dar el comando de install y seguir editando el manifest:
|
|
38
|
+
- Windows: `winget install astral-sh.uv`
|
|
39
|
+
- alternativa: `pipx install uv`
|
|
40
|
+
- Solo con `--secondary`: `node --version`. Si falta, avisar (el server CoderGamester no podrá correr).
|
|
41
|
+
|
|
42
|
+
### 3. Agregar el package UPM (lado Unity)
|
|
43
|
+
|
|
44
|
+
Leer `Packages/manifest.json`. Dentro de `"dependencies"`, agregar **solo si la key no existe** (idempotente — nunca duplicar):
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
"com.coplaydev.unity-mcp": "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Con `--secondary`, agregar también:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
"com.gamelovers.mcp-unity": "https://github.com/CoderGamester/mcp-unity.git"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Usar `Edit` puntual sobre el bloque `dependencies` preservando el JSON válido (indentación, comas). Si la key ya estaba, reportar "ya presente, sin cambios".
|
|
57
|
+
|
|
58
|
+
> **Antes de escribir**, mostrar el diff propuesto sobre `manifest.json` (y el `.mcp.json` del paso 4B si aplica) y pedir aprobación al usuario. No editar sin confirmación.
|
|
59
|
+
|
|
60
|
+
### 4. Registrar el server MCP en Claude Code
|
|
61
|
+
|
|
62
|
+
Dos caminos, en orden de preferencia:
|
|
63
|
+
|
|
64
|
+
**A. Recomendado (auto-config desde Unity).** Instruir al usuario:
|
|
65
|
+
1. Abrir el proyecto en Unity (Unity importará el package nuevo).
|
|
66
|
+
2. `Window → MCP for Unity`.
|
|
67
|
+
3. En esa ventana, usar el botón de auto-configuración para **Claude Code** — instala el server `uv` y registra el cliente MCP automáticamente.
|
|
68
|
+
|
|
69
|
+
**B. Fallback manual.** Si el usuario no puede usar el Editor ahora, registrar el transport HTTP que usa CoplayDev:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
claude mcp add --transport http unity-mcp http://127.0.0.1:8080
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
(equivalente: escribir un `.mcp.json` de proyecto con
|
|
76
|
+
`{"mcpServers":{"unity-mcp":{"type":"http","url":"http://127.0.0.1:8080"}}}`).
|
|
77
|
+
|
|
78
|
+
> El server solo responde cuando Unity está abierto con `MCP for Unity` activo. Registrar el cliente no levanta el server.
|
|
79
|
+
|
|
80
|
+
### 5. Verificar
|
|
81
|
+
|
|
82
|
+
Correr:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
claude mcp list
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Reportar si `unity-mcp` aparece **conectado**. Seguir la guía de TesisUade: **si NO está conectado, avisar explícitamente** y aclarar que las operaciones de engine (scenes, SOs, prefabs, UI wiring) NO se aplicaron — no asumir éxito.
|
|
89
|
+
|
|
90
|
+
### 6. Resumen
|
|
91
|
+
|
|
92
|
+
Reportar:
|
|
93
|
+
- Qué keys se agregaron a `manifest.json` (o si ya estaban).
|
|
94
|
+
- Estado del registro MCP (auto-config pendiente en Unity vs. fallback aplicado).
|
|
95
|
+
- Resultado de `claude mcp list`.
|
|
96
|
+
- Próximo paso manual: abrir Unity → `Window → MCP for Unity`.
|
|
97
|
+
|
|
98
|
+
**Verdict:**
|
|
99
|
+
- **READY** — package en `manifest.json` + cliente registrado + `unity-mcp` conectado en `claude mcp list`.
|
|
100
|
+
- **PENDING** — package y cliente listos, pero falta abrir Unity (`Window → MCP for Unity`) para que el server conecte. Avisar que las operaciones de engine aún NO están disponibles.
|
|
101
|
+
- **BLOCKED** — falta un prerrequisito (`uv` ausente) o no es un proyecto Unity válido. Indicar el fix.
|
|
102
|
+
|
|
103
|
+
Tras conectar, seguir con `/unity-game-architecture` o `/scaffold-unity` para trabajar el proyecto.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
> → Read references/manual-setup.md for [pasos detallados del flujo Window → MCP for Unity, troubleshooting (uv no encontrado, puerto 8080 ocupado, MCP no conecta) y la variante secundaria CoderGamester]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Manual setup — Unity MCP
|
|
2
|
+
|
|
3
|
+
Referencia detallada para el flujo manual y troubleshooting de `/install-mcp`.
|
|
4
|
+
|
|
5
|
+
## Primario: CoplayDev "MCP for Unity" (`com.coplaydev.unity-mcp`)
|
|
6
|
+
|
|
7
|
+
### Package UPM
|
|
8
|
+
|
|
9
|
+
En `Packages/manifest.json`, dentro de `dependencies`:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
"com.coplaydev.unity-mcp": "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Al abrir el proyecto, Unity descarga e importa el package desde el git URL.
|
|
16
|
+
|
|
17
|
+
### Levantar y registrar el server (desde Unity)
|
|
18
|
+
|
|
19
|
+
1. Abrir el proyecto en Unity.
|
|
20
|
+
2. `Window → MCP for Unity` abre el panel del package.
|
|
21
|
+
3. En el panel:
|
|
22
|
+
- El package instala/usa el server Python vía `uv`/`uvx` (paquete `mcp-for-unity`), transport HTTP en `127.0.0.1:8080`.
|
|
23
|
+
- Usar el botón de auto-config para el cliente **Claude Code** — escribe la config del cliente MCP y deja el server listo.
|
|
24
|
+
4. Dejar Unity abierto: el server MCP solo responde mientras el Editor está corriendo con el panel activo.
|
|
25
|
+
|
|
26
|
+
### Registro manual del cliente (sin GUI)
|
|
27
|
+
|
|
28
|
+
Si no se puede usar el botón de auto-config:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
claude mcp add --transport http unity-mcp http://127.0.0.1:8080
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
O escribir un `.mcp.json` en la raíz del proyecto:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"unity-mcp": {
|
|
40
|
+
"type": "http",
|
|
41
|
+
"url": "http://127.0.0.1:8080"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Verificar
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
claude mcp list
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`unity-mcp` debe figurar conectado. Si no, ver troubleshooting.
|
|
54
|
+
|
|
55
|
+
## Troubleshooting
|
|
56
|
+
|
|
57
|
+
| Síntoma | Causa probable | Fix |
|
|
58
|
+
|---------|----------------|-----|
|
|
59
|
+
| `uv: command not found` | `uv` no instalado / no en PATH | `winget install astral-sh.uv` (o `pipx install uv`), reabrir terminal |
|
|
60
|
+
| `claude mcp list` no muestra `unity-mcp` | Cliente no registrado | Re-correr el paso 4 (auto-config o `claude mcp add`) |
|
|
61
|
+
| `unity-mcp` aparece pero **no conecta** | Unity cerrado o panel inactivo | Abrir Unity y `Window → MCP for Unity` |
|
|
62
|
+
| Puerto `8080` ocupado | Otro proceso usa 8080 | Cambiar el puerto en el panel de MCP for Unity y ajustar la URL en el registro del cliente |
|
|
63
|
+
| Operaciones de engine no se aplican | MCP desconectado | No asumir éxito: verificar conexión antes de operar; avisar al usuario |
|
|
64
|
+
|
|
65
|
+
## Secundario (opcional): CoderGamester `mcp-unity` (`com.gamelovers.mcp-unity`)
|
|
66
|
+
|
|
67
|
+
Server Node. Instalar con el flag `--secondary`.
|
|
68
|
+
|
|
69
|
+
### Package UPM
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
"com.gamelovers.mcp-unity": "https://github.com/CoderGamester/mcp-unity.git"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Server
|
|
76
|
+
|
|
77
|
+
Requiere `node` en PATH. El package incluye un server Node en `Server~/build/index.js` dentro del package cache (`Library/PackageCache/com.gamelovers.mcp-unity@.../Server~`). El registro del cliente apunta a ese `index.js`:
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"mcp-unity": {
|
|
83
|
+
"command": "node",
|
|
84
|
+
"args": ["<ruta absoluta a Server~/build/index.js>"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
En TesisUade esta ruta la genera un editor tool propio (`Tools → Update MCP Unity Route`). Fuera de ese proyecto, ubicar el `index.js` en el `PackageCache` y registrar la ruta a mano.
|
|
91
|
+
|
|
92
|
+
> El primario (CoplayDev) es el oficial del set unity-dev. El secundario se mantiene solo por compatibilidad con proyectos que ya lo declaran.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interview-prep
|
|
3
|
+
description: "Prepare for a job interview: company research, likely question bank by role, STAR answers built from your real experience, smart questions to ask, and red flags to watch for. Triggers: preparar entrevista, interview prep, preguntas de entrevista, respuestas STAR, que preguntar en una entrevista, mock interview, red flags entrevista."
|
|
4
|
+
argument-hint: "[application-note | company + role + round]"
|
|
5
|
+
category: "career"
|
|
6
|
+
user-invocable: true
|
|
7
|
+
allowed-tools: Read, Glob, Grep, Write, Edit, WebFetch
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Interview Prep — Preparación de entrevista
|
|
11
|
+
|
|
12
|
+
Preparás al usuario para una entrevista concreta: research de la empresa, banco de preguntas probable según rol y ronda, respuestas **STAR** construidas desde su experiencia real, preguntas inteligentes para hacer, y red flags a detectar. El output queda en una nota de `06-Entrevistas/`.
|
|
13
|
+
|
|
14
|
+
## Inputs
|
|
15
|
+
|
|
16
|
+
- **Aplicación / empresa / rol** (`03-Aplicaciones/`, `04-Empresas/`) y la **ronda** (recruiter screen, técnica, system design, hiring manager, cultural, final).
|
|
17
|
+
- **Perfil maestro** (`01-Perfiles/`) — de ahí salen las historias para las respuestas STAR.
|
|
18
|
+
- **Entrevistadores** si se conocen (research de background ayuda).
|
|
19
|
+
|
|
20
|
+
## Qué producís
|
|
21
|
+
|
|
22
|
+
### 1. Research de la empresa
|
|
23
|
+
- Qué hacen, producto, modelo de negocio, etapa, tamaño.
|
|
24
|
+
- Cultura y valores (de su sitio, blog, reviews).
|
|
25
|
+
- Noticias recientes / financiación / lanzamientos.
|
|
26
|
+
- Stack técnico conocido.
|
|
27
|
+
- Cómo conectar tu perfil con su contexto.
|
|
28
|
+
|
|
29
|
+
### 2. Banco de preguntas por ronda
|
|
30
|
+
- **Recruiter screen:** motivación, expectativas salariales, disponibilidad, "contame de vos".
|
|
31
|
+
- **Técnica:** según stack del JD — fundamentos, problemas, debugging, code review.
|
|
32
|
+
- **System design** (si aplica): patrones, trade-offs, escala.
|
|
33
|
+
- **Hiring manager / comportamiento:** liderazgo, conflicto, fracaso, impacto.
|
|
34
|
+
- **Cultural:** valores, formas de trabajo, por qué esta empresa.
|
|
35
|
+
- Marcar las **3–5 más probables** para este rol específico.
|
|
36
|
+
|
|
37
|
+
### 3. Respuestas STAR
|
|
38
|
+
- Construir respuestas con el método **STAR** (Situación, Tarea, Acción, Resultado) usando logros reales del perfil maestro.
|
|
39
|
+
- Cada respuesta: concreta, con métrica, 60–90 segundos hablada.
|
|
40
|
+
- Ver `references/star-framework.md`.
|
|
41
|
+
|
|
42
|
+
### 4. Preguntas para hacer
|
|
43
|
+
- 5–7 preguntas inteligentes que demuestran research y filtran si la empresa te conviene (equipo, expectativas de los primeros 90 días, cómo miden éxito, deuda técnica, proceso).
|
|
44
|
+
|
|
45
|
+
### 5. Red flags a detectar
|
|
46
|
+
- Señales de mala empresa/equipo durante la entrevista (proceso caótico, evasión sobre cultura/turnover, expectativas irreales, falta de claridad de rol, hostilidad).
|
|
47
|
+
- Qué preguntar para sacarlas a la luz.
|
|
48
|
+
|
|
49
|
+
## Salario / negociación (si la ronda lo toca)
|
|
50
|
+
|
|
51
|
+
- No dar número primero si se puede evitar; preguntar rango.
|
|
52
|
+
- Anclar en research de mercado + tu valor (logros).
|
|
53
|
+
- Tener un rango (mínimo aceptable / objetivo / ambicioso) listo.
|
|
54
|
+
|
|
55
|
+
## Proceso
|
|
56
|
+
|
|
57
|
+
1. Leer aplicación + empresa + perfil. WebFetch del sitio/notas de la empresa.
|
|
58
|
+
2. Crear nota en `06-Entrevistas/` con el template `Entrevista`.
|
|
59
|
+
3. Llenar research, banco de preguntas (marcando las top), STAR de las 3–5 historias clave, preguntas a hacer, red flags.
|
|
60
|
+
4. Ofrecer un **mock**: vos hacés de entrevistador y das feedback sobre las respuestas.
|
|
61
|
+
5. Post-entrevista: ayudar a registrar feedback y definir próximo paso / follow-up (con `/cold-outreach`).
|
|
62
|
+
|
|
63
|
+
## Idioma
|
|
64
|
+
|
|
65
|
+
En el idioma de la entrevista. Preparar respuestas en inglés si el rol es internacional, aunque la prep se converse en español.
|
|
66
|
+
|
|
67
|
+
## Handoff
|
|
68
|
+
|
|
69
|
+
Pedí aprobación (approval) antes de escribir la nota en `06-Entrevistas/`. Cuando la prep está READY, ofrecé un mock; post-entrevista, seguí con `/cold-outreach` para el follow-up.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# STAR Framework — Respuestas de comportamiento
|
|
2
|
+
|
|
3
|
+
STAR estructura respuestas a preguntas de comportamiento ("contame de una vez que…") para que sean concretas, completas y memorables. La mayoría de los candidatos divaga; STAR te da una historia con resultado.
|
|
4
|
+
|
|
5
|
+
## Las 4 partes
|
|
6
|
+
|
|
7
|
+
- **S — Situación:** el contexto, breve. Dónde, cuándo, qué estaba pasando. (1–2 oraciones)
|
|
8
|
+
- **T — Tarea:** tu responsabilidad / el problema a resolver. (1 oración)
|
|
9
|
+
- **A — Acción:** qué hiciste *vos* (no "el equipo"). El grueso de la respuesta. Decisiones concretas. (2–4 oraciones)
|
|
10
|
+
- **R — Resultado:** el impacto, **con número** siempre que se pueda. Qué aprendiste. (1–2 oraciones)
|
|
11
|
+
|
|
12
|
+
Objetivo: 60–90 segundos hablado. Ni telegrama, ni monólogo de 5 minutos.
|
|
13
|
+
|
|
14
|
+
## Ejemplo
|
|
15
|
+
|
|
16
|
+
> **Pregunta:** "Contame de una vez que mejoraste el rendimiento de un sistema."
|
|
17
|
+
>
|
|
18
|
+
> **S:** En Acme nuestro servicio de matchmaking tenía picos de latencia que cortaban partidas.
|
|
19
|
+
> **T:** Como backend lead, me tocó bajar la latencia sin agregar infra.
|
|
20
|
+
> **A:** Perfilé el hot path, encontré queries N+1 y serialización redundante; introduje caching por sesión y batch de writes, y agregué métricas para validar.
|
|
21
|
+
> **R:** Latencia -25% y estabilidad del server +40%; duplicamos jugadores concurrentes sin sumar costos. Aprendí a medir antes de optimizar.
|
|
22
|
+
|
|
23
|
+
## Banco de historias (preparar 5–6)
|
|
24
|
+
|
|
25
|
+
Construí 5–6 historias STAR reutilizables desde el perfil maestro, cubriendo:
|
|
26
|
+
|
|
27
|
+
1. **Logro/impacto** del que estés orgulloso (con métrica).
|
|
28
|
+
2. **Problema técnico difícil** que resolviste.
|
|
29
|
+
3. **Conflicto / desacuerdo** con un compañero o stakeholder.
|
|
30
|
+
4. **Fracaso / error** y qué aprendiste (mostrá ownership, no excusas).
|
|
31
|
+
5. **Liderazgo / iniciativa** (lideraste algo, mentoreaste, empujaste un cambio).
|
|
32
|
+
6. **Ambigüedad / cambio de prioridades** que manejaste.
|
|
33
|
+
|
|
34
|
+
La misma historia puede servir para varias preguntas — lo que cambia es qué parte enfatizás.
|
|
35
|
+
|
|
36
|
+
## Errores comunes
|
|
37
|
+
|
|
38
|
+
- Quedarse en "nosotros" — la entrevista evalúa *tu* aporte. Decí "yo".
|
|
39
|
+
- Saltearse el Resultado, o un resultado sin número.
|
|
40
|
+
- Demasiada Situación, poca Acción.
|
|
41
|
+
- Historias vagas/inventadas que no aguantan repreguntas.
|
|
42
|
+
- No tener la historia de fracaso preparada (la piden casi siempre).
|