argos-harness 0.1.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/assets/agents/auditor.md +140 -0
- package/assets/agents/commit-pr-pilot.md +154 -0
- package/assets/agents/explorer.md +93 -0
- package/assets/agents/implementer.md +117 -0
- package/assets/agents/leader.md +149 -0
- package/assets/agents/researcher.md +89 -0
- package/assets/agents/review-readability.md +87 -0
- package/assets/agents/review-reliability.md +100 -0
- package/assets/agents/review-resilience.md +87 -0
- package/assets/agents/review-risk.md +87 -0
- package/assets/agents/reviewer.md +167 -0
- package/assets/agents/ticket-audit.md +129 -0
- package/assets/hooks/argos-guard-destructive.sh +127 -0
- package/assets/hooks/argos-quality-gate.sh +129 -0
- package/assets/managed/aterrizaje.md +24 -0
- package/assets/managed/formato-respuesta.md +21 -0
- package/assets/managed/identidad.md +48 -0
- package/assets/managed/operaciones-seguras.md +14 -0
- package/assets/managed/orquestacion.md +169 -0
- package/assets/output-styles/argos.md +71 -0
- package/assets/skills/ai-sdk-5/SKILL.md +230 -0
- package/assets/skills/angular/SKILL.md +19 -0
- package/assets/skills/angular/references/architecture.md +137 -0
- package/assets/skills/angular/references/core.md +197 -0
- package/assets/skills/angular/references/forms.md +115 -0
- package/assets/skills/angular/references/performance.md +124 -0
- package/assets/skills/apollo-client/SKILL.md +61 -0
- package/assets/skills/app-blueprint/SKILL.md +45 -0
- package/assets/skills/app-blueprint/assets/module-template.md +48 -0
- package/assets/skills/app-blueprint/assets/system-template.md +38 -0
- package/assets/skills/app-blueprint/references/workflow.md +101 -0
- package/assets/skills/app-builder/SKILL.md +43 -0
- package/assets/skills/app-builder/phases/0-product.md +58 -0
- package/assets/skills/app-builder/phases/1-scaffold.md +33 -0
- package/assets/skills/app-builder/phases/10-store.md +40 -0
- package/assets/skills/app-builder/phases/2-data.md +34 -0
- package/assets/skills/app-builder/phases/3-domain.md +33 -0
- package/assets/skills/app-builder/phases/4-ui-nav.md +32 -0
- package/assets/skills/app-builder/phases/5-identity.md +30 -0
- package/assets/skills/app-builder/phases/6-polish.md +34 -0
- package/assets/skills/app-builder/phases/7-brand.md +31 -0
- package/assets/skills/app-builder/phases/8-web.md +30 -0
- package/assets/skills/app-builder/phases/9-docs.md +31 -0
- package/assets/skills/app-ia/SKILL.md +54 -0
- package/assets/skills/astro/SKILL.md +39 -0
- package/assets/skills/axios/SKILL.md +61 -0
- package/assets/skills/branch-pr/SKILL.md +200 -0
- package/assets/skills/bullmq/SKILL.md +55 -0
- package/assets/skills/chained-pr/SKILL.md +48 -0
- package/assets/skills/chained-pr/references/chaining-details.md +99 -0
- package/assets/skills/cognitive-doc-design/SKILL.md +81 -0
- package/assets/skills/comment-writer/SKILL.md +74 -0
- package/assets/skills/dashboard-ia/SKILL.md +54 -0
- package/assets/skills/django-drf/SKILL.md +180 -0
- package/assets/skills/go-testing/SKILL.md +47 -0
- package/assets/skills/go-testing/references/examples.md +89 -0
- package/assets/skills/issue-creation/SKILL.md +223 -0
- package/assets/skills/jira-epic/SKILL.md +306 -0
- package/assets/skills/jira-task/SKILL.md +382 -0
- package/assets/skills/judgment-day/SKILL.md +52 -0
- package/assets/skills/judgment-day/references/prompts-and-formats.md +98 -0
- package/assets/skills/lightsail-deploy/SKILL.md +44 -0
- package/assets/skills/lightsail-deploy/references/runbook.md +102 -0
- package/assets/skills/loop-back-debug/SKILL.md +102 -0
- package/assets/skills/mantine-form/SKILL.md +57 -0
- package/assets/skills/mongoose/SKILL.md +66 -0
- package/assets/skills/nextjs-15/SKILL.md +144 -0
- package/assets/skills/not-boring-mobile/SKILL.md +43 -0
- package/assets/skills/not-boring-mobile/references/not-boring-playbook.md +65 -0
- package/assets/skills/playwright/SKILL.md +315 -0
- package/assets/skills/pr-comments/SKILL.md +93 -0
- package/assets/skills/pr-create/SKILL.md +64 -0
- package/assets/skills/promo-video/SKILL.md +52 -0
- package/assets/skills/promo-video/assets/package.template.json +22 -0
- package/assets/skills/promo-video/assets/promo.template.tsx +469 -0
- package/assets/skills/promo-video/assets/theme.template.ts +27 -0
- package/assets/skills/promo-video/references/pipeline.md +119 -0
- package/assets/skills/promo-video-web/SKILL.md +51 -0
- package/assets/skills/promo-video-web/assets/browser-promo.template.tsx +385 -0
- package/assets/skills/promo-video-web/assets/capture.template.ts +70 -0
- package/assets/skills/promo-video-web/assets/package.template.json +26 -0
- package/assets/skills/promo-video-web/references/pipeline.md +84 -0
- package/assets/skills/pytest/SKILL.md +180 -0
- package/assets/skills/react-19/SKILL.md +118 -0
- package/assets/skills/react-hook-form/SKILL.md +59 -0
- package/assets/skills/react-router/SKILL.md +60 -0
- package/assets/skills/redux-toolkit/SKILL.md +60 -0
- package/assets/skills/review-diff/SKILL.md +101 -0
- package/assets/skills/ship-docs/SKILL.md +45 -0
- package/assets/skills/ship-docs/references/ship-docs-playbook.md +31 -0
- package/assets/skills/skill-creator/SKILL.md +97 -0
- package/assets/skills/skill-creator/assets/SKILL-TEMPLATE.md +68 -0
- package/assets/skills/skill-creator/references/skill-style-guide.md +79 -0
- package/assets/skills/skill-improver/SKILL.md +50 -0
- package/assets/skills/skill-improver/references/skill-style-guide.md +79 -0
- package/assets/skills/socketio/SKILL.md +58 -0
- package/assets/skills/spec-bootstrap/SKILL.md +62 -0
- package/assets/skills/store-ship/SKILL.md +52 -0
- package/assets/skills/store-ship/assets/android-supply.template.md +22 -0
- package/assets/skills/store-ship/assets/eas.template.json +32 -0
- package/assets/skills/store-ship/assets/maestro-flow.template.yaml +27 -0
- package/assets/skills/store-ship/assets/store.config.template.json +28 -0
- package/assets/skills/store-ship/references/pipeline.md +198 -0
- package/assets/skills/stripe/SKILL.md +83 -0
- package/assets/skills/tailwind-4/SKILL.md +193 -0
- package/assets/skills/tamagui/SKILL.md +60 -0
- package/assets/skills/tanstack-query/SKILL.md +58 -0
- package/assets/skills/ticket-intake/SKILL.md +55 -0
- package/assets/skills/typescript/SKILL.md +134 -0
- package/assets/skills/verify-before-done/SKILL.md +111 -0
- package/assets/skills/webapp-rebuilder/SKILL.md +48 -0
- package/assets/skills/webapp-rebuilder/assets/charter-template.md +46 -0
- package/assets/skills/webapp-rebuilder/references/workflow.md +47 -0
- package/assets/skills/winston-logging/SKILL.md +61 -0
- package/assets/skills/work-unit-commits/SKILL.md +84 -0
- package/assets/skills/zod-4/SKILL.md +210 -0
- package/assets/skills/zustand-5/SKILL.md +216 -0
- package/bin/argos.js +6 -0
- package/dist/commands/adopt.d.ts +35 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +347 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +478 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +32 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +358 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/remove.d.ts +62 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +487 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/workspace.d.ts +73 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +354 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assets.d.ts +29 -0
- package/dist/lib/assets.d.ts.map +1 -0
- package/dist/lib/assets.js +57 -0
- package/dist/lib/assets.js.map +1 -0
- package/dist/lib/atomic-write.d.ts +17 -0
- package/dist/lib/atomic-write.d.ts.map +1 -0
- package/dist/lib/atomic-write.js +41 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/backup.d.ts +11 -0
- package/dist/lib/backup.d.ts.map +1 -0
- package/dist/lib/backup.js +42 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +36 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/detect.d.ts +58 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +330 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/ficha.d.ts +10 -0
- package/dist/lib/ficha.d.ts.map +1 -0
- package/dist/lib/ficha.js +38 -0
- package/dist/lib/ficha.js.map +1 -0
- package/dist/lib/git.d.ts +27 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +79 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/managed-files.d.ts +35 -0
- package/dist/lib/managed-files.d.ts.map +1 -0
- package/dist/lib/managed-files.js +97 -0
- package/dist/lib/managed-files.js.map +1 -0
- package/dist/lib/markers.d.ts +64 -0
- package/dist/lib/markers.d.ts.map +1 -0
- package/dist/lib/markers.js +157 -0
- package/dist/lib/markers.js.map +1 -0
- package/dist/lib/navori-import.d.ts +42 -0
- package/dist/lib/navori-import.d.ts.map +1 -0
- package/dist/lib/navori-import.js +65 -0
- package/dist/lib/navori-import.js.map +1 -0
- package/dist/lib/openclaw-agents.d.ts +53 -0
- package/dist/lib/openclaw-agents.d.ts.map +1 -0
- package/dist/lib/openclaw-agents.js +118 -0
- package/dist/lib/openclaw-agents.js.map +1 -0
- package/dist/lib/package-root.d.ts +11 -0
- package/dist/lib/package-root.d.ts.map +1 -0
- package/dist/lib/package-root.js +23 -0
- package/dist/lib/package-root.js.map +1 -0
- package/dist/lib/paths.d.ts +11 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +16 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/settings-merge.d.ts +125 -0
- package/dist/lib/settings-merge.d.ts.map +1 -0
- package/dist/lib/settings-merge.js +373 -0
- package/dist/lib/settings-merge.js.map +1 -0
- package/dist/lib/version.d.ts +3 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +13 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/which.d.ts +8 -0
- package/dist/lib/which.d.ts.map +1 -0
- package/dist/lib/which.js +30 -0
- package/dist/lib/which.js.map +1 -0
- package/dist/lib/workspaces.d.ts +133 -0
- package/dist/lib/workspaces.d.ts.map +1 -0
- package/dist/lib/workspaces.js +241 -0
- package/dist/lib/workspaces.js.map +1 -0
- package/dist/lib/zod-messages.d.ts +4 -0
- package/dist/lib/zod-messages.d.ts.map +1 -0
- package/dist/lib/zod-messages.js +28 -0
- package/dist/lib/zod-messages.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
## Rol: orquestador (centro de gravedad)
|
|
2
|
+
|
|
3
|
+
Ante una tarea no trivial actúas como el orquestador: descompones y coordinas,
|
|
4
|
+
no implementas el código directamente. Este rol lo encarnas tú, el agente
|
|
5
|
+
principal — es el único que puede abrir un abanico de subagentes en paralelo.
|
|
6
|
+
NUNCA lo delegues: no invoques un subagente "leader" ni ningún equivalente; el
|
|
7
|
+
rol de orquestador no es un subagente delegable, es tu propia función como
|
|
8
|
+
agente principal. Delegarlo serializa el trabajo y tira abajo el paralelismo.
|
|
9
|
+
Hay siempre exactamente UN hilo orquestador — nunca dos agentes coordinando
|
|
10
|
+
en simultáneo sobre la misma tarea.
|
|
11
|
+
|
|
12
|
+
Los agentes de rol viven una sola vez a nivel de motor (`~/.claude/agents/`):
|
|
13
|
+
`explorer`, `researcher`, `implementer`, `reviewer`, `ticket-audit`,
|
|
14
|
+
`commit-pr-pilot`, `auditor` y las lentes 4R (`review-risk`,
|
|
15
|
+
`review-readability`, `review-reliability`, `review-resilience`). Cargan en
|
|
16
|
+
toda sesión, en cualquier repo, sin importar el cwd — no existen agentes "de
|
|
17
|
+
repo" que los reemplacen ni los sombreen. Lo que cambia de un repo a otro es
|
|
18
|
+
el dato, nunca el agente: cada agente/skill resuelve en runtime el quality
|
|
19
|
+
gate del repo (ficha/argos.config.json) — nunca asumas un comando
|
|
20
|
+
hardcodeado, verifícalo ahí antes de declarar algo terminado.
|
|
21
|
+
|
|
22
|
+
En modo operador (el default) esta es la única capa de orquestación posible:
|
|
23
|
+
no hay una capa "de repo" separada que la reemplace. La única excepción es un
|
|
24
|
+
repo exportado (`argos export`, opt-in de equipo): ahí el compilado
|
|
25
|
+
versionado manda para sesiones de terceros sin este motor instalado; tus
|
|
26
|
+
propias sesiones como operador, con el motor global, nunca dependen de ese
|
|
27
|
+
export. Los hooks globales parametrizados, además, solo corren dentro de una
|
|
28
|
+
sesión anclada en el repo (ver aterrizaje); fuera de esa sesión no asumas
|
|
29
|
+
guardas automáticas — verifica el gate a mano.
|
|
30
|
+
|
|
31
|
+
### Cómo descomponer (tabla de escalado)
|
|
32
|
+
|
|
33
|
+
| Complejidad | Subagentes |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Trivial (1 archivo) | 1 `implementer` |
|
|
36
|
+
| Media (2–3 archivos) | 1 `implementer` → 1 `reviewer` |
|
|
37
|
+
| Multi-bug independiente (sin estado compartido) | N `implementer` en paralelo (1 por bug, scopes aislados) → 1 `reviewer` que valida los N diffs juntos |
|
|
38
|
+
| Compleja (migración, refactor multi-capa) | `ticket-audit` → 2–3 `researcher`/`explorer` en paralelo → `implementer` → `reviewer` → `commit-pr-pilot` |
|
|
39
|
+
| Muy compleja | Divide en sub-tareas y reaplica la tabla |
|
|
40
|
+
|
|
41
|
+
Investigación con preguntas acotadas → `researcher`; mapas amplios (¿dónde
|
|
42
|
+
vive X?) → `explorer`. Con audit previo, pasa al `implementer` la ruta de
|
|
43
|
+
`.claude/progress/audit_<ID>.md` — relativa al repo donde trabajas, nunca al
|
|
44
|
+
motor global.
|
|
45
|
+
|
|
46
|
+
### Lentes de review 4R (por perfil de riesgo)
|
|
47
|
+
|
|
48
|
+
El `reviewer` general es el revisor por defecto del ciclo `implementer` →
|
|
49
|
+
`reviewer`. Para diffs de riesgo lo complementas (no lo reemplazas) con
|
|
50
|
+
lentes especializadas read-only, seleccionadas por perfil:
|
|
51
|
+
|
|
52
|
+
| Señal del diff | Lente |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Naming/estructura claros, refactor chico | `review-readability` |
|
|
55
|
+
| Comportamiento, estado, tests, regresiones | `review-reliability` |
|
|
56
|
+
| Integración shell/proceso, fallas parciales, dependencias degradadas | `review-resilience` |
|
|
57
|
+
| Seguridad, permisos, exposición de datos, arquitectura, dependencias | `review-risk` |
|
|
58
|
+
| PR grande / hot path (auth, payments, security) / más de 400 líneas cambiadas | las 4 en paralelo (fan-out 4R) |
|
|
59
|
+
|
|
60
|
+
Numeración R usada dentro de cada archivo de lente: R1 `review-risk`, R2
|
|
61
|
+
`review-readability`, R3 `review-reliability`, R4 `review-resilience`. Una
|
|
62
|
+
lente barata alcanza para lo cotidiano; el fan-out 4R (las 4 llamadas `Agent`
|
|
63
|
+
en el MISMO turno, ver Paralelismo) se reserva para hot paths o diffs
|
|
64
|
+
grandes. Diffs chicos → solo el `reviewer`. Cada lente escribe su avance en
|
|
65
|
+
`.claude/progress/review_<lente>_<feature>.md` (ruta relativa al repo) y
|
|
66
|
+
devuelve `done -> <ruta>`; la síntesis de los veredictos la haces tú.
|
|
67
|
+
|
|
68
|
+
### Paralelismo (la palanca — mecánica, no opcional)
|
|
69
|
+
|
|
70
|
+
El paralelismo es analítico, no solo velocidad: el valor está en partir el
|
|
71
|
+
problema en piezas genuinamente independientes y en cómo integras lo que
|
|
72
|
+
vuelve. La mecánica: cuando la tabla dice "en paralelo", eso se logra
|
|
73
|
+
emitiendo TODAS las llamadas `Agent` en un MISMO turno. Por defecto se lanzan
|
|
74
|
+
en serie; el paralelo hay que pedirlo explícito, en un solo mensaje.
|
|
75
|
+
|
|
76
|
+
- Correcto: en un mensaje, invoca `Agent` 3 veces (`explorer` auth, db, api).
|
|
77
|
+
Corren concurrentes; el total ≈ el más lento.
|
|
78
|
+
- Incorrecto: invocar auth, esperar su `done -> ruta`, luego db, luego api.
|
|
79
|
+
Eso es serie y tira lo que el paralelo ahorra.
|
|
80
|
+
|
|
81
|
+
Regla: sub-tareas independientes (no comparten estado ni una depende del
|
|
82
|
+
output de otra) → mismo turno. Serializa solo con dependencia real
|
|
83
|
+
(`implementer` → `reviewer`). `implementer` en paralelo SOLO con archivos
|
|
84
|
+
disjuntos — dos que tocan el mismo archivo se pisan y van en serie; en la
|
|
85
|
+
duda, serie. Reparte el scope explícito antes de abrir el abanico.
|
|
86
|
+
|
|
87
|
+
### Fan-out → síntesis
|
|
88
|
+
|
|
89
|
+
Para una pregunta amplia, descompónla en sub-preguntas y lanza un
|
|
90
|
+
investigador por cada una en paralelo. Cuando vuelven los `done -> ruta`,
|
|
91
|
+
recopila y analiza a fondo TÚ: lee los N archivos juntos, cruza hallazgos
|
|
92
|
+
(contradicciones, gaps, qué falta) y recién ahí decides la implementación. La
|
|
93
|
+
síntesis NUNCA se delega — ni a un subagente de síntesis, ni al último
|
|
94
|
+
agente de la ronda.
|
|
95
|
+
|
|
96
|
+
### Presupuesto de delegación (aplica a TODO encargo delegado)
|
|
97
|
+
|
|
98
|
+
- Lo mecánico se separa ANTES de delegar. Copias de archivos, renombres,
|
|
99
|
+
scaffolding: los haces tú directo o van a un agente de tier bajo. Nunca se
|
|
100
|
+
empaquetan dentro del encargo de un `implementer` — inflan su contexto y
|
|
101
|
+
su corrida sin subir calidad.
|
|
102
|
+
- Un encargo = una unidad de trabajo. Si el `implementer` encuentra un bug
|
|
103
|
+
preexistente fuera de su scope, lo reporta y se detiene ahí (fix trivial de
|
|
104
|
+
una línea es la excepción). Tú decides si abre unidad aparte — el scope no
|
|
105
|
+
se expande solo a mitad de corrida.
|
|
106
|
+
- Tests dirigidos durante, suite completa al cierre. El `implementer` corre
|
|
107
|
+
los archivos de test del área que toca mientras trabaja; la suite completa
|
|
108
|
+
— el quality gate del repo (ficha/argos.config.json) — corre UNA vez al
|
|
109
|
+
cierre de la unidad de trabajo, no en cada iteración.
|
|
110
|
+
- Review de una pasada en diffs chicos/medianos. Hallazgos menores los
|
|
111
|
+
corriges tú directo, sin ronda extra de re-verificación. La
|
|
112
|
+
re-verificación se reserva para cuando el fix tocó maquinaria compartida y
|
|
113
|
+
el cambio en sí es riesgoso — no reabras el review indefinidamente.
|
|
114
|
+
- Ronda de fix → agente fresco, no resume. Retomar un agente con transcript
|
|
115
|
+
grande re-alimenta todo su historial en cada turno. Para una ronda de fixes
|
|
116
|
+
acotada (por ejemplo, hallazgos de un review 4R), lanza un agente NUEVO con
|
|
117
|
+
solo el contrato del fix — no sigas con el `implementer` original y su
|
|
118
|
+
contexto viejo; el contexto caliente casi nunca paga lo que cuesta
|
|
119
|
+
arrastrarlo.
|
|
120
|
+
- Scopes disjuntos → paralelo también en rondas de fix. Reparte los N fixes
|
|
121
|
+
por archivos que no se cruzan y ábrelos en el mismo turno (ver
|
|
122
|
+
Paralelismo). Consolida en un solo agente solo cuando los archivos
|
|
123
|
+
realmente se pisan.
|
|
124
|
+
|
|
125
|
+
### Agiliza con subagentes por default
|
|
126
|
+
|
|
127
|
+
Si el trabajo puede acelerarse delegando (lecturas amplias, sub-tareas
|
|
128
|
+
independientes, escrituras con scopes disjuntos), delégalo en paralelo — no
|
|
129
|
+
lo hagas monolítico. El tier de cada subagente se elige por
|
|
130
|
+
costo-beneficio-velocidad de SU sub-tarea: tier bajo para lo mecánico, tier
|
|
131
|
+
medio para implementación estándar, tier alto solo donde el juicio o el
|
|
132
|
+
diseño deciden el resultado. Nunca todos los agentes al tier alto por
|
|
133
|
+
default.
|
|
134
|
+
|
|
135
|
+
### Ejecución continua (no pausar entre tareas)
|
|
136
|
+
|
|
137
|
+
Aprobado el plan/scope, ejecuta TODAS las sub-tareas sin pedir confirmación
|
|
138
|
+
entre nodos. No hagas "hice la 1, ¿sigo con la 2?" — ejecuta el plan. Solo
|
|
139
|
+
paras por: BLOCKED (subagente bloqueado que no puedes resolver), spec
|
|
140
|
+
ambigua mid-flight (gap real fuera de scope), o ciclo completo (listo para
|
|
141
|
+
PR). Cap: 2 ciclos CHANGES_REQUESTED sobre la misma tarea → escala al
|
|
142
|
+
usuario en vez de reintentar en loop.
|
|
143
|
+
|
|
144
|
+
### Síntesis sin teléfono descompuesto
|
|
145
|
+
|
|
146
|
+
Instruye a los subagentes a escribir su avance en
|
|
147
|
+
`.claude/progress/<archivo>.md` — siempre una ruta relativa al repo donde
|
|
148
|
+
trabajan, nunca al motor global en `~/.claude`; tú recibes solo la línea
|
|
149
|
+
`done -> <ruta>`. Esa carpeta es solo para handoffs efímeros entre agentes
|
|
150
|
+
(`audit_*`, `explore_*`, `research_*`, `impl_*`, `review_*`); el estado de
|
|
151
|
+
sesión (tarea, plan, blockers) vive en `progress/current.md` (raíz del repo,
|
|
152
|
+
persiste en git) y lo consolidas tú, nunca los subagentes — cada
|
|
153
|
+
`implementer` reporta su estado (incluido `blocked`) en su propio
|
|
154
|
+
`impl_<feature>.md`. Verifica el diff/evidencia tú mismo, no confíes ciego en
|
|
155
|
+
el reporte. Al cerrar el ciclo, cuando `review_<feature>.md` diga `APPROVED`,
|
|
156
|
+
invoca `commit-pr-pilot` (pre-flight: working tree limpio, no estás en la
|
|
157
|
+
rama base del repo, el quality gate del repo (ficha/argos.config.json) en
|
|
158
|
+
verde, `gh auth status` ok). Si dice `CHANGES_REQUESTED`, lanza otro
|
|
159
|
+
`implementer` fresco — no el pilot.
|
|
160
|
+
|
|
161
|
+
### Cuándo NO orquestar (hazlo tú directo)
|
|
162
|
+
|
|
163
|
+
- Pregunta conceptual / lectura pura → responde sin subagentes.
|
|
164
|
+
- Cambios en `docs/`, `.claude/`, `CLAUDE.md`, `progress/` del repo →
|
|
165
|
+
edítalos tú; el código fuente del proyecto NUNCA — eso es del
|
|
166
|
+
`implementer`.
|
|
167
|
+
- Una sola línea trivial en un archivo conocido → puede no valer el overhead
|
|
168
|
+
del fan-out. El fan-out cuesta contexto; no abras 5 explorers para una
|
|
169
|
+
tarea chica.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Argos
|
|
3
|
+
description: La voz de Argos — el vigía de cien ojos, que reporta lo visto antes de opinar
|
|
4
|
+
keep-coding-instructions: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Argos Output Style
|
|
8
|
+
|
|
9
|
+
## Quién sos
|
|
10
|
+
|
|
11
|
+
Sos Argos Panoptes: el vigía de cien ojos, siempre con alguno abierto. Tu
|
|
12
|
+
oficio es ver, y tu palabra vale porque distinguís lo que viste de lo que no.
|
|
13
|
+
No sos solemne ni teatral — lo mítico está en la actitud (vigilancia total,
|
|
14
|
+
calma, certeza ganada), no en el vocabulario.
|
|
15
|
+
|
|
16
|
+
## Registro
|
|
17
|
+
|
|
18
|
+
- Español neutro, sereno y preciso. Términos técnicos en inglés.
|
|
19
|
+
- Frases cortas. Sin exclamaciones. Sin muletillas de entusiasmo.
|
|
20
|
+
- Lideras con el estado observado; el juicio viene después y se nota que es
|
|
21
|
+
juicio.
|
|
22
|
+
- Metáforas de vigilancia con cuentagotas y solo cuando aportan: "a la
|
|
23
|
+
vista", "fuera de mi vista", "lo estoy mirando".
|
|
24
|
+
- Nunca disfraz griego ("¡oh, mortal!", invocaciones, tono de oráculo).
|
|
25
|
+
Nunca hablás de vos mismo en tercera persona ("Argos ve que...").
|
|
26
|
+
|
|
27
|
+
## Principio rector: visto vs. inferido
|
|
28
|
+
|
|
29
|
+
La regla que te define por encima de cualquier estilo:
|
|
30
|
+
|
|
31
|
+
- **Lo visto se afirma con su fuente**: "el gate falla en
|
|
32
|
+
`test/auth.spec.ts`, lo corrí recién".
|
|
33
|
+
- **Lo no visto se declara**: "no he mirado los hooks de ese repo" — nunca
|
|
34
|
+
se rellena con suposición presentada como hecho.
|
|
35
|
+
- **Lo inferido se marca**: "por el patrón del stack, infiero X; no lo
|
|
36
|
+
verifiqué".
|
|
37
|
+
|
|
38
|
+
Un vigía que reporta lo que no vio deja de servir. Preferí "no lo sé, lo
|
|
39
|
+
miro" a cualquier respuesta fluida sin respaldo.
|
|
40
|
+
|
|
41
|
+
## Comportamiento
|
|
42
|
+
|
|
43
|
+
- Reportás primero, opinás después. Malas noticias completas y sin
|
|
44
|
+
amortiguar.
|
|
45
|
+
- Una pregunta a la vez; si la respuesta puede observarse (código, git,
|
|
46
|
+
config), la observás en vez de preguntar.
|
|
47
|
+
- En la duda entre breve y detallado: breve. El detalle está disponible, no
|
|
48
|
+
impuesto.
|
|
49
|
+
- Desacuerdo directo con evidencia; sin adulación; reconocés lo que no
|
|
50
|
+
sabés.
|
|
51
|
+
|
|
52
|
+
## Alcance (persona scope) — CRÍTICO
|
|
53
|
+
|
|
54
|
+
Esta voz rige SOLO tu conversación con el operador — lo que decís en el
|
|
55
|
+
chat. NO rige ningún artefacto que produzcas:
|
|
56
|
+
|
|
57
|
+
- Código, identificadores, nombres de función/variable, comentarios.
|
|
58
|
+
- Copy de UI, etiquetas, texto de botones, mensajes de error, cadenas de
|
|
59
|
+
accesibilidad.
|
|
60
|
+
- Documentación, README, mensajes de commit, descripciones de PR.
|
|
61
|
+
- Cualquier string dentro del código fuente.
|
|
62
|
+
|
|
63
|
+
Cada artefacto sigue las convenciones propias del proyecto y su idioma
|
|
64
|
+
configurado (tomado de la ficha del repo o de `argos.config.json` en
|
|
65
|
+
runtime) — nunca el tono de este estilo. El tono mítico jamás toca un
|
|
66
|
+
artefacto: un commit tuyo es un conventional commit común y corriente.
|
|
67
|
+
|
|
68
|
+
## navori vs. Argos
|
|
69
|
+
|
|
70
|
+
navori era el arquitecto pragmático que conversaba; vos sos el vigía que
|
|
71
|
+
reporta.
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ai-sdk-5
|
|
3
|
+
description: Vercel AI SDK 5 patterns. Trigger: When building AI chat features - breaking changes from v4.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Breaking Changes from AI SDK 4
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
// ❌ AI SDK 4 (OLD)
|
|
10
|
+
import { useChat } from "ai";
|
|
11
|
+
const { messages, handleSubmit, input, handleInputChange } = useChat({
|
|
12
|
+
api: "/api/chat",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// ✅ AI SDK 5 (NEW)
|
|
16
|
+
import { useChat } from "@ai-sdk/react";
|
|
17
|
+
import { DefaultChatTransport } from "ai";
|
|
18
|
+
|
|
19
|
+
const { messages, sendMessage } = useChat({
|
|
20
|
+
transport: new DefaultChatTransport({ api: "/api/chat" }),
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Client Setup
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { useChat } from "@ai-sdk/react";
|
|
28
|
+
import { DefaultChatTransport } from "ai";
|
|
29
|
+
import { useState } from "react";
|
|
30
|
+
|
|
31
|
+
export function Chat() {
|
|
32
|
+
const [input, setInput] = useState("");
|
|
33
|
+
|
|
34
|
+
const { messages, sendMessage, isLoading, error } = useChat({
|
|
35
|
+
transport: new DefaultChatTransport({ api: "/api/chat" }),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const handleSubmit = (e: React.FormEvent) => {
|
|
39
|
+
e.preventDefault();
|
|
40
|
+
if (!input.trim()) return;
|
|
41
|
+
sendMessage({ text: input });
|
|
42
|
+
setInput("");
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div>
|
|
47
|
+
<div>
|
|
48
|
+
{messages.map((message) => (
|
|
49
|
+
<Message key={message.id} message={message} />
|
|
50
|
+
))}
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<form onSubmit={handleSubmit}>
|
|
54
|
+
<input
|
|
55
|
+
value={input}
|
|
56
|
+
onChange={(e) => setInput(e.target.value)}
|
|
57
|
+
placeholder="Type a message..."
|
|
58
|
+
disabled={isLoading}
|
|
59
|
+
/>
|
|
60
|
+
<button type="submit" disabled={isLoading}>
|
|
61
|
+
Send
|
|
62
|
+
</button>
|
|
63
|
+
</form>
|
|
64
|
+
|
|
65
|
+
{error && <div>Error: {error.message}</div>}
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## UIMessage Structure (v5)
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// ❌ Old: message.content was a string
|
|
75
|
+
// ✅ New: message.parts is an array
|
|
76
|
+
|
|
77
|
+
interface UIMessage {
|
|
78
|
+
id: string;
|
|
79
|
+
role: "user" | "assistant" | "system";
|
|
80
|
+
parts: MessagePart[];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
type MessagePart =
|
|
84
|
+
| { type: "text"; text: string }
|
|
85
|
+
| { type: "image"; image: string }
|
|
86
|
+
| { type: "tool-call"; toolCallId: string; toolName: string; args: unknown }
|
|
87
|
+
| { type: "tool-result"; toolCallId: string; result: unknown };
|
|
88
|
+
|
|
89
|
+
// Extract text from parts
|
|
90
|
+
function getMessageText(message: UIMessage): string {
|
|
91
|
+
return message.parts
|
|
92
|
+
.filter((part): part is { type: "text"; text: string } => part.type === "text")
|
|
93
|
+
.map((part) => part.text)
|
|
94
|
+
.join("");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Render message
|
|
98
|
+
function Message({ message }: { message: UIMessage }) {
|
|
99
|
+
return (
|
|
100
|
+
<div className={message.role === "user" ? "user" : "assistant"}>
|
|
101
|
+
{message.parts.map((part, index) => {
|
|
102
|
+
if (part.type === "text") {
|
|
103
|
+
return <p key={index}>{part.text}</p>;
|
|
104
|
+
}
|
|
105
|
+
if (part.type === "image") {
|
|
106
|
+
return <img key={index} src={part.image} alt="" />;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
})}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Server-Side (Route Handler)
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// app/api/chat/route.ts
|
|
119
|
+
import { openai } from "@ai-sdk/openai";
|
|
120
|
+
import { streamText } from "ai";
|
|
121
|
+
|
|
122
|
+
export async function POST(req: Request) {
|
|
123
|
+
const { messages } = await req.json();
|
|
124
|
+
|
|
125
|
+
const result = await streamText({
|
|
126
|
+
model: openai("gpt-4o"),
|
|
127
|
+
messages,
|
|
128
|
+
system: "You are a helpful assistant.",
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return result.toDataStreamResponse();
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## With LangChain
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
// app/api/chat/route.ts
|
|
139
|
+
import { toUIMessageStream } from "@ai-sdk/langchain";
|
|
140
|
+
import { ChatOpenAI } from "@langchain/openai";
|
|
141
|
+
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
|
142
|
+
|
|
143
|
+
export async function POST(req: Request) {
|
|
144
|
+
const { messages } = await req.json();
|
|
145
|
+
|
|
146
|
+
const model = new ChatOpenAI({
|
|
147
|
+
modelName: "gpt-4o",
|
|
148
|
+
streaming: true,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Convert UI messages to LangChain format
|
|
152
|
+
const langchainMessages = messages.map((m) => {
|
|
153
|
+
const text = m.parts
|
|
154
|
+
.filter((p) => p.type === "text")
|
|
155
|
+
.map((p) => p.text)
|
|
156
|
+
.join("");
|
|
157
|
+
return m.role === "user"
|
|
158
|
+
? new HumanMessage(text)
|
|
159
|
+
: new AIMessage(text);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const stream = await model.stream(langchainMessages);
|
|
163
|
+
|
|
164
|
+
return toUIMessageStream(stream).toDataStreamResponse();
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Streaming with Tools
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { openai } from "@ai-sdk/openai";
|
|
172
|
+
import { streamText, tool } from "ai";
|
|
173
|
+
import { z } from "zod";
|
|
174
|
+
|
|
175
|
+
const result = await streamText({
|
|
176
|
+
model: openai("gpt-4o"),
|
|
177
|
+
messages,
|
|
178
|
+
tools: {
|
|
179
|
+
getWeather: tool({
|
|
180
|
+
description: "Get weather for a location",
|
|
181
|
+
parameters: z.object({
|
|
182
|
+
location: z.string().describe("City name"),
|
|
183
|
+
}),
|
|
184
|
+
execute: async ({ location }) => {
|
|
185
|
+
// Fetch weather data
|
|
186
|
+
return { temperature: 72, condition: "sunny" };
|
|
187
|
+
},
|
|
188
|
+
}),
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## useCompletion (Text Generation)
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import { useCompletion } from "@ai-sdk/react";
|
|
197
|
+
import { DefaultCompletionTransport } from "ai";
|
|
198
|
+
|
|
199
|
+
const { completion, complete, isLoading } = useCompletion({
|
|
200
|
+
transport: new DefaultCompletionTransport({ api: "/api/complete" }),
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Trigger completion
|
|
204
|
+
await complete("Write a haiku about");
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Error Handling
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const { error, messages, sendMessage } = useChat({
|
|
211
|
+
transport: new DefaultChatTransport({ api: "/api/chat" }),
|
|
212
|
+
onError: (error) => {
|
|
213
|
+
console.error("Chat error:", error);
|
|
214
|
+
toast.error("Failed to send message");
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Display error
|
|
219
|
+
{error && (
|
|
220
|
+
<div className="error">
|
|
221
|
+
{error.message}
|
|
222
|
+
<button onClick={() => sendMessage({ text: lastInput })}>
|
|
223
|
+
Retry
|
|
224
|
+
</button>
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Keywords
|
|
230
|
+
ai sdk, vercel ai, chat, streaming, langchain, openai, llm
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular
|
|
3
|
+
description: Angular patterns covering standalone components, signals, inject(), native control flow, and zoneless change detection; Signal Forms and Reactive Forms; project structure via the Scope Rule and file naming; and performance via NgOptimizedImage, @defer, lazy routes, and SSR. Trigger: When creating Angular components, working with forms, structuring an Angular app, or optimizing Angular performance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Orientation
|
|
7
|
+
|
|
8
|
+
This skill assumes modern Angular: **standalone components** (no `standalone: true` flag needed), **signals** for state, **inject()** over constructor injection, native **`@if`/`@for`/`@switch`** control flow, and **zoneless** change detection (no `zone.js`). RxJS is used only where signals don't fit (combining streams, debounce/throttle, race conditions, websockets).
|
|
9
|
+
|
|
10
|
+
## Index
|
|
11
|
+
|
|
12
|
+
| Reference | Covers |
|
|
13
|
+
|-----------|--------|
|
|
14
|
+
| [references/core.md](references/core.md) | Standalone components, `input`/`output`/`model`, signals, no lifecycle hooks, `inject()`, control flow, RxJS-vs-signals, zoneless setup |
|
|
15
|
+
| [references/forms.md](references/forms.md) | Signal Forms (experimental) vs Reactive Forms vs template-driven, nested forms/`FormArray` |
|
|
16
|
+
| [references/architecture.md](references/architecture.md) | The Scope Rule, project structure, file naming (no `.component`/`.service` suffixes), style guide, CLI commands |
|
|
17
|
+
| [references/performance.md](references/performance.md) | `NgOptimizedImage`, `@defer`, lazy routes, SSR/hydration, slow computations |
|
|
18
|
+
|
|
19
|
+
Read the reference file(s) relevant to the task at hand before writing Angular code.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
## The Scope Rule (REQUIRED)
|
|
2
|
+
|
|
3
|
+
**"Scope determines structure"** - Where a component lives depends on its usage.
|
|
4
|
+
|
|
5
|
+
| Usage | Placement |
|
|
6
|
+
|-------|-----------|
|
|
7
|
+
| Used by 1 feature | `features/[feature]/components/` |
|
|
8
|
+
| Used by 2+ features | `features/shared/components/` |
|
|
9
|
+
|
|
10
|
+
### Example
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
features/
|
|
14
|
+
shopping-cart/
|
|
15
|
+
shopping-cart.ts # Main component = feature name
|
|
16
|
+
components/
|
|
17
|
+
cart-item.ts # Used ONLY by shopping-cart
|
|
18
|
+
cart-summary.ts # Used ONLY by shopping-cart
|
|
19
|
+
checkout/
|
|
20
|
+
checkout.ts
|
|
21
|
+
components/
|
|
22
|
+
payment-form.ts # Used ONLY by checkout
|
|
23
|
+
shared/
|
|
24
|
+
components/
|
|
25
|
+
button.ts # Used by shopping-cart AND checkout
|
|
26
|
+
modal.ts # Used by multiple features
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Project Structure
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
src/app/
|
|
35
|
+
features/
|
|
36
|
+
[feature-name]/
|
|
37
|
+
[feature-name].ts # Main component (same name as folder)
|
|
38
|
+
components/ # Feature-specific components
|
|
39
|
+
services/ # Feature-specific services
|
|
40
|
+
models/ # Feature-specific types
|
|
41
|
+
shared/ # ONLY for 2+ feature usage
|
|
42
|
+
components/
|
|
43
|
+
services/
|
|
44
|
+
pipes/
|
|
45
|
+
core/ # App-wide singletons
|
|
46
|
+
services/
|
|
47
|
+
interceptors/
|
|
48
|
+
guards/
|
|
49
|
+
app.ts
|
|
50
|
+
app.config.ts
|
|
51
|
+
routes.ts
|
|
52
|
+
main.ts
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## File Naming (REQUIRED)
|
|
58
|
+
|
|
59
|
+
No `.component`, `.service`, `.model` suffixes. The folder tells you what it is.
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
✅ user-profile.ts
|
|
63
|
+
❌ user-profile.component.ts
|
|
64
|
+
|
|
65
|
+
✅ cart.ts
|
|
66
|
+
❌ cart.service.ts
|
|
67
|
+
|
|
68
|
+
✅ user.ts
|
|
69
|
+
❌ user.model.ts
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Style Guide
|
|
75
|
+
|
|
76
|
+
### What We Follow (from official docs)
|
|
77
|
+
|
|
78
|
+
- `inject()` over constructor injection
|
|
79
|
+
- `class` and `style` bindings over `ngClass`/`ngStyle`
|
|
80
|
+
- `protected` for template-only members
|
|
81
|
+
- `readonly` for inputs, outputs, queries
|
|
82
|
+
- Name handlers for action (`saveUser`) not event (`handleClick`)
|
|
83
|
+
- Keep lifecycle hooks simple - delegate to well-named methods
|
|
84
|
+
- One concept per file
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
@Component({...})
|
|
88
|
+
export class UserProfileComponent {
|
|
89
|
+
// 1. Injected dependencies
|
|
90
|
+
private readonly userService = inject(UserService);
|
|
91
|
+
|
|
92
|
+
// 2. Inputs/Outputs
|
|
93
|
+
readonly userId = input.required<string>();
|
|
94
|
+
readonly userSaved = output<User>();
|
|
95
|
+
|
|
96
|
+
// 3. Internal state
|
|
97
|
+
private readonly _loading = signal(false);
|
|
98
|
+
readonly loading = this._loading.asReadonly();
|
|
99
|
+
|
|
100
|
+
// 4. Computed
|
|
101
|
+
protected readonly displayName = computed(() => ...);
|
|
102
|
+
|
|
103
|
+
// 5. Methods
|
|
104
|
+
save(): void { ... }
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### What We Override
|
|
109
|
+
|
|
110
|
+
| Official Says | We Do | Why |
|
|
111
|
+
|---------------|-------|-----|
|
|
112
|
+
| `user-profile.component.ts` | `user-profile.ts` | Redundant - folder tells context |
|
|
113
|
+
| `user.service.ts` | `user.ts` | Same |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Commands
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# New project
|
|
121
|
+
ng new my-app --style=scss --ssr=false
|
|
122
|
+
|
|
123
|
+
# Component in feature
|
|
124
|
+
ng g c features/products/components/product-card --flat
|
|
125
|
+
|
|
126
|
+
# Service in feature
|
|
127
|
+
ng g s features/products/services/product --flat
|
|
128
|
+
|
|
129
|
+
# Guard in core
|
|
130
|
+
ng g g core/guards/auth --functional
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Resources
|
|
136
|
+
|
|
137
|
+
- https://angular.dev/style-guide
|