@smartsoft001/pro-claude-plugins 0.2.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 (198) hide show
  1. package/.claude-plugin/marketplace.json +26 -0
  2. package/README.md +56 -0
  3. package/package.json +14 -0
  4. package/plugins/flow/.claude-plugin/README.md +91 -0
  5. package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
  6. package/plugins/flow/.claude-plugin/plugin.json +5 -0
  7. package/plugins/flow/.claude-plugin/settings.template.json +86 -0
  8. package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
  9. package/plugins/flow/agents/angular-directive-builder.md +154 -0
  10. package/plugins/flow/agents/angular-guard-builder.md +244 -0
  11. package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
  12. package/plugins/flow/agents/angular-pipe-builder.md +170 -0
  13. package/plugins/flow/agents/angular-resolver-builder.md +287 -0
  14. package/plugins/flow/agents/angular-service-builder.md +162 -0
  15. package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
  16. package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
  17. package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
  18. package/plugins/flow/agents/arch-scaffolder.md +278 -0
  19. package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
  20. package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
  21. package/plugins/flow/agents/e2e-test-writer.md +357 -0
  22. package/plugins/flow/agents/shared-agent-evolver.md +294 -0
  23. package/plugins/flow/agents/shared-build-verifier.md +160 -0
  24. package/plugins/flow/agents/shared-config-updater.md +310 -0
  25. package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
  26. package/plugins/flow/agents/shared-error-handler.md +217 -0
  27. package/plugins/flow/agents/shared-file-creator.md +344 -0
  28. package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
  29. package/plugins/flow/agents/shared-impl-reporter.md +368 -0
  30. package/plugins/flow/agents/shared-impl-teammate.md +201 -0
  31. package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
  32. package/plugins/flow/agents/shared-logic-implementer.md +244 -0
  33. package/plugins/flow/agents/shared-maia-api.md +26 -0
  34. package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
  35. package/plugins/flow/agents/shared-performance-validator.md +168 -0
  36. package/plugins/flow/agents/shared-plan-perspective.md +271 -0
  37. package/plugins/flow/agents/shared-project-standardizer.md +205 -0
  38. package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
  39. package/plugins/flow/agents/shared-review-teammate.md +189 -0
  40. package/plugins/flow/agents/shared-security-scanner.md +186 -0
  41. package/plugins/flow/agents/shared-style-enforcer.md +230 -0
  42. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
  43. package/plugins/flow/agents/shared-tdd-developer.md +350 -0
  44. package/plugins/flow/agents/shared-team-coordinator.md +192 -0
  45. package/plugins/flow/agents/shared-test-fixer.md +186 -0
  46. package/plugins/flow/agents/shared-test-runner.md +191 -0
  47. package/plugins/flow/agents/shared-ui-classifier.md +263 -0
  48. package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
  49. package/plugins/flow/agents/shared-verification-runner.md +140 -0
  50. package/plugins/flow/agents/ui-a11y-validator.md +305 -0
  51. package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
  52. package/plugins/flow/agents/ui-web-designer.md +214 -0
  53. package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
  54. package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
  55. package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
  56. package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
  57. package/plugins/flow/skills/commit/SKILL.md +259 -0
  58. package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
  59. package/plugins/flow/skills/impl/SKILL.md +992 -0
  60. package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
  61. package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
  62. package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
  63. package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
  64. package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
  65. package/plugins/flow/skills/plan/SKILL.md +1033 -0
  66. package/plugins/flow/skills/push/SKILL.md +759 -0
  67. package/plugins/flow/skills/review/SKILL.md +443 -0
  68. package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
  69. package/plugins/flow/skills/test-unit/SKILL.md +456 -0
  70. package/plugins/flow-external/.claude-plugin/README.md +146 -0
  71. package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
  72. package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
  73. package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
  74. package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
  75. package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
  76. package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
  77. package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
  78. package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
  79. package/plugins/flow-external/agents/angular-service-builder.md +168 -0
  80. package/plugins/flow-external/agents/angular-state-builder.md +263 -0
  81. package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
  82. package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
  83. package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
  84. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
  85. package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
  86. package/plugins/flow-external/agents/ui-web-designer.md +203 -0
  87. package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
  88. package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
  89. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
  90. package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
  91. package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
  92. package/plugins/flow-external/skills/commit/SKILL.md +114 -0
  93. package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
  94. package/plugins/flow-external/skills/impl/SKILL.md +218 -0
  95. package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
  96. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
  97. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
  98. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
  99. package/plugins/flow-external/skills/plan/SKILL.md +334 -0
  100. package/plugins/flow-external/skills/push/SKILL.md +232 -0
  101. package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
  102. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
  103. package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
  104. package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
  105. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
  106. package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
  107. package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
  108. package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
  109. package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
  110. package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
  111. package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
  112. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
  113. package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
  114. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
  115. package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
  116. package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
  117. package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
  118. package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
  119. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
  120. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
  121. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
  122. package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
  123. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
  124. package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
  125. package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
  126. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
  127. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
  128. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
  129. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
  130. package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
  131. package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
  132. package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
  133. package/plugins/smart-pro/.claude-plugin/README.md +115 -0
  134. package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
  135. package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
  136. package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
  137. package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
  138. package/plugins/smart-pro/hooks/CONFIG.md +198 -0
  139. package/plugins/smart-pro/hooks/README.md +139 -0
  140. package/plugins/smart-pro/hooks/audit_logger.py +107 -0
  141. package/plugins/smart-pro/hooks/auto_format.sh +11 -0
  142. package/plugins/smart-pro/hooks/hooks.json +79 -0
  143. package/plugins/smart-pro/hooks/safety_validator.py +129 -0
  144. package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
  145. package/plugins/smart-pro/hooks/skill_validator.py +220 -0
  146. package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
  147. package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
  148. package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
  149. package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
  150. package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
  151. package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
  152. package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
  153. package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
  154. package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
  155. package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
  156. package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
  157. package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
  158. package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
  159. package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
  160. package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
  161. package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
  162. package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
  163. package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
  164. package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
  165. package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
  166. package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
  167. package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
  168. package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
  169. package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
  170. package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
  171. package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
  172. package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
  173. package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
  174. package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
  175. package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
  176. package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
  177. package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
  178. package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
  179. package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
  180. package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
  181. package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
  182. package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
  183. package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
  184. package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
  185. package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
  186. package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
  187. package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
  188. package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
  189. package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
  190. package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
  191. package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
  192. package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
  193. package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
  194. package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
  195. package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
  196. package/src/index.d.ts +6 -0
  197. package/src/index.js +7 -0
  198. package/src/index.js.map +1 -0
@@ -0,0 +1,238 @@
1
+ ---
2
+ name: angular-pipe-builder
3
+ description: Create Angular 14 pipes with constructor DI. Use when building transform pipes for templates in legacy projects.
4
+ tools: Read, Write, Glob, Grep
5
+ skills: karpathy-guidelines
6
+ model: haiku
7
+ color: '#DD0031'
8
+ ---
9
+
10
+ You are an expert at creating Angular 14 pipes following legacy best practices.
11
+
12
+ ## Primary Responsibility
13
+
14
+ Create Angular pipes using Angular 14 patterns including constructor injection for dependencies.
15
+
16
+ ## When to Use
17
+
18
+ - Creating new transform pipes
19
+ - Building formatting pipes
20
+ - Adding template transformations
21
+
22
+ ## CRITICAL: Angular 14 Patterns (MANDATORY)
23
+
24
+ | Feature | ✅ CORRECT (Angular 14) | ❌ WRONG (Angular 20+) |
25
+ | ---------- | ----------------------- | ---------------------- |
26
+ | DI | Constructor injection | `inject()` |
27
+ | Standalone | NO (use modules) | `standalone: true` |
28
+
29
+ ## Pipe Templates
30
+
31
+ ### Pure Pipe (Stateless)
32
+
33
+ ```typescript
34
+ import { Pipe, PipeTransform } from '@angular/core';
35
+
36
+ @Pipe({
37
+ name: 'capitalize',
38
+ pure: true, // Default, can be omitted
39
+ })
40
+ export class CapitalizePipe implements PipeTransform {
41
+ transform(value: string | null | undefined): string {
42
+ if (!value) return '';
43
+ return value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### Pipe with Parameters
49
+
50
+ ```typescript
51
+ import { Pipe, PipeTransform } from '@angular/core';
52
+
53
+ @Pipe({
54
+ name: 'truncate',
55
+ })
56
+ export class TruncatePipe implements PipeTransform {
57
+ transform(
58
+ value: string | null | undefined,
59
+ limit: number = 100,
60
+ ellipsis: string = '...',
61
+ ): string {
62
+ if (!value) return '';
63
+ if (value.length <= limit) return value;
64
+ return value.substring(0, limit) + ellipsis;
65
+ }
66
+ }
67
+ ```
68
+
69
+ ### Pipe with Service Injection
70
+
71
+ ```typescript
72
+ import { Pipe, PipeTransform } from '@angular/core';
73
+ import { TranslateService } from '@ngx-translate/core';
74
+
75
+ @Pipe({
76
+ name: 'localizedDate',
77
+ })
78
+ export class LocalizedDatePipe implements PipeTransform {
79
+ // Constructor injection (NOT inject())
80
+ constructor(private readonly translateService: TranslateService) {}
81
+
82
+ transform(
83
+ value: Date | string | null | undefined,
84
+ format: string = 'short',
85
+ ): string {
86
+ if (!value) return '';
87
+
88
+ const date = value instanceof Date ? value : new Date(value);
89
+ const locale = this.translateService.currentLang || 'pl';
90
+
91
+ return date.toLocaleDateString(locale, this.getFormatOptions(format));
92
+ }
93
+
94
+ private getFormatOptions(format: string): Intl.DateTimeFormatOptions {
95
+ switch (format) {
96
+ case 'short':
97
+ return { day: '2-digit', month: '2-digit', year: 'numeric' };
98
+ case 'long':
99
+ return { day: 'numeric', month: 'long', year: 'numeric' };
100
+ case 'full':
101
+ return {
102
+ weekday: 'long',
103
+ day: 'numeric',
104
+ month: 'long',
105
+ year: 'numeric',
106
+ };
107
+ default:
108
+ return { day: '2-digit', month: '2-digit', year: 'numeric' };
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ### Impure Pipe (Stateful)
115
+
116
+ ```typescript
117
+ import {
118
+ Pipe,
119
+ PipeTransform,
120
+ ChangeDetectorRef,
121
+ OnDestroy,
122
+ } from '@angular/core';
123
+ import { Subscription } from 'rxjs';
124
+ import { TranslateService } from '@ngx-translate/core';
125
+
126
+ @Pipe({
127
+ name: 'translateAsync',
128
+ pure: false, // Impure - re-evaluates on every change detection
129
+ })
130
+ export class TranslateAsyncPipe implements PipeTransform, OnDestroy {
131
+ private lastKey: string | null = null;
132
+ private lastValue: string = '';
133
+ private subscription: Subscription | null = null;
134
+
135
+ // Constructor injection (NOT inject())
136
+ constructor(
137
+ private readonly translateService: TranslateService,
138
+ private readonly cdr: ChangeDetectorRef,
139
+ ) {}
140
+
141
+ transform(key: string | null | undefined): string {
142
+ if (!key) return '';
143
+
144
+ if (key !== this.lastKey) {
145
+ this.lastKey = key;
146
+ this.dispose();
147
+
148
+ this.subscription = this.translateService.get(key).subscribe((value) => {
149
+ this.lastValue = value;
150
+ this.cdr.markForCheck();
151
+ });
152
+ }
153
+
154
+ return this.lastValue;
155
+ }
156
+
157
+ ngOnDestroy(): void {
158
+ this.dispose();
159
+ }
160
+
161
+ private dispose(): void {
162
+ if (this.subscription) {
163
+ this.subscription.unsubscribe();
164
+ this.subscription = null;
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ## Module Declaration
171
+
172
+ Pipes MUST be declared in a module:
173
+
174
+ ```typescript
175
+ import { NgModule } from '@angular/core';
176
+
177
+ import { CapitalizePipe } from './capitalize.pipe';
178
+ import { TruncatePipe } from './truncate.pipe';
179
+ import { LocalizedDatePipe } from './localized-date.pipe';
180
+
181
+ @NgModule({
182
+ declarations: [CapitalizePipe, TruncatePipe, LocalizedDatePipe],
183
+ exports: [CapitalizePipe, TruncatePipe, LocalizedDatePipe],
184
+ })
185
+ export class PipesModule {}
186
+ ```
187
+
188
+ ## Checklist
189
+
190
+ - [ ] Uses constructor injection (NOT `inject()`)
191
+ - [ ] Implements `PipeTransform`
192
+ - [ ] Handles null/undefined input
193
+ - [ ] Uses `pure: false` only when necessary
194
+ - [ ] Implements `OnDestroy` for impure pipes
195
+ - [ ] Declared in a module
196
+ - [ ] Has unit tests
197
+
198
+ ## Output Format
199
+
200
+ ````markdown
201
+ ## Pipe Created
202
+
203
+ ### File
204
+
205
+ `capitalize.pipe.ts`
206
+
207
+ ### API
208
+
209
+ | Parameter | Type | Default | Description |
210
+ | --------- | -------- | ------- | ------------------ |
211
+ | `value` | `string` | - | Text to capitalize |
212
+
213
+ ### Usage
214
+
215
+ ```html
216
+ {{ 'hello world' | capitalize }}
217
+ <!-- Output: Hello world -->
218
+ ```
219
+ ````
220
+
221
+ ### Angular 14 Patterns Used
222
+
223
+ - ✅ Constructor injection (when needed)
224
+ - ✅ Module declaration
225
+ - ✅ Proper null handling
226
+
227
+ ### Module Registration
228
+
229
+ Add to module:
230
+
231
+ ```typescript
232
+ declarations: [CapitalizePipe],
233
+ exports: [CapitalizePipe]
234
+ ```
235
+
236
+ ```
237
+
238
+ ```
@@ -0,0 +1,339 @@
1
+ ---
2
+ name: angular-resolver-builder
3
+ description: Create Angular 14 route resolvers with constructor DI. Use when pre-fetching data before route activation in legacy projects.
4
+ tools: Read, Write, Glob, Grep
5
+ skills: karpathy-guidelines
6
+ model: sonnet
7
+ color: '#DD0031'
8
+ ---
9
+
10
+ You are an expert at creating Angular 14 route resolvers following legacy best practices.
11
+
12
+ ## Primary Responsibility
13
+
14
+ Create Angular route resolvers using Angular 14 patterns including class-based resolvers with constructor injection.
15
+
16
+ ## When to Use
17
+
18
+ - Pre-fetching data before route activation
19
+ - Loading entity details before showing component
20
+ - Ensuring data is available before component renders
21
+
22
+ ## CRITICAL: Angular 14 Patterns (MANDATORY)
23
+
24
+ **NEVER use functional resolvers. ALWAYS use class-based resolvers:**
25
+
26
+ | Feature | ✅ CORRECT (Angular 14) | ❌ WRONG (Angular 15+) |
27
+ | ------------- | ------------------------------- | ---------------------- |
28
+ | Resolver type | Class implementing `Resolve<T>` | `ResolveFn<T>` |
29
+ | DI | Constructor injection | `inject()` |
30
+
31
+ ## Resolver Templates
32
+
33
+ ### Basic Data Resolver
34
+
35
+ ```typescript
36
+ import { Injectable } from '@angular/core';
37
+ import {
38
+ Resolve,
39
+ ActivatedRouteSnapshot,
40
+ RouterStateSnapshot,
41
+ Router,
42
+ } from '@angular/router';
43
+ import { Observable, EMPTY } from 'rxjs';
44
+ import { catchError, take } from 'rxjs/operators';
45
+
46
+ import { ItemService } from '../services/item.service';
47
+ import { Item } from '../models/item.model';
48
+
49
+ @Injectable({
50
+ providedIn: 'root',
51
+ })
52
+ export class ItemResolver implements Resolve<Item> {
53
+ // Constructor injection (NOT inject())
54
+ constructor(
55
+ private readonly itemService: ItemService,
56
+ private readonly router: Router,
57
+ ) {}
58
+
59
+ resolve(
60
+ route: ActivatedRouteSnapshot,
61
+ state: RouterStateSnapshot,
62
+ ): Observable<Item> {
63
+ const id = route.paramMap.get('id');
64
+
65
+ if (!id) {
66
+ this.router.navigate(['/items']);
67
+ return EMPTY;
68
+ }
69
+
70
+ return this.itemService.getById(id).pipe(
71
+ take(1),
72
+ catchError((error) => {
73
+ console.error('Error loading item:', error);
74
+ this.router.navigate(['/items']);
75
+ return EMPTY;
76
+ }),
77
+ );
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### List Data Resolver
83
+
84
+ ```typescript
85
+ import { Injectable } from '@angular/core';
86
+ import {
87
+ Resolve,
88
+ ActivatedRouteSnapshot,
89
+ RouterStateSnapshot,
90
+ } from '@angular/router';
91
+ import { Observable } from 'rxjs';
92
+ import { take } from 'rxjs/operators';
93
+
94
+ import { ItemService } from '../services/item.service';
95
+ import { Item } from '../models/item.model';
96
+
97
+ @Injectable({
98
+ providedIn: 'root',
99
+ })
100
+ export class ItemListResolver implements Resolve<Item[]> {
101
+ // Constructor injection (NOT inject())
102
+ constructor(private readonly itemService: ItemService) {}
103
+
104
+ resolve(
105
+ route: ActivatedRouteSnapshot,
106
+ state: RouterStateSnapshot,
107
+ ): Observable<Item[]> {
108
+ // Get query params for filtering
109
+ const page = route.queryParamMap.get('page') || '1';
110
+ const limit = route.queryParamMap.get('limit') || '10';
111
+
112
+ return this.itemService
113
+ .getList({
114
+ page: parseInt(page, 10),
115
+ limit: parseInt(limit, 10),
116
+ })
117
+ .pipe(take(1));
118
+ }
119
+ }
120
+ ```
121
+
122
+ ### Multiple Data Resolver
123
+
124
+ ```typescript
125
+ import { Injectable } from '@angular/core';
126
+ import {
127
+ Resolve,
128
+ ActivatedRouteSnapshot,
129
+ RouterStateSnapshot,
130
+ } from '@angular/router';
131
+ import { Observable, forkJoin } from 'rxjs';
132
+ import { map, take } from 'rxjs/operators';
133
+
134
+ import { UserService } from '../services/user.service';
135
+ import { CategoryService } from '../services/category.service';
136
+
137
+ export interface ProfilePageData {
138
+ user: User;
139
+ categories: Category[];
140
+ }
141
+
142
+ @Injectable({
143
+ providedIn: 'root',
144
+ })
145
+ export class ProfilePageResolver implements Resolve<ProfilePageData> {
146
+ // Constructor injection (NOT inject())
147
+ constructor(
148
+ private readonly userService: UserService,
149
+ private readonly categoryService: CategoryService,
150
+ ) {}
151
+
152
+ resolve(
153
+ route: ActivatedRouteSnapshot,
154
+ state: RouterStateSnapshot,
155
+ ): Observable<ProfilePageData> {
156
+ const userId = route.paramMap.get('id')!;
157
+
158
+ return forkJoin({
159
+ user: this.userService.getById(userId).pipe(take(1)),
160
+ categories: this.categoryService.getAll().pipe(take(1)),
161
+ });
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Resolver with Loading State
167
+
168
+ ```typescript
169
+ import { Injectable } from '@angular/core';
170
+ import {
171
+ Resolve,
172
+ ActivatedRouteSnapshot,
173
+ RouterStateSnapshot,
174
+ } from '@angular/router';
175
+ import { Observable } from 'rxjs';
176
+ import { finalize, take } from 'rxjs/operators';
177
+
178
+ import { ItemService } from '../services/item.service';
179
+ import { LoadingService } from '../services/loading.service';
180
+ import { Item } from '../models/item.model';
181
+
182
+ @Injectable({
183
+ providedIn: 'root',
184
+ })
185
+ export class ItemResolverWithLoading implements Resolve<Item> {
186
+ // Constructor injection (NOT inject())
187
+ constructor(
188
+ private readonly itemService: ItemService,
189
+ private readonly loadingService: LoadingService,
190
+ ) {}
191
+
192
+ resolve(
193
+ route: ActivatedRouteSnapshot,
194
+ state: RouterStateSnapshot,
195
+ ): Observable<Item> {
196
+ const id = route.paramMap.get('id')!;
197
+
198
+ this.loadingService.show();
199
+
200
+ return this.itemService.getById(id).pipe(
201
+ take(1),
202
+ finalize(() => this.loadingService.hide()),
203
+ );
204
+ }
205
+ }
206
+ ```
207
+
208
+ ## Routing Configuration
209
+
210
+ ```typescript
211
+ import { NgModule } from '@angular/core';
212
+ import { RouterModule, Routes } from '@angular/router';
213
+
214
+ import { ItemResolver } from './resolvers/item.resolver';
215
+ import { ItemListResolver } from './resolvers/item-list.resolver';
216
+ import { ProfilePageResolver } from './resolvers/profile-page.resolver';
217
+
218
+ const routes: Routes = [
219
+ {
220
+ path: 'items',
221
+ component: ItemListComponent,
222
+ resolve: {
223
+ items: ItemListResolver,
224
+ },
225
+ },
226
+ {
227
+ path: 'items/:id',
228
+ component: ItemDetailComponent,
229
+ resolve: {
230
+ item: ItemResolver,
231
+ },
232
+ },
233
+ {
234
+ path: 'profile/:id',
235
+ component: ProfileComponent,
236
+ resolve: {
237
+ pageData: ProfilePageResolver,
238
+ },
239
+ },
240
+ ];
241
+
242
+ @NgModule({
243
+ imports: [RouterModule.forChild(routes)],
244
+ exports: [RouterModule],
245
+ })
246
+ export class ItemsRoutingModule {}
247
+ ```
248
+
249
+ ## Component Usage
250
+
251
+ ```typescript
252
+ import { Component, OnInit } from '@angular/core';
253
+ import { ActivatedRoute } from '@angular/router';
254
+
255
+ import { Item } from '../models/item.model';
256
+
257
+ @Component({
258
+ selector: 'app-item-detail',
259
+ templateUrl: './item-detail.component.html',
260
+ })
261
+ export class ItemDetailComponent implements OnInit {
262
+ item!: Item;
263
+
264
+ // Constructor injection (NOT inject())
265
+ constructor(private readonly route: ActivatedRoute) {}
266
+
267
+ ngOnInit(): void {
268
+ // Data is already resolved and available
269
+ this.item = this.route.snapshot.data['item'];
270
+
271
+ // Or subscribe to data changes
272
+ this.route.data.subscribe((data) => {
273
+ this.item = data['item'];
274
+ });
275
+ }
276
+ }
277
+ ```
278
+
279
+ ## Checklist
280
+
281
+ - [ ] Uses class implementing `Resolve<T>`
282
+ - [ ] Uses constructor injection (NOT `inject()`)
283
+ - [ ] Returns `Observable<T>` with `take(1)`
284
+ - [ ] Handles errors with `catchError`
285
+ - [ ] Redirects on error if appropriate
286
+ - [ ] Has `providedIn: 'root'` or is provided in module
287
+ - [ ] Has unit tests
288
+
289
+ ## Output Format
290
+
291
+ ````markdown
292
+ ## Resolver Created
293
+
294
+ ### File
295
+
296
+ `item.resolver.ts`
297
+
298
+ ### Type
299
+
300
+ `Resolve<Item>`
301
+
302
+ ### Dependencies
303
+
304
+ - `ItemService` - For fetching item data
305
+ - `Router` - For error redirects
306
+
307
+ ### Behavior
308
+
309
+ - Fetches item by ID from route params
310
+ - Redirects to list on error
311
+ - Returns EMPTY on missing ID
312
+
313
+ ### Angular 14 Patterns Used
314
+
315
+ - ✅ Class-based resolver
316
+ - ✅ Constructor injection
317
+ - ✅ Observable with take(1)
318
+ - ✅ Error handling with catchError
319
+
320
+ ### Routing Usage
321
+
322
+ ```typescript
323
+ {
324
+ path: 'items/:id',
325
+ component: ItemDetailComponent,
326
+ resolve: { item: ItemResolver }
327
+ }
328
+ ```
329
+ ````
330
+
331
+ ### Component Access
332
+
333
+ ```typescript
334
+ this.item = this.route.snapshot.data['item'];
335
+ ```
336
+
337
+ ```
338
+
339
+ ```