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.
Files changed (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/assets/agents/auditor.md +140 -0
  4. package/assets/agents/commit-pr-pilot.md +154 -0
  5. package/assets/agents/explorer.md +93 -0
  6. package/assets/agents/implementer.md +117 -0
  7. package/assets/agents/leader.md +149 -0
  8. package/assets/agents/researcher.md +89 -0
  9. package/assets/agents/review-readability.md +87 -0
  10. package/assets/agents/review-reliability.md +100 -0
  11. package/assets/agents/review-resilience.md +87 -0
  12. package/assets/agents/review-risk.md +87 -0
  13. package/assets/agents/reviewer.md +167 -0
  14. package/assets/agents/ticket-audit.md +129 -0
  15. package/assets/hooks/argos-guard-destructive.sh +127 -0
  16. package/assets/hooks/argos-quality-gate.sh +129 -0
  17. package/assets/managed/aterrizaje.md +24 -0
  18. package/assets/managed/formato-respuesta.md +21 -0
  19. package/assets/managed/identidad.md +48 -0
  20. package/assets/managed/operaciones-seguras.md +14 -0
  21. package/assets/managed/orquestacion.md +169 -0
  22. package/assets/output-styles/argos.md +71 -0
  23. package/assets/skills/ai-sdk-5/SKILL.md +230 -0
  24. package/assets/skills/angular/SKILL.md +19 -0
  25. package/assets/skills/angular/references/architecture.md +137 -0
  26. package/assets/skills/angular/references/core.md +197 -0
  27. package/assets/skills/angular/references/forms.md +115 -0
  28. package/assets/skills/angular/references/performance.md +124 -0
  29. package/assets/skills/apollo-client/SKILL.md +61 -0
  30. package/assets/skills/app-blueprint/SKILL.md +45 -0
  31. package/assets/skills/app-blueprint/assets/module-template.md +48 -0
  32. package/assets/skills/app-blueprint/assets/system-template.md +38 -0
  33. package/assets/skills/app-blueprint/references/workflow.md +101 -0
  34. package/assets/skills/app-builder/SKILL.md +43 -0
  35. package/assets/skills/app-builder/phases/0-product.md +58 -0
  36. package/assets/skills/app-builder/phases/1-scaffold.md +33 -0
  37. package/assets/skills/app-builder/phases/10-store.md +40 -0
  38. package/assets/skills/app-builder/phases/2-data.md +34 -0
  39. package/assets/skills/app-builder/phases/3-domain.md +33 -0
  40. package/assets/skills/app-builder/phases/4-ui-nav.md +32 -0
  41. package/assets/skills/app-builder/phases/5-identity.md +30 -0
  42. package/assets/skills/app-builder/phases/6-polish.md +34 -0
  43. package/assets/skills/app-builder/phases/7-brand.md +31 -0
  44. package/assets/skills/app-builder/phases/8-web.md +30 -0
  45. package/assets/skills/app-builder/phases/9-docs.md +31 -0
  46. package/assets/skills/app-ia/SKILL.md +54 -0
  47. package/assets/skills/astro/SKILL.md +39 -0
  48. package/assets/skills/axios/SKILL.md +61 -0
  49. package/assets/skills/branch-pr/SKILL.md +200 -0
  50. package/assets/skills/bullmq/SKILL.md +55 -0
  51. package/assets/skills/chained-pr/SKILL.md +48 -0
  52. package/assets/skills/chained-pr/references/chaining-details.md +99 -0
  53. package/assets/skills/cognitive-doc-design/SKILL.md +81 -0
  54. package/assets/skills/comment-writer/SKILL.md +74 -0
  55. package/assets/skills/dashboard-ia/SKILL.md +54 -0
  56. package/assets/skills/django-drf/SKILL.md +180 -0
  57. package/assets/skills/go-testing/SKILL.md +47 -0
  58. package/assets/skills/go-testing/references/examples.md +89 -0
  59. package/assets/skills/issue-creation/SKILL.md +223 -0
  60. package/assets/skills/jira-epic/SKILL.md +306 -0
  61. package/assets/skills/jira-task/SKILL.md +382 -0
  62. package/assets/skills/judgment-day/SKILL.md +52 -0
  63. package/assets/skills/judgment-day/references/prompts-and-formats.md +98 -0
  64. package/assets/skills/lightsail-deploy/SKILL.md +44 -0
  65. package/assets/skills/lightsail-deploy/references/runbook.md +102 -0
  66. package/assets/skills/loop-back-debug/SKILL.md +102 -0
  67. package/assets/skills/mantine-form/SKILL.md +57 -0
  68. package/assets/skills/mongoose/SKILL.md +66 -0
  69. package/assets/skills/nextjs-15/SKILL.md +144 -0
  70. package/assets/skills/not-boring-mobile/SKILL.md +43 -0
  71. package/assets/skills/not-boring-mobile/references/not-boring-playbook.md +65 -0
  72. package/assets/skills/playwright/SKILL.md +315 -0
  73. package/assets/skills/pr-comments/SKILL.md +93 -0
  74. package/assets/skills/pr-create/SKILL.md +64 -0
  75. package/assets/skills/promo-video/SKILL.md +52 -0
  76. package/assets/skills/promo-video/assets/package.template.json +22 -0
  77. package/assets/skills/promo-video/assets/promo.template.tsx +469 -0
  78. package/assets/skills/promo-video/assets/theme.template.ts +27 -0
  79. package/assets/skills/promo-video/references/pipeline.md +119 -0
  80. package/assets/skills/promo-video-web/SKILL.md +51 -0
  81. package/assets/skills/promo-video-web/assets/browser-promo.template.tsx +385 -0
  82. package/assets/skills/promo-video-web/assets/capture.template.ts +70 -0
  83. package/assets/skills/promo-video-web/assets/package.template.json +26 -0
  84. package/assets/skills/promo-video-web/references/pipeline.md +84 -0
  85. package/assets/skills/pytest/SKILL.md +180 -0
  86. package/assets/skills/react-19/SKILL.md +118 -0
  87. package/assets/skills/react-hook-form/SKILL.md +59 -0
  88. package/assets/skills/react-router/SKILL.md +60 -0
  89. package/assets/skills/redux-toolkit/SKILL.md +60 -0
  90. package/assets/skills/review-diff/SKILL.md +101 -0
  91. package/assets/skills/ship-docs/SKILL.md +45 -0
  92. package/assets/skills/ship-docs/references/ship-docs-playbook.md +31 -0
  93. package/assets/skills/skill-creator/SKILL.md +97 -0
  94. package/assets/skills/skill-creator/assets/SKILL-TEMPLATE.md +68 -0
  95. package/assets/skills/skill-creator/references/skill-style-guide.md +79 -0
  96. package/assets/skills/skill-improver/SKILL.md +50 -0
  97. package/assets/skills/skill-improver/references/skill-style-guide.md +79 -0
  98. package/assets/skills/socketio/SKILL.md +58 -0
  99. package/assets/skills/spec-bootstrap/SKILL.md +62 -0
  100. package/assets/skills/store-ship/SKILL.md +52 -0
  101. package/assets/skills/store-ship/assets/android-supply.template.md +22 -0
  102. package/assets/skills/store-ship/assets/eas.template.json +32 -0
  103. package/assets/skills/store-ship/assets/maestro-flow.template.yaml +27 -0
  104. package/assets/skills/store-ship/assets/store.config.template.json +28 -0
  105. package/assets/skills/store-ship/references/pipeline.md +198 -0
  106. package/assets/skills/stripe/SKILL.md +83 -0
  107. package/assets/skills/tailwind-4/SKILL.md +193 -0
  108. package/assets/skills/tamagui/SKILL.md +60 -0
  109. package/assets/skills/tanstack-query/SKILL.md +58 -0
  110. package/assets/skills/ticket-intake/SKILL.md +55 -0
  111. package/assets/skills/typescript/SKILL.md +134 -0
  112. package/assets/skills/verify-before-done/SKILL.md +111 -0
  113. package/assets/skills/webapp-rebuilder/SKILL.md +48 -0
  114. package/assets/skills/webapp-rebuilder/assets/charter-template.md +46 -0
  115. package/assets/skills/webapp-rebuilder/references/workflow.md +47 -0
  116. package/assets/skills/winston-logging/SKILL.md +61 -0
  117. package/assets/skills/work-unit-commits/SKILL.md +84 -0
  118. package/assets/skills/zod-4/SKILL.md +210 -0
  119. package/assets/skills/zustand-5/SKILL.md +216 -0
  120. package/bin/argos.js +6 -0
  121. package/dist/commands/adopt.d.ts +35 -0
  122. package/dist/commands/adopt.d.ts.map +1 -0
  123. package/dist/commands/adopt.js +347 -0
  124. package/dist/commands/adopt.js.map +1 -0
  125. package/dist/commands/doctor.d.ts +20 -0
  126. package/dist/commands/doctor.d.ts.map +1 -0
  127. package/dist/commands/doctor.js +478 -0
  128. package/dist/commands/doctor.js.map +1 -0
  129. package/dist/commands/init.d.ts +32 -0
  130. package/dist/commands/init.d.ts.map +1 -0
  131. package/dist/commands/init.js +358 -0
  132. package/dist/commands/init.js.map +1 -0
  133. package/dist/commands/remove.d.ts +62 -0
  134. package/dist/commands/remove.d.ts.map +1 -0
  135. package/dist/commands/remove.js +487 -0
  136. package/dist/commands/remove.js.map +1 -0
  137. package/dist/commands/workspace.d.ts +73 -0
  138. package/dist/commands/workspace.d.ts.map +1 -0
  139. package/dist/commands/workspace.js +354 -0
  140. package/dist/commands/workspace.js.map +1 -0
  141. package/dist/index.d.ts +2 -0
  142. package/dist/index.d.ts.map +1 -0
  143. package/dist/index.js +24 -0
  144. package/dist/index.js.map +1 -0
  145. package/dist/lib/assets.d.ts +29 -0
  146. package/dist/lib/assets.d.ts.map +1 -0
  147. package/dist/lib/assets.js +57 -0
  148. package/dist/lib/assets.js.map +1 -0
  149. package/dist/lib/atomic-write.d.ts +17 -0
  150. package/dist/lib/atomic-write.d.ts.map +1 -0
  151. package/dist/lib/atomic-write.js +41 -0
  152. package/dist/lib/atomic-write.js.map +1 -0
  153. package/dist/lib/backup.d.ts +11 -0
  154. package/dist/lib/backup.d.ts.map +1 -0
  155. package/dist/lib/backup.js +42 -0
  156. package/dist/lib/backup.js.map +1 -0
  157. package/dist/lib/config.d.ts +36 -0
  158. package/dist/lib/config.d.ts.map +1 -0
  159. package/dist/lib/config.js +52 -0
  160. package/dist/lib/config.js.map +1 -0
  161. package/dist/lib/detect.d.ts +58 -0
  162. package/dist/lib/detect.d.ts.map +1 -0
  163. package/dist/lib/detect.js +330 -0
  164. package/dist/lib/detect.js.map +1 -0
  165. package/dist/lib/ficha.d.ts +10 -0
  166. package/dist/lib/ficha.d.ts.map +1 -0
  167. package/dist/lib/ficha.js +38 -0
  168. package/dist/lib/ficha.js.map +1 -0
  169. package/dist/lib/git.d.ts +27 -0
  170. package/dist/lib/git.d.ts.map +1 -0
  171. package/dist/lib/git.js +79 -0
  172. package/dist/lib/git.js.map +1 -0
  173. package/dist/lib/managed-files.d.ts +35 -0
  174. package/dist/lib/managed-files.d.ts.map +1 -0
  175. package/dist/lib/managed-files.js +97 -0
  176. package/dist/lib/managed-files.js.map +1 -0
  177. package/dist/lib/markers.d.ts +64 -0
  178. package/dist/lib/markers.d.ts.map +1 -0
  179. package/dist/lib/markers.js +157 -0
  180. package/dist/lib/markers.js.map +1 -0
  181. package/dist/lib/navori-import.d.ts +42 -0
  182. package/dist/lib/navori-import.d.ts.map +1 -0
  183. package/dist/lib/navori-import.js +65 -0
  184. package/dist/lib/navori-import.js.map +1 -0
  185. package/dist/lib/openclaw-agents.d.ts +53 -0
  186. package/dist/lib/openclaw-agents.d.ts.map +1 -0
  187. package/dist/lib/openclaw-agents.js +118 -0
  188. package/dist/lib/openclaw-agents.js.map +1 -0
  189. package/dist/lib/package-root.d.ts +11 -0
  190. package/dist/lib/package-root.d.ts.map +1 -0
  191. package/dist/lib/package-root.js +23 -0
  192. package/dist/lib/package-root.js.map +1 -0
  193. package/dist/lib/paths.d.ts +11 -0
  194. package/dist/lib/paths.d.ts.map +1 -0
  195. package/dist/lib/paths.js +16 -0
  196. package/dist/lib/paths.js.map +1 -0
  197. package/dist/lib/settings-merge.d.ts +125 -0
  198. package/dist/lib/settings-merge.d.ts.map +1 -0
  199. package/dist/lib/settings-merge.js +373 -0
  200. package/dist/lib/settings-merge.js.map +1 -0
  201. package/dist/lib/version.d.ts +3 -0
  202. package/dist/lib/version.d.ts.map +1 -0
  203. package/dist/lib/version.js +13 -0
  204. package/dist/lib/version.js.map +1 -0
  205. package/dist/lib/which.d.ts +8 -0
  206. package/dist/lib/which.d.ts.map +1 -0
  207. package/dist/lib/which.js +30 -0
  208. package/dist/lib/which.js.map +1 -0
  209. package/dist/lib/workspaces.d.ts +133 -0
  210. package/dist/lib/workspaces.d.ts.map +1 -0
  211. package/dist/lib/workspaces.js +241 -0
  212. package/dist/lib/workspaces.js.map +1 -0
  213. package/dist/lib/zod-messages.d.ts +4 -0
  214. package/dist/lib/zod-messages.d.ts.map +1 -0
  215. package/dist/lib/zod-messages.js +28 -0
  216. package/dist/lib/zod-messages.js.map +1 -0
  217. package/package.json +44 -0
@@ -0,0 +1,197 @@
1
+ ## Standalone Components (REQUIRED)
2
+
3
+ Components are standalone by default. Do NOT set `standalone: true`.
4
+
5
+ ```typescript
6
+ @Component({
7
+ selector: 'app-user',
8
+ imports: [CommonModule],
9
+ changeDetection: ChangeDetectionStrategy.OnPush,
10
+ template: `...`
11
+ })
12
+ export class UserComponent {}
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Input/Output Functions (REQUIRED)
18
+
19
+ ```typescript
20
+ // ✅ ALWAYS: Function-based
21
+ readonly user = input.required<User>();
22
+ readonly disabled = input(false);
23
+ readonly selected = output<User>();
24
+ readonly checked = model(false); // Two-way binding
25
+
26
+ // ❌ NEVER: Decorators
27
+ @Input() user: User;
28
+ @Output() selected = new EventEmitter<User>();
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Signals for State (REQUIRED)
34
+
35
+ ```typescript
36
+ readonly count = signal(0);
37
+ readonly doubled = computed(() => this.count() * 2);
38
+
39
+ // Update
40
+ this.count.set(5);
41
+ this.count.update(prev => prev + 1);
42
+
43
+ // Side effects
44
+ effect(() => localStorage.setItem('count', this.count().toString()));
45
+ ```
46
+
47
+ ---
48
+
49
+ ## NO Lifecycle Hooks (REQUIRED)
50
+
51
+ Signals replace lifecycle hooks. Do NOT use `ngOnInit`, `ngOnChanges`, `ngOnDestroy`.
52
+
53
+ ```typescript
54
+ // ❌ NEVER: Lifecycle hooks
55
+ ngOnInit() {
56
+ this.loadUser();
57
+ }
58
+
59
+ ngOnChanges(changes: SimpleChanges) {
60
+ if (changes['userId']) {
61
+ this.loadUser();
62
+ }
63
+ }
64
+
65
+ // ✅ ALWAYS: Signals + effect
66
+ readonly userId = input.required<string>();
67
+ readonly user = signal<User | null>(null);
68
+
69
+ private userEffect = effect(() => {
70
+ // Runs automatically when userId() changes
71
+ this.loadUser(this.userId());
72
+ });
73
+
74
+ // ✅ For derived data, use computed
75
+ readonly displayName = computed(() => this.user()?.name ?? 'Guest');
76
+ ```
77
+
78
+ ### When to Use What
79
+
80
+ | Need | Use |
81
+ |------|-----|
82
+ | React to input changes | `effect()` watching the input signal |
83
+ | Derived/computed state | `computed()` |
84
+ | Side effects (API calls, localStorage) | `effect()` |
85
+ | Cleanup on destroy | `DestroyRef` + `inject()` |
86
+
87
+ ```typescript
88
+ // Cleanup example
89
+ private readonly destroyRef = inject(DestroyRef);
90
+
91
+ constructor() {
92
+ const subscription = someObservable$.subscribe();
93
+ this.destroyRef.onDestroy(() => subscription.unsubscribe());
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## inject() Over Constructor (REQUIRED)
100
+
101
+ ```typescript
102
+ // ✅ ALWAYS
103
+ private readonly http = inject(HttpClient);
104
+
105
+ // ❌ NEVER
106
+ constructor(private http: HttpClient) {}
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Native Control Flow (REQUIRED)
112
+
113
+ ```html
114
+ @if (loading()) {
115
+ <spinner />
116
+ } @else {
117
+ @for (item of items(); track item.id) {
118
+ <item-card [data]="item" />
119
+ } @empty {
120
+ <p>No items</p>
121
+ }
122
+ }
123
+
124
+ @switch (status()) {
125
+ @case ('active') { <span>Active</span> }
126
+ @default { <span>Unknown</span> }
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## RxJS - Only When Needed
133
+
134
+ Signals are the default. Use RxJS ONLY for complex async operations.
135
+
136
+ | Use Signals | Use RxJS |
137
+ |-------------|----------|
138
+ | Component state | Combining multiple streams |
139
+ | Derived values | Debounce/throttle |
140
+ | Simple async (single API call) | Race conditions |
141
+ | Input/Output | WebSockets, real-time |
142
+ | | Complex error retry logic |
143
+
144
+ ```typescript
145
+ // ✅ Simple API call - use signals
146
+ readonly user = signal<User | null>(null);
147
+ readonly loading = signal(false);
148
+
149
+ async loadUser(id: string) {
150
+ this.loading.set(true);
151
+ this.user.set(await firstValueFrom(this.http.get<User>(`/api/users/${id}`)));
152
+ this.loading.set(false);
153
+ }
154
+
155
+ // ✅ Complex stream - use RxJS
156
+ readonly searchResults$ = this.searchTerm$.pipe(
157
+ debounceTime(300),
158
+ distinctUntilChanged(),
159
+ switchMap(term => this.http.get<Results>(`/api/search?q=${term}`))
160
+ );
161
+
162
+ // Convert to signal when needed in template
163
+ readonly searchResults = toSignal(this.searchResults$, { initialValue: [] });
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Zoneless Angular (REQUIRED)
169
+
170
+ Angular is zoneless. Use `provideZonelessChangeDetection()`.
171
+
172
+ ```typescript
173
+ bootstrapApplication(AppComponent, {
174
+ providers: [provideZonelessChangeDetection()]
175
+ });
176
+ ```
177
+
178
+ Remove ZoneJS:
179
+ ```bash
180
+ npm uninstall zone.js
181
+ ```
182
+
183
+ Remove from `angular.json` polyfills: `zone.js` and `zone.js/testing`.
184
+
185
+ ### Zoneless Requirements
186
+ - Use `OnPush` change detection
187
+ - Use signals for state (auto-notifies Angular)
188
+ - Use `AsyncPipe` for observables
189
+ - Use `markForCheck()` when needed
190
+
191
+ ---
192
+
193
+ ## Resources
194
+
195
+ - https://angular.dev/guide/signals
196
+ - https://angular.dev/guide/templates/control-flow
197
+ - https://angular.dev/guide/zoneless
@@ -0,0 +1,115 @@
1
+ ## When to Use What
2
+
3
+ | Use Case | Recommendation |
4
+ |----------|----------------|
5
+ | New apps with signals | Signal Forms (experimental) |
6
+ | Production apps | Reactive Forms |
7
+ | Simple forms | Template-driven |
8
+
9
+ ---
10
+
11
+ ## Signal Forms (v21+, experimental)
12
+
13
+ ```typescript
14
+ import { form, FormField, required, email } from '@angular/forms/signals';
15
+
16
+ @Component({
17
+ imports: [FormField],
18
+ template: `
19
+ <form>
20
+ <input [formField]="emailField" type="email" />
21
+ <input [formField]="passwordField" type="password" />
22
+ <button (click)="submit()">Login</button>
23
+ </form>
24
+ `
25
+ })
26
+ export class LoginComponent {
27
+ readonly loginForm = form({
28
+ email: ['', [required, email]],
29
+ password: ['', required]
30
+ });
31
+
32
+ readonly emailField = this.loginForm.controls.email;
33
+ readonly passwordField = this.loginForm.controls.password;
34
+
35
+ submit() {
36
+ if (this.loginForm.valid()) {
37
+ const values = this.loginForm.value();
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### Signal Forms Benefits
44
+ - Automatic two-way binding
45
+ - Type-safe field access
46
+ - Schema-based validation
47
+ - Built on signals
48
+
49
+ ---
50
+
51
+ ## Reactive Forms (production)
52
+
53
+ ```typescript
54
+ import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
55
+
56
+ @Component({
57
+ imports: [ReactiveFormsModule],
58
+ template: `
59
+ <form [formGroup]="form" (ngSubmit)="submit()">
60
+ <input formControlName="email" type="email" />
61
+ <input formControlName="password" type="password" />
62
+ <button type="submit" [disabled]="form.invalid">Login</button>
63
+ </form>
64
+ `
65
+ })
66
+ export class LoginComponent {
67
+ private readonly fb = inject(FormBuilder);
68
+
69
+ form = this.fb.nonNullable.group({
70
+ email: ['', [Validators.required, Validators.email]],
71
+ password: ['', [Validators.required, Validators.minLength(8)]],
72
+ });
73
+
74
+ submit() {
75
+ if (this.form.valid) {
76
+ const { email, password } = this.form.getRawValue();
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Key Points
83
+ - ALWAYS use `fb.nonNullable.group()` for type safety
84
+ - Use `getRawValue()` to get typed values
85
+ - Reactive Forms are synchronous (easier to test)
86
+
87
+ ---
88
+
89
+ ## Nested Forms & FormArray
90
+
91
+ ```typescript
92
+ form = this.fb.nonNullable.group({
93
+ name: [''],
94
+ address: this.fb.group({
95
+ street: [''],
96
+ city: [''],
97
+ }),
98
+ phones: this.fb.array([this.fb.control('')]),
99
+ });
100
+
101
+ get phones() {
102
+ return this.form.get('phones') as FormArray;
103
+ }
104
+
105
+ addPhone() {
106
+ this.phones.push(this.fb.control(''));
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Resources
113
+
114
+ - https://angular.dev/guide/forms/signals/overview
115
+ - https://angular.dev/guide/forms/reactive-forms
@@ -0,0 +1,124 @@
1
+ ## NgOptimizedImage (REQUIRED for images)
2
+
3
+ ```typescript
4
+ import { NgOptimizedImage } from '@angular/common';
5
+
6
+ @Component({
7
+ imports: [NgOptimizedImage],
8
+ template: `
9
+ <!-- LCP image: add priority -->
10
+ <img ngSrc="hero.jpg" width="800" height="400" priority>
11
+
12
+ <!-- Regular: lazy loaded by default -->
13
+ <img ngSrc="thumb.jpg" width="200" height="200">
14
+
15
+ <!-- Fill mode (parent needs position: relative) -->
16
+ <img ngSrc="bg.jpg" fill>
17
+
18
+ <!-- With placeholder -->
19
+ <img ngSrc="photo.jpg" width="400" height="300" placeholder>
20
+ `
21
+ })
22
+ ```
23
+
24
+ ### Rules
25
+ - ALWAYS set `width` and `height` (or `fill`)
26
+ - Add `priority` to LCP (Largest Contentful Paint) image
27
+ - Use `ngSrc` not `src`
28
+ - Parent of `fill` image must have `position: relative/fixed/absolute`
29
+
30
+ ---
31
+
32
+ ## @defer - Lazy Components
33
+
34
+ ```html
35
+ @defer (on viewport) {
36
+ <heavy-component />
37
+ } @placeholder {
38
+ <p>Placeholder shown immediately</p>
39
+ } @loading (minimum 200ms) {
40
+ <spinner />
41
+ } @error {
42
+ <p>Failed to load</p>
43
+ }
44
+ ```
45
+
46
+ ### Triggers
47
+
48
+ | Trigger | When to Use |
49
+ |---------|-------------|
50
+ | `on viewport` | Below the fold content |
51
+ | `on interaction` | Load on click/focus/hover |
52
+ | `on idle` | Load when browser is idle |
53
+ | `on timer(500ms)` | Load after delay |
54
+ | `when condition` | Load when expression is true |
55
+
56
+ ```html
57
+ <!-- Multiple triggers -->
58
+ @defer (on viewport; on interaction) {
59
+ <comments />
60
+ }
61
+
62
+ <!-- Conditional -->
63
+ @defer (when showComments()) {
64
+ <comments />
65
+ }
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Lazy Routes
71
+
72
+ ```typescript
73
+ // Single component
74
+ {
75
+ path: 'admin',
76
+ loadComponent: () => import('./features/admin/admin').then(c => c.AdminComponent)
77
+ }
78
+
79
+ // Feature with child routes
80
+ {
81
+ path: 'users',
82
+ loadChildren: () => import('./features/users/routes').then(m => m.USERS_ROUTES)
83
+ }
84
+ ```
85
+
86
+ ---
87
+
88
+ ## SSR & Hydration
89
+
90
+ ```typescript
91
+ bootstrapApplication(AppComponent, {
92
+ providers: [
93
+ provideClientHydration()
94
+ ]
95
+ });
96
+ ```
97
+
98
+ | Scenario | Use |
99
+ |----------|-----|
100
+ | SEO critical (blog, e-commerce) | SSR |
101
+ | Dashboard/Admin | CSR |
102
+ | Static marketing site | SSG/Prerender |
103
+
104
+ ---
105
+
106
+ ## Slow Computations
107
+
108
+ | Solution | When |
109
+ |----------|------|
110
+ | Optimize algorithm | First choice always |
111
+ | Pure pipes | Cache single result |
112
+ | Memoization | Cache multiple results |
113
+ | `computed()` | Derived signal state |
114
+
115
+ **NEVER** trigger reflows/repaints in lifecycle hooks (`ngOnInit`, `ngAfterViewInit`).
116
+
117
+ ---
118
+
119
+ ## Resources
120
+
121
+ - https://angular.dev/guide/image-optimization
122
+ - https://angular.dev/guide/defer
123
+ - https://angular.dev/best-practices/runtime-performance
124
+ - https://angular.dev/guide/ssr
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: apollo-client
3
+ description: GraphQL con Apollo Client — hooks, fetchPolicy, normalización de caché y actualización tras mutaciones. Trigger: al escribir queries/mutations, configurar la caché o los links.
4
+ ---
5
+
6
+ # Apollo Client — el patrón canónico
7
+
8
+ Lecturas declarativas con hooks, caché **normalizada por id**, y la UI se mantiene en sync actualizando la caché tras cada mutación. Los concerns de red/auth viven en los links, no en los componentes.
9
+
10
+ ## Cuándo usar este skill
11
+
12
+ Al escribir una query/mutation, configurar `InMemoryCache`/`typePolicies`, o la cadena de `links`.
13
+
14
+ ## Hooks y aislamiento
15
+
16
+ `useQuery` (lectura al montar), `useLazyQuery` (bajo demanda, retorna `execute`), `useMutation` (retorna `[mutate, { data, loading, error }]`). Aísla los hooks en una capa (hook + adapter): el componente recibe un **modelo de dominio**, no el shape crudo de GraphQL.
17
+
18
+ ```ts
19
+ export function useReport(id: string) {
20
+ const { data, loading, error } = useGetReportQuery({ variables: { id }, fetchPolicy: 'cache-first' });
21
+ return { report: data?.report ? adaptReport(data.report) : null, loading, error };
22
+ }
23
+ ```
24
+
25
+ ## fetchPolicy según el dato
26
+
27
+ - `cache-first` (default) — catálogos/detalles ya traídos por una lista.
28
+ - `cache-and-network` — feeds que cambian seguido (render instantáneo + refresh).
29
+ - `network-only` — sesión/bootstrap, datos críticos.
30
+ - Evita `no-cache` salvo PII estricta que no deba tocar disco.
31
+
32
+ ## Normalización de caché
33
+
34
+ ```ts
35
+ const cache = new InMemoryCache({ typePolicies: { Report: { keyFields: ['id'] } } });
36
+ ```
37
+
38
+ Con `keyFields`, Apollo identifica entidades por id y deduplica/actualiza solo. Sin normalización, las listas y detalles se desincronizan.
39
+
40
+ ## Reglas duras
41
+
42
+ 1. **Tras una mutation, actualiza la caché:** `update(cache, { data })` (`cache.modify`/`evict`/`writeQuery`) o `refetchQueries`. Nunca dejes la UI desincronizada.
43
+ 2. **`optimisticResponse`** para UI instantánea (resultado temporal con `__typename` + id ficticio); `update` reconcilia al llegar la respuesta real.
44
+ 3. **No over-fetch:** pide solo los campos que el componente usa; apóyate en **fragments con colocation** (el fragmento junto al componente que lo consume). Regenera tipos (codegen) tras editar `.graphql`.
45
+ 4. **Maneja `loading` y `error` siempre.** Separa error de red (banner genérico, resuelto en un `errorLink`) de error de negocio (`graphQLErrors`, copy según `extensions.code`).
46
+ 5. **Paginación** con `fetchMore` + `updateQuery`, o `relayStylePagination`/merge en `typePolicies`.
47
+ 6. Red/auth/upload en la cadena de **links** (auth → error → upload), no en cada componente.
48
+
49
+ ```ts
50
+ const [createReport] = useCreateReportMutation({
51
+ optimisticResponse: { createReport: { __typename: 'Report', id: 'temp', ...fields } },
52
+ update(cache) { cache.evict({ fieldName: 'reports' }); }, // invalida la lista
53
+ });
54
+ ```
55
+
56
+ ## Antes de declarar listo
57
+
58
+ - Hooks aislados en capa (hook + adapter); el componente ve el modelo de dominio.
59
+ - Caché normalizada por `keyFields`; mutaciones actualizan/invalidan la caché.
60
+ - `fetchPolicy` elegido por tipo de dato; `loading`/`error` manejados.
61
+ - El quality gate del repo (`qualityGate.fast` en `argos.config.json`) en verde.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: app-blueprint
3
+ description: Generate reconstruction-grade docs of an app — business rules, endpoints, routes, screens, contracts. Trigger: app blueprint, appblueprint, reverse-spec, mapear app, map app for reconstruction.
4
+ ---
5
+
6
+ ## Activation Contract
7
+
8
+ Activate on `/app-blueprint <target>` or requests to map/document an app well enough to rebuild it without losing logic or features. Targets: `<repo-dir>` (one repo), `all` (every repo in the workspace root minus user exclusions), `system` (cross-repo synthesis from existing blueprints).
9
+
10
+ ## Hard Rules
11
+
12
+ - Output goes to `<workspace-root>/blueprint/<repo>/`. All docs in English.
13
+ - Phase 0 inventory is mandatory and script-only (`rg`/`fd`, zero agent reading). `_inventory.json` is the coverage contract for the whole run.
14
+ - Module agents write their doc file directly to disk and return ONE summary line. Never pipe doc content through the orchestrator context.
15
+ - Business rules are numbered, testable statements with `file:line` refs. No prose-only rules.
16
+ - Partition modules by business domain, never by folder.
17
+ - The run is not done until the audit maps every inventory item (route, endpoint, model, page, slice, job) to a doc section, or lists it in `_gaps.md`.
18
+
19
+ ## Decision Gates
20
+
21
+ | Target | Action |
22
+ |--------|--------|
23
+ | Single repo | Phases 0-2 on that repo per `references/workflow.md` |
24
+ | `all` | Phases 0-2 per repo, one repo at a time |
25
+ | `system` | Read existing blueprints only (no source code), cross-check contracts, write `SYSTEM.md` |
26
+ | Frontend stack detected | Module docs use frontend sections of the template |
27
+ | Backend stack detected | Module docs use backend sections of the template |
28
+
29
+ ## Execution Steps
30
+
31
+ 1. Read `references/workflow.md` in full before acting.
32
+ 2. Phase 0: detect stack, run the inventory command cookbook, write `_inventory.json`.
33
+ 3. Phase 1: partition into 6-12 domain modules; spawn all module agents in parallel (Agent tool, single message, `model: sonnet`), each pointed at `assets/module-template.md`.
34
+ 4. Phase 2: audit coverage against `_inventory.json`; spawn gap agents for unmapped items; write the repo `README.md`.
35
+ 5. `system` mode: cross-check consumed vs exposed endpoints across blueprints; write `SYSTEM.md`.
36
+
37
+ ## Output Contract
38
+
39
+ Per repo: `blueprint/<repo>/{README.md, _inventory.json, <module>.md...}` plus `_gaps.md` if items remain unresolved. System mode: `blueprint/SYSTEM.md`. Final report to user: files written, coverage count (mapped/total), gaps.
40
+
41
+ ## References
42
+
43
+ - `references/workflow.md` — phase details, inventory command cookbook, agent prompt templates, audit rules.
44
+ - `assets/module-template.md` — module doc template (frontend/backend sections).
45
+ - `assets/system-template.md` — SYSTEM.md skeleton with contract table.
@@ -0,0 +1,48 @@
1
+ # Module: {name}
2
+
3
+ **Repo:** {repo} · **Kind:** {frontend|backend} · **Purpose:** one sentence.
4
+
5
+ ## Screens & Routes (frontend) / Endpoints (backend)
6
+
7
+ Frontend:
8
+
9
+ | Route | Screen/Page | Guard | Purpose |
10
+ |-------|-------------|-------|---------|
11
+
12
+ Backend:
13
+
14
+ | Method | Path | Auth | Request | Response | Errors |
15
+ |--------|------|------|---------|----------|--------|
16
+
17
+ ## Business Rules
18
+
19
+ Numbered, testable, with source refs. Capture validations, conditionals, permission checks, status transitions, limits, and defaults.
20
+
21
+ - **BR-1:** A session cannot be booked when the coach has no connected calendar. (`src/services/x.js:42`)
22
+ - **BR-2:** ...
23
+
24
+ ## Data
25
+
26
+ Frontend: state used (slices/stores), key entities and their shapes as consumed.
27
+ Backend: models/schemas with fields, types, constraints, indexes, relations.
28
+
29
+ ## API Calls Consumed (frontend) / Dependencies (backend)
30
+
31
+ Frontend:
32
+
33
+ | Method | URL | Trigger (screen/action) | Payload | Response used for |
34
+ |--------|-----|-------------------------|---------|-------------------|
35
+
36
+ Backend: services/DBs/queues this module calls, with purpose.
37
+
38
+ ## Side Effects
39
+
40
+ Emails, notifications, jobs enqueued, events emitted, external API writes — with trigger condition and source ref.
41
+
42
+ ## Edge Cases & Gotchas
43
+
44
+ Non-obvious behavior a rebuilder would miss: race handling, retries, timezone logic, legacy quirks, feature flags.
45
+
46
+ ## Files Covered
47
+
48
+ Every assigned file, one per line. Required — the audit uses this list.
@@ -0,0 +1,38 @@
1
+ # SYSTEM — {workspace name}
2
+
3
+ **Purpose:** one paragraph — what the whole system does for whom.
4
+
5
+ ## Repo Map
6
+
7
+ | Repo | Kind | Role | Blueprint |
8
+ |------|------|------|-----------|
9
+
10
+ ## Cross-Service Flows
11
+
12
+ Trace the 3-6 core user journeys end to end. For each: numbered steps naming screen → endpoint → service → side effects.
13
+
14
+ ### Flow: {e.g. Coachee books a session}
15
+
16
+ 1. ...
17
+
18
+ ## Contract Table
19
+
20
+ Every HTTP call consumed vs the endpoint that exposes it.
21
+
22
+ | Consumer | Method | Path | Exposed by | Status |
23
+ |----------|--------|------|------------|--------|
24
+ | bonum-webapp | POST | /sessions | services--sessions | OK / MISSING / ORPHAN |
25
+
26
+ MISSING = consumed but no documented service exposes it. ORPHAN = exposed but no documented consumer (may be an unmapped client).
27
+
28
+ ## Auth Model
29
+
30
+ Identity provider, token flow, how each service validates, role/permission model.
31
+
32
+ ## Shared Integrations & Infra
33
+
34
+ External services (calendar, streaming, email...), who uses them, env vars per repo.
35
+
36
+ ## Gaps
37
+
38
+ Unresolved items from per-repo `_gaps.md` files plus MISSING/ORPHAN contracts, each with a one-line reason.