@qubiit/lmagent 2.5.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 (155) hide show
  1. package/.editorconfig +18 -0
  2. package/AGENTS.md +169 -0
  3. package/CLAUDE.md +122 -0
  4. package/CONTRIBUTING.md +90 -0
  5. package/LICENSE +21 -0
  6. package/README.md +195 -0
  7. package/config/commands.yaml +194 -0
  8. package/config/levels.yaml +135 -0
  9. package/config/models.yaml +192 -0
  10. package/config/settings.yaml +405 -0
  11. package/config/tools-extended.yaml +534 -0
  12. package/config/tools.yaml +437 -0
  13. package/docs/assets/logo.png +0 -0
  14. package/docs/commands.md +132 -0
  15. package/docs/customization-guide.md +445 -0
  16. package/docs/getting-started.md +154 -0
  17. package/docs/how-to-start.md +242 -0
  18. package/docs/navigation-index.md +227 -0
  19. package/docs/usage-guide.md +113 -0
  20. package/install.js +1044 -0
  21. package/package.json +35 -0
  22. package/pyproject.toml +182 -0
  23. package/rules/_bootstrap.md +138 -0
  24. package/rules/agents-ia.md +607 -0
  25. package/rules/api-design.md +337 -0
  26. package/rules/automations-n8n.md +646 -0
  27. package/rules/code-style.md +570 -0
  28. package/rules/documentation.md +98 -0
  29. package/rules/security.md +316 -0
  30. package/rules/stack.md +395 -0
  31. package/rules/testing.md +326 -0
  32. package/rules/workflow.md +353 -0
  33. package/scripts/create_skill.js +300 -0
  34. package/scripts/validate_skills.js +283 -0
  35. package/skills/ai-agent-engineer/SKILL.md +394 -0
  36. package/skills/ai-agent-engineer/references/agent-patterns.md +149 -0
  37. package/skills/api-designer/SKILL.md +429 -0
  38. package/skills/api-designer/references/api-standards.md +13 -0
  39. package/skills/architect/SKILL.md +285 -0
  40. package/skills/architect/references/c4-model.md +133 -0
  41. package/skills/automation-engineer/SKILL.md +352 -0
  42. package/skills/automation-engineer/references/n8n-patterns.md +127 -0
  43. package/skills/backend-engineer/SKILL.md +261 -0
  44. package/skills/backend-engineer/assets/fastapi-project-structure.yaml +74 -0
  45. package/skills/backend-engineer/references/debugging-guide.md +174 -0
  46. package/skills/backend-engineer/references/design-patterns.md +208 -0
  47. package/skills/backend-engineer/scripts/scaffold_backend.py +313 -0
  48. package/skills/bmad-methodology/SKILL.md +202 -0
  49. package/skills/bmad-methodology/references/scale-adaptive-levels.md +141 -0
  50. package/skills/browser-agent/SKILL.md +502 -0
  51. package/skills/browser-agent/scripts/playwright_setup.ts +16 -0
  52. package/skills/code-reviewer/SKILL.md +306 -0
  53. package/skills/code-reviewer/references/code-review-checklist.md +16 -0
  54. package/skills/data-engineer/SKILL.md +474 -0
  55. package/skills/data-engineer/assets/pg-monitoring-queries.sql +154 -0
  56. package/skills/data-engineer/references/index-strategy.md +128 -0
  57. package/skills/data-engineer/scripts/backup_postgres.py +221 -0
  58. package/skills/devops-engineer/SKILL.md +547 -0
  59. package/skills/devops-engineer/references/ci-cd-patterns.md +265 -0
  60. package/skills/devops-engineer/scripts/docker_healthcheck.py +125 -0
  61. package/skills/document-generator/SKILL.md +746 -0
  62. package/skills/document-generator/references/pdf-generation.md +22 -0
  63. package/skills/frontend-engineer/SKILL.md +532 -0
  64. package/skills/frontend-engineer/references/accessibility-guide.md +146 -0
  65. package/skills/frontend-engineer/scripts/audit_bundle.py +144 -0
  66. package/skills/git-workflow/SKILL.md +374 -0
  67. package/skills/git-workflow/references/git-flow.md +25 -0
  68. package/skills/mcp-builder/SKILL.md +471 -0
  69. package/skills/mcp-builder/references/mcp-server-guide.md +23 -0
  70. package/skills/mobile-engineer/SKILL.md +502 -0
  71. package/skills/mobile-engineer/references/platform-guidelines.md +160 -0
  72. package/skills/orchestrator/SKILL.md +246 -0
  73. package/skills/orchestrator/references/methodology-routing.md +117 -0
  74. package/skills/orchestrator/references/persona-mapping.md +85 -0
  75. package/skills/orchestrator/references/routing-logic.md +110 -0
  76. package/skills/performance-engineer/SKILL.md +549 -0
  77. package/skills/performance-engineer/references/caching-patterns.md +181 -0
  78. package/skills/performance-engineer/scripts/profile_endpoint.py +170 -0
  79. package/skills/product-manager/SKILL.md +488 -0
  80. package/skills/product-manager/references/prioritization-frameworks.md +126 -0
  81. package/skills/prompt-engineer/SKILL.md +433 -0
  82. package/skills/prompt-engineer/references/prompt-patterns.md +158 -0
  83. package/skills/qa-engineer/SKILL.md +441 -0
  84. package/skills/qa-engineer/references/testing-strategy.md +166 -0
  85. package/skills/qa-engineer/scripts/run_coverage.py +147 -0
  86. package/skills/scrum-master/SKILL.md +225 -0
  87. package/skills/scrum-master/references/sprint-ceremonies.md +159 -0
  88. package/skills/security-analyst/SKILL.md +390 -0
  89. package/skills/security-analyst/references/owasp-top10.md +188 -0
  90. package/skills/security-analyst/scripts/audit_security.py +242 -0
  91. package/skills/seo-auditor/SKILL.md +523 -0
  92. package/skills/seo-auditor/references/seo-checklist.md +17 -0
  93. package/skills/spec-driven-dev/SKILL.md +342 -0
  94. package/skills/spec-driven-dev/references/phase-gates.md +107 -0
  95. package/skills/supabase-expert/SKILL.md +602 -0
  96. package/skills/supabase-expert/references/supabase-patterns.md +19 -0
  97. package/skills/swe-agent/SKILL.md +311 -0
  98. package/skills/swe-agent/references/trajectory-format.md +134 -0
  99. package/skills/systematic-debugger/SKILL.md +512 -0
  100. package/skills/systematic-debugger/references/debugging-guide.md +12 -0
  101. package/skills/tech-lead/SKILL.md +409 -0
  102. package/skills/tech-lead/references/code-review-checklist.md +111 -0
  103. package/skills/technical-writer/SKILL.md +631 -0
  104. package/skills/technical-writer/references/doc-templates.md +218 -0
  105. package/skills/testing-strategist/SKILL.md +476 -0
  106. package/skills/testing-strategist/references/testing-pyramid.md +16 -0
  107. package/skills/ux-ui-designer/SKILL.md +419 -0
  108. package/skills/ux-ui-designer/references/design-system-foundation.md +168 -0
  109. package/skills_overview.txt +94 -0
  110. package/templates/PROJECT_KICKOFF.md +284 -0
  111. package/templates/SKILL_TEMPLATE.md +131 -0
  112. package/templates/USAGE.md +95 -0
  113. package/templates/agent-python/README.md +71 -0
  114. package/templates/agent-python/agent.py +272 -0
  115. package/templates/agent-python/config.yaml +76 -0
  116. package/templates/agent-python/prompts/system.md +109 -0
  117. package/templates/agent-python/requirements.txt +7 -0
  118. package/templates/automation-n8n/README.md +14 -0
  119. package/templates/automation-n8n/webhook-handler.json +57 -0
  120. package/templates/backend-node/Dockerfile +12 -0
  121. package/templates/backend-node/README.md +15 -0
  122. package/templates/backend-node/package.json +30 -0
  123. package/templates/backend-node/src/index.ts +19 -0
  124. package/templates/backend-node/src/routes.ts +7 -0
  125. package/templates/backend-node/tsconfig.json +22 -0
  126. package/templates/backend-python/Dockerfile +11 -0
  127. package/templates/backend-python/README.md +78 -0
  128. package/templates/backend-python/app/core/config.py +12 -0
  129. package/templates/backend-python/app/core/database.py +12 -0
  130. package/templates/backend-python/app/main.py +17 -0
  131. package/templates/backend-python/app/routers/__init__.py +1 -0
  132. package/templates/backend-python/app/routers/health.py +7 -0
  133. package/templates/backend-python/requirements-dev.txt +6 -0
  134. package/templates/backend-python/requirements.txt +4 -0
  135. package/templates/backend-python/tests/test_health.py +9 -0
  136. package/templates/checkpoint.yaml +117 -0
  137. package/templates/database/README.md +474 -0
  138. package/templates/frontend-react/README.md +446 -0
  139. package/templates/plan.yaml +320 -0
  140. package/templates/session.yaml +125 -0
  141. package/templates/spec.yaml +229 -0
  142. package/templates/tasks.yaml +330 -0
  143. package/workflows/bugfix-backend.md +380 -0
  144. package/workflows/documentation.md +232 -0
  145. package/workflows/generate-prd.md +320 -0
  146. package/workflows/ideation.md +396 -0
  147. package/workflows/new-agent-ia.md +497 -0
  148. package/workflows/new-automation.md +374 -0
  149. package/workflows/new-feature.md +290 -0
  150. package/workflows/optimize-performance.md +373 -0
  151. package/workflows/resolve-github-issue.md +524 -0
  152. package/workflows/security-review.md +291 -0
  153. package/workflows/spec-driven.md +476 -0
  154. package/workflows/testing-strategy.md +296 -0
  155. package/workflows/third-party-integration.md +277 -0
@@ -0,0 +1,128 @@
1
+ # Index Strategy Guide — Data Engineer
2
+
3
+ > Guía completa para estrategia de índices en PostgreSQL.
4
+
5
+ ## Regla de Oro
6
+
7
+ > **No crees índices prematuramente.** Crea índices basados en queries reales que observas en producción vía `pg_stat_statements` y `EXPLAIN ANALYZE`.
8
+
9
+ ## Tipos de Índices
10
+
11
+ | Tipo | Cuándo Usar | Ejemplo |
12
+ |------|------------|---------|
13
+ | **B-Tree** (default) | Igualdad, rango, ORDER BY | `CREATE INDEX idx_users_email ON users(email)` |
14
+ | **Hash** | Solo igualdad, reads pesados | `CREATE INDEX idx_users_uuid ON users USING hash(uuid)` |
15
+ | **GIN** | Arrays, JSONB, full-text search | `CREATE INDEX idx_data_tags ON items USING gin(tags)` |
16
+ | **GiST** | Geoespacial, rangos, proximidad | `CREATE INDEX idx_locations ON places USING gist(location)` |
17
+ | **BRIN** | Datos naturalmente ordenados (timestamps) | `CREATE INDEX idx_logs_created ON logs USING brin(created_at)` |
18
+
19
+ ## Patrones de Índices
20
+
21
+ ### 1. Índice Simple
22
+
23
+ ```sql
24
+ -- Para filtros frecuentes en una columna
25
+ CREATE INDEX idx_orders_status ON orders(status);
26
+ ```
27
+
28
+ ### 2. Índice Compuesto
29
+
30
+ ```sql
31
+ -- Para queries que filtran por múltiples columnas
32
+ -- IMPORTANTE: el orden importa (left-to-right)
33
+ CREATE INDEX idx_orders_user_status ON orders(user_id, status);
34
+
35
+ -- Este índice sirve para:
36
+ -- ✅ WHERE user_id = X
37
+ -- ✅ WHERE user_id = X AND status = Y
38
+ -- ❌ WHERE status = Y (no usa el índice)
39
+ ```
40
+
41
+ ### 3. Índice Parcial
42
+
43
+ ```sql
44
+ -- Solo indexa un subconjunto de filas
45
+ -- Ideal para queries que siempre filtran lo mismo
46
+ CREATE INDEX idx_orders_pending
47
+ ON orders(created_at)
48
+ WHERE status = 'pending';
49
+ -- Mucho más pequeño que indexar toda la tabla
50
+ ```
51
+
52
+ ### 4. Índice Covering (INCLUDE)
53
+
54
+ ```sql
55
+ -- Incluye columnas extra para evitar table lookup
56
+ CREATE INDEX idx_orders_user_covering
57
+ ON orders(user_id)
58
+ INCLUDE (status, total, created_at);
59
+ -- Index-Only Scan: no necesita ir a la tabla
60
+ ```
61
+
62
+ ### 5. Índice Unique
63
+
64
+ ```sql
65
+ -- Garantiza unicidad a nivel de DB
66
+ CREATE UNIQUE INDEX unq_users_email ON users(email);
67
+
68
+ -- Unique parcial (solo activos)
69
+ CREATE UNIQUE INDEX unq_users_active_email
70
+ ON users(email)
71
+ WHERE deleted_at IS NULL;
72
+ ```
73
+
74
+ ### 6. Índice para JSONB
75
+
76
+ ```sql
77
+ -- GIN para queries dentro de JSONB
78
+ CREATE INDEX idx_items_metadata ON items USING gin(metadata);
79
+
80
+ -- Soporta:
81
+ -- WHERE metadata @> '{"category": "electronics"}'
82
+ -- WHERE metadata ? 'key_name'
83
+ ```
84
+
85
+ ## Cuándo NO Crear Índices
86
+
87
+ | Situación | Razón |
88
+ |-----------|-------|
89
+ | Tablas con < 1000 filas | Seq Scan es más rápido |
90
+ | Columnas con muy baja cardinalidad (ej: boolean) | El índice no ayuda |
91
+ | Tablas con muchos INSERT/UPDATE | Los índices penalizan escrituras |
92
+ | Columnas que nunca se filtran | Desperdicio de espacio |
93
+
94
+ ## Diagnóstico con EXPLAIN ANALYZE
95
+
96
+ ```sql
97
+ -- Siempre usar EXPLAIN (ANALYZE, BUFFERS) para verificar
98
+ EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
99
+ SELECT * FROM orders
100
+ WHERE user_id = 'abc-123'
101
+ AND status = 'pending'
102
+ ORDER BY created_at DESC
103
+ LIMIT 10;
104
+
105
+ -- Lo que buscas:
106
+ -- ✅ Index Scan / Index Only Scan
107
+ -- ⚠️ Bitmap Heap Scan (aceptable para muchos resultados)
108
+ -- ❌ Seq Scan en tabla grande = falta índice
109
+ -- ❌ Nested Loop con muchas rows = posible N+1
110
+ ```
111
+
112
+ ## Mantenimiento de Índices
113
+
114
+ ```sql
115
+ -- Crear sin bloquear la tabla (CONCURRENTLY)
116
+ CREATE INDEX CONCURRENTLY idx_users_phone ON users(phone);
117
+
118
+ -- Reconstruir índice fragmentado
119
+ REINDEX INDEX CONCURRENTLY idx_users_email;
120
+
121
+ -- Ver tamaño de índices
122
+ SELECT
123
+ indexrelname,
124
+ pg_size_pretty(pg_relation_size(indexrelid)) AS size,
125
+ idx_scan AS scans
126
+ FROM pg_stat_user_indexes
127
+ ORDER BY pg_relation_size(indexrelid) DESC;
128
+ ```
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ LMAgent - Database Backup & Restore Script (PostgreSQL)
4
+ Crea backups comprimidos y restaura bases de datos PostgreSQL.
5
+
6
+ Uso:
7
+ python backup_postgres.py backup --db mydb --output ./backups/
8
+ python backup_postgres.py restore --db mydb --file ./backups/mydb_20240121.sql.gz
9
+ python backup_postgres.py list --dir ./backups/
10
+ python backup_postgres.py clean --dir ./backups/ --keep 7
11
+
12
+ Requiere: pg_dump y pg_restore en el PATH.
13
+ Las credenciales se leen de variables de entorno.
14
+ """
15
+
16
+ import argparse
17
+ import gzip
18
+ import os
19
+ import subprocess
20
+ import sys
21
+ from datetime import datetime
22
+ from pathlib import Path
23
+
24
+
25
+ def get_db_config() -> dict:
26
+ """Obtiene configuración de DB desde variables de entorno."""
27
+ return {
28
+ "host": os.getenv("DB_HOST", "localhost"),
29
+ "port": os.getenv("DB_PORT", "5432"),
30
+ "user": os.getenv("DB_USER", "postgres"),
31
+ "password": os.getenv("DB_PASSWORD", ""),
32
+ }
33
+
34
+
35
+ def backup(db_name: str, output_dir: str) -> str:
36
+ """Crea un backup comprimido de la base de datos."""
37
+ config = get_db_config()
38
+ output_path = Path(output_dir)
39
+ output_path.mkdir(parents=True, exist_ok=True)
40
+
41
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
42
+ filename = f"{db_name}_{timestamp}.sql.gz"
43
+ filepath = output_path / filename
44
+
45
+ env = os.environ.copy()
46
+ env["PGPASSWORD"] = config["password"]
47
+
48
+ print(f"📦 Creando backup de '{db_name}'...")
49
+
50
+ # pg_dump → gzip
51
+ pg_dump_cmd = [
52
+ "pg_dump",
53
+ "-h", config["host"],
54
+ "-p", config["port"],
55
+ "-U", config["user"],
56
+ "-d", db_name,
57
+ "--format=plain",
58
+ "--no-owner",
59
+ "--no-privileges",
60
+ ]
61
+
62
+ try:
63
+ result = subprocess.run(
64
+ pg_dump_cmd,
65
+ capture_output=True,
66
+ env=env,
67
+ timeout=300,
68
+ )
69
+
70
+ if result.returncode != 0:
71
+ print(f"❌ Error en pg_dump: {result.stderr.decode()}")
72
+ sys.exit(1)
73
+
74
+ with gzip.open(filepath, "wb") as f:
75
+ f.write(result.stdout)
76
+
77
+ size_mb = filepath.stat().st_size / (1024 * 1024)
78
+ print(f"✅ Backup creado: {filepath} ({size_mb:.1f} MB)")
79
+ return str(filepath)
80
+
81
+ except subprocess.TimeoutExpired:
82
+ print("❌ Timeout: el backup tardó más de 5 minutos")
83
+ sys.exit(1)
84
+ except FileNotFoundError:
85
+ print("❌ pg_dump no encontrado. Verifica que PostgreSQL esté instalado.")
86
+ sys.exit(1)
87
+
88
+
89
+ def restore(db_name: str, backup_file: str):
90
+ """Restaura una base de datos desde un backup."""
91
+ config = get_db_config()
92
+ filepath = Path(backup_file)
93
+
94
+ if not filepath.exists():
95
+ print(f"❌ Archivo no encontrado: {filepath}")
96
+ sys.exit(1)
97
+
98
+ env = os.environ.copy()
99
+ env["PGPASSWORD"] = config["password"]
100
+
101
+ print(f"🔄 Restaurando backup en '{db_name}' desde {filepath.name}...")
102
+
103
+ # Descomprimir si es .gz
104
+ if filepath.suffix == ".gz":
105
+ with gzip.open(filepath, "rb") as f:
106
+ sql_content = f.read()
107
+ else:
108
+ sql_content = filepath.read_bytes()
109
+
110
+ psql_cmd = [
111
+ "psql",
112
+ "-h", config["host"],
113
+ "-p", config["port"],
114
+ "-U", config["user"],
115
+ "-d", db_name,
116
+ ]
117
+
118
+ try:
119
+ result = subprocess.run(
120
+ psql_cmd,
121
+ input=sql_content,
122
+ capture_output=True,
123
+ env=env,
124
+ timeout=600,
125
+ )
126
+
127
+ if result.returncode != 0:
128
+ stderr = result.stderr.decode()
129
+ if "ERROR" in stderr:
130
+ print(f"⚠️ Restauración completada con errores:\n{stderr[:500]}")
131
+ else:
132
+ print(f"✅ Restauración completada exitosamente.")
133
+ else:
134
+ print(f"✅ Restauración completada exitosamente.")
135
+
136
+ except subprocess.TimeoutExpired:
137
+ print("❌ Timeout: la restauración tardó más de 10 minutos")
138
+ sys.exit(1)
139
+
140
+
141
+ def list_backups(backup_dir: str):
142
+ """Lista los backups disponibles."""
143
+ backup_path = Path(backup_dir)
144
+
145
+ if not backup_path.exists():
146
+ print(f"❌ Directorio no encontrado: {backup_path}")
147
+ sys.exit(1)
148
+
149
+ backups = sorted(backup_path.glob("*.sql*"), reverse=True)
150
+
151
+ if not backups:
152
+ print("📂 No hay backups disponibles.")
153
+ return
154
+
155
+ print(f"\n📂 Backups en {backup_path}:\n")
156
+ print(f"{'Archivo':<45} {'Tamaño':<12} {'Fecha'}")
157
+ print("-" * 75)
158
+
159
+ for b in backups:
160
+ size_mb = b.stat().st_size / (1024 * 1024)
161
+ mod_time = datetime.fromtimestamp(b.stat().st_mtime).strftime("%Y-%m-%d %H:%M")
162
+ print(f"{b.name:<45} {size_mb:>8.1f} MB {mod_time}")
163
+
164
+
165
+ def clean_old_backups(backup_dir: str, keep: int = 7):
166
+ """Elimina backups antiguos, manteniendo los N más recientes."""
167
+ backup_path = Path(backup_dir)
168
+ backups = sorted(backup_path.glob("*.sql*"), key=lambda p: p.stat().st_mtime, reverse=True)
169
+
170
+ to_delete = backups[keep:]
171
+
172
+ if not to_delete:
173
+ print(f"✅ No hay backups para eliminar (manteniendo últimos {keep}).")
174
+ return
175
+
176
+ for b in to_delete:
177
+ b.unlink()
178
+ print(f"🗑️ Eliminado: {b.name}")
179
+
180
+ print(f"✅ Eliminados {len(to_delete)} backups. Mantenidos: {keep}.")
181
+
182
+
183
+ def main():
184
+ parser = argparse.ArgumentParser(
185
+ description="LMAgent PostgreSQL Backup/Restore"
186
+ )
187
+ sub = parser.add_subparsers(dest="command", required=True)
188
+
189
+ # backup
190
+ p_backup = sub.add_parser("backup", help="Crear backup")
191
+ p_backup.add_argument("--db", required=True, help="Nombre de la base de datos")
192
+ p_backup.add_argument("--output", default="./backups", help="Directorio de salida")
193
+
194
+ # restore
195
+ p_restore = sub.add_parser("restore", help="Restaurar backup")
196
+ p_restore.add_argument("--db", required=True, help="Nombre de la base de datos")
197
+ p_restore.add_argument("--file", required=True, help="Archivo de backup")
198
+
199
+ # list
200
+ p_list = sub.add_parser("list", help="Listar backups")
201
+ p_list.add_argument("--dir", default="./backups", help="Directorio de backups")
202
+
203
+ # clean
204
+ p_clean = sub.add_parser("clean", help="Limpiar backups antiguos")
205
+ p_clean.add_argument("--dir", default="./backups", help="Directorio de backups")
206
+ p_clean.add_argument("--keep", type=int, default=7, help="Cantidad a mantener")
207
+
208
+ args = parser.parse_args()
209
+
210
+ if args.command == "backup":
211
+ backup(args.db, args.output)
212
+ elif args.command == "restore":
213
+ restore(args.db, args.file)
214
+ elif args.command == "list":
215
+ list_backups(args.dir)
216
+ elif args.command == "clean":
217
+ clean_old_backups(args.dir, args.keep)
218
+
219
+
220
+ if __name__ == "__main__":
221
+ main()