@smartsoft001-mobilems/claude-plugins 2.84.0 → 2.86.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 (136) hide show
  1. package/.claude-plugin/marketplace.json +2 -6
  2. package/README.md +97 -0
  3. package/package.json +2 -2
  4. package/plugins/flow/scripts/refresh-mobilems-api-spec.sh +372 -0
  5. package/plugins/flow/skills/mobilems-docs-reader/SKILL.md +116 -0
  6. package/plugins/flow-external/scripts/refresh-mobilems-api-spec.sh +372 -0
  7. package/plugins/flow-external/skills/mobilems-docs-reader/SKILL.md +116 -0
  8. package/plugins/flow-legacy/scripts/refresh-mobilems-api-spec.sh +372 -0
  9. package/plugins/flow-legacy/skills/mobilems-docs-reader/SKILL.md +116 -0
  10. package/plugins/mobilems/.claude-plugin/README.md +30 -0
  11. package/plugins/mobilems/.claude-plugin/plugin.json +5 -0
  12. package/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh +372 -0
  13. package/plugins/mobilems/skills/mobilems-docs-reader/SKILL.md +116 -0
  14. package/plugins/flow/.claude-plugin/README.md +0 -91
  15. package/plugins/flow/.claude-plugin/merge-permissions.js +0 -97
  16. package/plugins/flow/.claude-plugin/plugin.json +0 -5
  17. package/plugins/flow/.claude-plugin/settings.template.json +0 -86
  18. package/plugins/flow/agents/angular-component-scaffolder.md +0 -175
  19. package/plugins/flow/agents/angular-directive-builder.md +0 -153
  20. package/plugins/flow/agents/angular-guard-builder.md +0 -243
  21. package/plugins/flow/agents/angular-jest-test-writer.md +0 -474
  22. package/plugins/flow/agents/angular-pipe-builder.md +0 -169
  23. package/plugins/flow/agents/angular-resolver-builder.md +0 -286
  24. package/plugins/flow/agents/angular-service-builder.md +0 -161
  25. package/plugins/flow/agents/angular-signal-state-builder.md +0 -339
  26. package/plugins/flow/agents/angular-test-diagnostician.md +0 -279
  27. package/plugins/flow/agents/angular-testbed-configurator.md +0 -315
  28. package/plugins/flow/agents/arch-scaffolder.md +0 -278
  29. package/plugins/flow/agents/e2e-data-testid-injector.md +0 -197
  30. package/plugins/flow/agents/e2e-project-scaffolder.md +0 -194
  31. package/plugins/flow/agents/e2e-test-writer.md +0 -350
  32. package/plugins/flow/agents/shared-agent-evolver.md +0 -294
  33. package/plugins/flow/agents/shared-build-verifier.md +0 -160
  34. package/plugins/flow/agents/shared-config-updater.md +0 -310
  35. package/plugins/flow/agents/shared-coverage-enforcer.md +0 -184
  36. package/plugins/flow/agents/shared-error-handler.md +0 -217
  37. package/plugins/flow/agents/shared-file-creator.md +0 -344
  38. package/plugins/flow/agents/shared-impl-orchestrator.md +0 -312
  39. package/plugins/flow/agents/shared-impl-reporter.md +0 -339
  40. package/plugins/flow/agents/shared-impl-teammate.md +0 -201
  41. package/plugins/flow/agents/shared-linear-subtask-iterator.md +0 -337
  42. package/plugins/flow/agents/shared-logic-implementer.md +0 -243
  43. package/plugins/flow/agents/shared-maia-api.md +0 -26
  44. package/plugins/flow/agents/shared-parallelization-analyzer.md +0 -343
  45. package/plugins/flow/agents/shared-performance-validator.md +0 -168
  46. package/plugins/flow/agents/shared-plan-perspective.md +0 -269
  47. package/plugins/flow/agents/shared-project-standardizer.md +0 -205
  48. package/plugins/flow/agents/shared-report-synthesizer.md +0 -188
  49. package/plugins/flow/agents/shared-review-teammate.md +0 -189
  50. package/plugins/flow/agents/shared-security-scanner.md +0 -186
  51. package/plugins/flow/agents/shared-style-enforcer.md +0 -230
  52. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +0 -188
  53. package/plugins/flow/agents/shared-tdd-developer.md +0 -350
  54. package/plugins/flow/agents/shared-team-coordinator.md +0 -189
  55. package/plugins/flow/agents/shared-test-fixer.md +0 -186
  56. package/plugins/flow/agents/shared-test-runner.md +0 -191
  57. package/plugins/flow/agents/shared-ui-classifier.md +0 -263
  58. package/plugins/flow/agents/shared-verification-orchestrator.md +0 -194
  59. package/plugins/flow/agents/shared-verification-runner.md +0 -140
  60. package/plugins/flow/agents/ui-a11y-validator.md +0 -305
  61. package/plugins/flow/agents/ui-screenshot-reporter.md +0 -329
  62. package/plugins/flow/agents/ui-web-designer.md +0 -214
  63. package/plugins/flow/skills/a11y-audit/SKILL.md +0 -214
  64. package/plugins/flow/skills/angular-patterns/SKILL.md +0 -191
  65. package/plugins/flow/skills/browser-capture/SKILL.md +0 -238
  66. package/plugins/flow/skills/commit/SKILL.md +0 -259
  67. package/plugins/flow/skills/debug-helper/SKILL.md +0 -375
  68. package/plugins/flow/skills/impl/SKILL.md +0 -992
  69. package/plugins/flow/skills/linear-suggestion/SKILL.md +0 -132
  70. package/plugins/flow/skills/maia-files-delete/SKILL.md +0 -59
  71. package/plugins/flow/skills/maia-files-upload/SKILL.md +0 -57
  72. package/plugins/flow/skills/nx-conventions/SKILL.md +0 -326
  73. package/plugins/flow/skills/plan/SKILL.md +0 -1003
  74. package/plugins/flow/skills/push/SKILL.md +0 -737
  75. package/plugins/flow/skills/review/SKILL.md +0 -443
  76. package/plugins/flow/skills/test-e2e/SKILL.md +0 -161
  77. package/plugins/flow/skills/test-unit/SKILL.md +0 -456
  78. package/plugins/flow-external/.claude-plugin/README.md +0 -152
  79. package/plugins/flow-external/.claude-plugin/merge-permissions.js +0 -80
  80. package/plugins/flow-external/.claude-plugin/plugin.json +0 -5
  81. package/plugins/flow-external/.claude-plugin/settings.template.json +0 -78
  82. package/plugins/flow-external/agents/angular-component-scaffolder.md +0 -269
  83. package/plugins/flow-external/agents/angular-directive-builder.md +0 -130
  84. package/plugins/flow-external/agents/angular-guard-builder.md +0 -70
  85. package/plugins/flow-external/agents/angular-pipe-builder.md +0 -82
  86. package/plugins/flow-external/agents/angular-resolver-builder.md +0 -74
  87. package/plugins/flow-external/agents/angular-service-builder.md +0 -160
  88. package/plugins/flow-external/agents/angular-state-builder.md +0 -254
  89. package/plugins/flow-external/agents/shared-build-verifier.md +0 -67
  90. package/plugins/flow-external/agents/shared-impl-orchestrator.md +0 -88
  91. package/plugins/flow-external/agents/shared-impl-reporter.md +0 -107
  92. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +0 -70
  93. package/plugins/flow-external/agents/shared-ui-classifier.md +0 -38
  94. package/plugins/flow-external/agents/ui-web-designer.md +0 -179
  95. package/plugins/flow-external/skills/a11y-audit/SKILL.md +0 -96
  96. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +0 -267
  97. package/plugins/flow-external/skills/angular-patterns/SKILL.md +0 -170
  98. package/plugins/flow-external/skills/browser-capture/SKILL.md +0 -68
  99. package/plugins/flow-external/skills/commit/SKILL.md +0 -114
  100. package/plugins/flow-external/skills/debug-helper/SKILL.md +0 -131
  101. package/plugins/flow-external/skills/impl/SKILL.md +0 -217
  102. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +0 -62
  103. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +0 -34
  104. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +0 -41
  105. package/plugins/flow-external/skills/plan/SKILL.md +0 -302
  106. package/plugins/flow-external/skills/push/SKILL.md +0 -210
  107. package/plugins/flow-legacy/.claude-plugin/README.md +0 -143
  108. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +0 -94
  109. package/plugins/flow-legacy/.claude-plugin/plugin.json +0 -5
  110. package/plugins/flow-legacy/.claude-plugin/settings.template.json +0 -79
  111. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +0 -323
  112. package/plugins/flow-legacy/agents/angular-directive-builder.md +0 -258
  113. package/plugins/flow-legacy/agents/angular-guard-builder.md +0 -322
  114. package/plugins/flow-legacy/agents/angular-pipe-builder.md +0 -227
  115. package/plugins/flow-legacy/agents/angular-resolver-builder.md +0 -332
  116. package/plugins/flow-legacy/agents/angular-service-builder.md +0 -271
  117. package/plugins/flow-legacy/agents/angular-state-builder.md +0 -479
  118. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +0 -174
  119. package/plugins/flow-legacy/agents/shared-impl-reporter.md +0 -204
  120. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +0 -187
  121. package/plugins/flow-legacy/agents/shared-tdd-developer.md +0 -306
  122. package/plugins/flow-legacy/agents/shared-test-runner.md +0 -131
  123. package/plugins/flow-legacy/agents/shared-ui-classifier.md +0 -145
  124. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +0 -214
  125. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +0 -346
  126. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +0 -238
  127. package/plugins/flow-legacy/skills/commit/SKILL.md +0 -215
  128. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +0 -395
  129. package/plugins/flow-legacy/skills/impl/SKILL.md +0 -710
  130. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +0 -132
  131. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +0 -59
  132. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +0 -57
  133. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +0 -368
  134. package/plugins/flow-legacy/skills/plan/SKILL.md +0 -708
  135. package/plugins/flow-legacy/skills/push/SKILL.md +0 -623
  136. package/plugins/flow-legacy/skills/test-unit/SKILL.md +0 -500
@@ -1,86 +0,0 @@
1
- {
2
- "$schema": "https://raw.githubusercontent.com/anthropics/claude-code/main/schemas/settings.schema.json",
3
- "_description": "Template permissions for flow@mobilems plugin. Merge these into your project's .claude/settings.json",
4
- "permissions": {
5
- "allow": [
6
- "Bash(git status:*)",
7
- "Bash(git diff:*)",
8
- "Bash(git log:*)",
9
- "Bash(git show:*)",
10
- "Bash(git add:*)",
11
- "Bash(git fetch:*)",
12
- "Bash(git pull:*)",
13
- "Bash(gh run list:*)",
14
- "Bash(gh run view:*)",
15
- "Bash(gh pr list:*)",
16
- "Bash(nx:*)",
17
- "Bash(npx nx:*)",
18
- "Bash(npx tsc:*)",
19
- "Bash(npm start)",
20
- "Bash(npm run format:*)",
21
- "Bash(npm audit:*)",
22
- "Bash(npm install:*)",
23
- "Bash(source:*)",
24
- "Bash(nvm use:*)",
25
- "Bash(curl:*)",
26
- "Bash(lsof:*)",
27
- "Bash(ls:*)",
28
- "Bash(find:*)",
29
- "Bash(grep:*)",
30
- "Bash(xargs:*)",
31
- "Bash(sleep:*)",
32
- "Bash(rm:*)",
33
- "Bash(test:*)",
34
- "Bash(for:*)",
35
- "Bash(node:*)",
36
- "Bash(mkdir:*)",
37
- "mcp__linear__get_issue",
38
- "mcp__linear__list_issues",
39
- "mcp__linear__list_comments",
40
- "mcp__linear__save_comment",
41
- "mcp__linear__delete_comment",
42
- "mcp__linear__save_issue",
43
- "mcp__linear__list_issue_statuses",
44
- "mcp__linear__create_attachment",
45
- "mcp__linear__get_attachment",
46
- "mcp__linear__delete_attachment",
47
- "mcp__linear__list_issue_labels",
48
- "mcp__playwright__browser_snapshot",
49
- "mcp__playwright__browser_take_screenshot",
50
- "mcp__playwright__browser_navigate",
51
- "mcp__playwright__browser_close",
52
- "mcp__playwright__browser_wait_for",
53
- "mcp__playwright__browser_click",
54
- "mcp__playwright__browser_resize",
55
- "mcp__playwright__browser_evaluate",
56
- "mcp__playwright__browser_console_messages",
57
- "mcp__playwright__browser_press_key",
58
- "mcp__playwright__browser_network_requests",
59
- "Skill(flow:maia-files-upload)",
60
- "Skill(flow:maia-files-delete)",
61
- "Skill(flow:browser-capture)",
62
- "Skill(flow:linear-suggestion)",
63
- "Skill(flow:test-unit)",
64
- "Skill(flow:a11y-audit)",
65
- "Skill(flow:test-e2e)",
66
- "Skill(flow:review)",
67
- "Bash(npx playwright:*)"
68
- ],
69
- "ask": [
70
- "Skill(flow:commit)",
71
- "Skill(flow:impl)",
72
- "Skill(flow:plan)",
73
- "Skill(flow:push)",
74
- "Skill(flow:review)",
75
- "Bash(git commit:*)",
76
- "Bash(git push:*)",
77
- "Bash(gh pr create:*)"
78
- ]
79
- },
80
- "enabledPlugins": {
81
- "flow@mobilems": true
82
- },
83
- "env": {
84
- "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
85
- }
86
- }
@@ -1,175 +0,0 @@
1
- ---
2
- name: angular-component-scaffolder
3
- description: Create Angular standalone components with signals and modern patterns. Use when scaffolding new components following Angular 20+ best practices.
4
- tools: Read, Write, Glob, Grep
5
- model: sonnet
6
- color: "#DD0031"
7
- ---
8
-
9
- You are an expert at creating Angular standalone components following modern best practices.
10
-
11
- ## Primary Responsibility
12
-
13
- Create Angular components using Angular 20+ patterns including signals, standalone architecture, and modern control flow.
14
-
15
- ## When to Use
16
-
17
- - Creating new Angular components
18
- - Scaffolding component structure with template and styles
19
- - Setting up component with proper DI using inject()
20
-
21
- ## Project-Specific Patterns
22
-
23
- This project uses:
24
-
25
- - **No explicit `standalone: true`** - Angular 19+ defaults to standalone
26
- - **TranslatePipe** from `@ngx-translate/core` for i18n
27
- - **CapitalizePipe** from project pipes
28
- - **Tailwind CSS** with `smart-` prefix
29
-
30
- ## Component Template
31
-
32
- ### Basic Component
33
-
34
- ```typescript
35
- import { Component, signal, computed, inject } from '@angular/core';
36
- import { TranslatePipe } from '@ngx-translate/core';
37
-
38
- import { CapitalizePipe } from '../../pipes';
39
-
40
- @Component({
41
- selector: 'app-feature-name',
42
- imports: [TranslatePipe, CapitalizePipe],
43
- templateUrl: './feature-name.component.html',
44
- })
45
- export class FeatureNameComponent {
46
- // Injected services (at top)
47
- private readonly dataService = inject(DataService);
48
-
49
- // Signals for local state
50
- readonly isLoading = signal(false);
51
- readonly data = signal<DataType[]>([]);
52
-
53
- // Computed values for derived state
54
- readonly itemCount = computed(() => this.data().length);
55
- readonly hasData = computed(() => this.data().length > 0);
56
- }
57
- ```
58
-
59
- ### Component with Inputs/Outputs
60
-
61
- ```typescript
62
- import { Component, input, output, model, signal } from '@angular/core';
63
- import { TranslatePipe } from '@ngx-translate/core';
64
-
65
- import { CapitalizePipe } from '../../pipes';
66
-
67
- @Component({
68
- selector: 'app-item-card',
69
- imports: [TranslatePipe, CapitalizePipe],
70
- templateUrl: './item-card.component.html',
71
- })
72
- export class ItemCardComponent {
73
- // Required inputs
74
- label = input.required<string>();
75
- item = input.required<Item>();
76
-
77
- // Optional input with default
78
- showActions = input<boolean>(true);
79
-
80
- // Input with transform
81
- page = input<number, number>(1, {
82
- transform: (val: number) => (val < 1 ? 1 : val),
83
- });
84
-
85
- // Output events
86
- selected = output<Item>();
87
- closed = output();
88
-
89
- // Two-way binding (model)
90
- searchText = model<string>('');
91
-
92
- // Internal signals
93
- isOpen = signal(false);
94
-
95
- // Methods
96
- toggleDropdown(force?: boolean) {
97
- this.isOpen.update((val) => force ?? !val);
98
- }
99
- }
100
- ```
101
-
102
- ## Template Patterns
103
-
104
- ### Modern Control Flow
105
-
106
- ```html
107
- @if (isLoading()) {
108
- <app-spinner />
109
- } @else if (error()) {
110
- <app-error [message]="error()?.message" />
111
- } @else {
112
- <div class="smart-grid smart-gap-4">
113
- @for (item of items(); track item.id) {
114
- <app-item-card [item]="item" (selected)="onSelect($event)" />
115
- } @empty {
116
- <p class="smart-text-gray-500">
117
- {{ 'COMMON.noItems' | translate | capitalize }}
118
- </p>
119
- }
120
- </div>
121
- }
122
- ```
123
-
124
- ## File Structure
125
-
126
- ```
127
- feature-name/
128
- feature-name.component.ts # Component class
129
- feature-name.component.html # Template
130
- feature-name.component.scss # Styles (optional)
131
- ```
132
-
133
- ## Scaffolding Checklist
134
-
135
- - [ ] NO `standalone: true` (Angular 19+ default)
136
- - [ ] Uses `inject()` for DI at top of class
137
- - [ ] Uses `signal()` for internal state
138
- - [ ] Uses `computed()` for derived values
139
- - [ ] Uses `input()`/`input.required()` for inputs
140
- - [ ] Uses `output()` for outputs
141
- - [ ] Uses `model()` for two-way binding
142
- - [ ] Uses `@if`/`@for` in template
143
- - [ ] Has `track` in all `@for` loops
144
- - [ ] Imports `TranslatePipe` if using translations
145
- - [ ] Imports `CapitalizePipe` if capitalizing text
146
- - [ ] Tailwind classes with `smart-` prefix
147
-
148
- ## Output Format
149
-
150
- ```markdown
151
- ## Component Scaffolded
152
-
153
- ### Files Created
154
-
155
- | File | Purpose |
156
- | ----------------------------- | --------------- |
157
- | `feature-name.component.ts` | Component class |
158
- | `feature-name.component.html` | Template |
159
-
160
- ### Component API
161
-
162
- **Inputs:**
163
-
164
- - `item: Item` (required)
165
- - `showActions: boolean` (default: true)
166
-
167
- **Outputs:**
168
-
169
- - `selected: Item`
170
-
171
- ### Next Steps
172
-
173
- 1. Implement component logic
174
- 2. Add to routing or parent component
175
- ```
@@ -1,153 +0,0 @@
1
- ---
2
- name: angular-directive-builder
3
- description: Create Angular standalone directives. Use when building attribute or structural directives.
4
- tools: Read, Write, Glob, Grep
5
- model: sonnet
6
- color: "#DD0031"
7
- ---
8
-
9
- You are an expert at creating Angular directives following modern best practices.
10
-
11
- ## Primary Responsibility
12
-
13
- Create Angular directives using modern patterns including `input()`, `inject()`, and standalone architecture.
14
-
15
- ## When to Use
16
-
17
- - Creating attribute directives
18
- - Building structural directives
19
- - Adding behavior to existing elements
20
-
21
- ## Project-Specific Patterns
22
-
23
- This project uses:
24
-
25
- - **`standalone: true`** explicitly for directives (for clarity)
26
- - **`inject()`** for dependency injection
27
- - **`input()`** for directive inputs
28
- - **`@HostListener`** for event handling
29
- - **`ElementRef`** via inject for DOM access
30
-
31
- ## Directive Template
32
-
33
- ### Attribute Directive
34
-
35
- ```typescript
36
- import {
37
- Directive,
38
- ElementRef,
39
- HostListener,
40
- inject,
41
- input,
42
- } from '@angular/core';
43
- import { TranslateService } from '@ngx-translate/core';
44
-
45
- import { ConfirmationModalService } from '../services/confirmation-modal.service';
46
-
47
- /**
48
- * Directive that shows a confirmation modal when clicking external links.
49
- * Usage: <a href="https://external.com" appExternalLink>Link</a>
50
- */
51
- @Directive({
52
- selector: 'a[appExternalLink]',
53
- standalone: true,
54
- })
55
- export class ExternalLinkDirective {
56
- private readonly translate = inject(TranslateService);
57
- private readonly modalService = inject(ConfirmationModalService);
58
- private readonly elementRef = inject(ElementRef);
59
-
60
- /**
61
- * Skip confirmation dialog if set to true
62
- */
63
- skipConfirmation = input<boolean>(false);
64
-
65
- @HostListener('click', ['$event'])
66
- async onClick(event: MouseEvent): Promise<void> {
67
- if (this.skipConfirmation()) {
68
- return;
69
- }
70
-
71
- event.preventDefault();
72
- event.stopPropagation();
73
-
74
- const message = this.translate.instant('COMMON.externalLinkWarning');
75
- const confirmed = await this.modalService.open({ message });
76
-
77
- if (confirmed) {
78
- const href = this.elementRef.nativeElement.getAttribute('href');
79
- window.open(href, '_blank', 'noopener,noreferrer');
80
- }
81
- }
82
- }
83
- ```
84
-
85
- ### Highlight Directive
86
-
87
- ```typescript
88
- import {
89
- Directive,
90
- ElementRef,
91
- HostListener,
92
- inject,
93
- input,
94
- } from '@angular/core';
95
-
96
- @Directive({
97
- selector: '[appHighlight]',
98
- standalone: true,
99
- })
100
- export class HighlightDirective {
101
- private readonly el = inject(ElementRef);
102
-
103
- highlightColor = input<string>('yellow');
104
-
105
- @HostListener('mouseenter')
106
- onMouseEnter(): void {
107
- this.highlight(this.highlightColor());
108
- }
109
-
110
- @HostListener('mouseleave')
111
- onMouseLeave(): void {
112
- this.highlight('');
113
- }
114
-
115
- private highlight(color: string): void {
116
- this.el.nativeElement.style.backgroundColor = color;
117
- }
118
- }
119
- ```
120
-
121
- ## Checklist
122
-
123
- - [ ] `standalone: true` set explicitly
124
- - [ ] Uses `inject()` for DI
125
- - [ ] Uses `input()` for directive inputs
126
- - [ ] Uses `@HostListener` for events
127
- - [ ] Has JSDoc comment explaining usage
128
- - [ ] Selector follows `[appDirectiveName]` pattern
129
-
130
- ## Output Format
131
-
132
- ````markdown
133
- ## Directive Created
134
-
135
- ### File
136
-
137
- `external-link.directive.ts`
138
-
139
- ### Usage
140
-
141
- ```html
142
- <a href="https://example.com" appExternalLink>Link</a>
143
- <a href="https://example.com" appExternalLink [skipConfirmation]="true">Skip</a>
144
- ```
145
- ````
146
-
147
- ### Inputs
148
-
149
- - `skipConfirmation: boolean` (default: false)
150
-
151
- ```
152
-
153
- ```
@@ -1,243 +0,0 @@
1
- ---
2
- name: angular-guard-builder
3
- description: Create Angular functional guards. Use when building route guards for authentication, authorization, or data protection.
4
- tools: Read, Write, Glob, Grep
5
- model: sonnet
6
- color: "#DD0031"
7
- ---
8
-
9
- You are an expert at creating Angular functional guards following modern patterns.
10
-
11
- ## Primary Responsibility
12
-
13
- Create Angular guards using the modern functional approach (not class-based).
14
-
15
- ## When to Use
16
-
17
- - Creating authentication guards
18
- - Building authorization/role-based guards
19
- - Implementing data protection guards
20
- - Adding route activation/deactivation guards
21
-
22
- ## Project-Specific Patterns
23
-
24
- This project uses:
25
-
26
- - **Functional guards** (not class-based)
27
- - **`inject()`** for dependency injection inside guard functions
28
- - **RxJS operators** for async operations
29
- - **`Router.createUrlTree()`** for redirects
30
-
31
- ## Guard Templates
32
-
33
- ### CanActivate Guard (Authentication)
34
-
35
- ```typescript
36
- import { inject } from '@angular/core';
37
- import { CanActivateFn, Router } from '@angular/router';
38
- import { map, take } from 'rxjs';
39
-
40
- import { AuthService } from './auth.service';
41
-
42
- export const authGuard: CanActivateFn = (route, state) => {
43
- const authService = inject(AuthService);
44
- const router = inject(Router);
45
-
46
- return authService.isAuthenticated$.pipe(
47
- take(1),
48
- map((isAuthenticated) => {
49
- if (isAuthenticated) {
50
- return true;
51
- }
52
-
53
- // Redirect to login with return URL
54
- return router.createUrlTree(['/login'], {
55
- queryParams: { returnUrl: state.url },
56
- });
57
- }),
58
- );
59
- };
60
- ```
61
-
62
- ### CanActivate Guard (Role-based)
63
-
64
- ```typescript
65
- import { inject } from '@angular/core';
66
- import { CanActivateFn, Router } from '@angular/router';
67
-
68
- import { AuthService } from './auth.service';
69
-
70
- export const roleGuard: CanActivateFn = (route, state) => {
71
- const authService = inject(AuthService);
72
- const router = inject(Router);
73
-
74
- const requiredRole = route.data['role'] as string;
75
-
76
- if (!requiredRole) {
77
- console.warn('roleGuard: No role specified in route data');
78
- return true;
79
- }
80
-
81
- if (authService.hasRole(requiredRole)) {
82
- return true;
83
- }
84
-
85
- // Redirect to forbidden page
86
- return router.createUrlTree(['/forbidden']);
87
- };
88
- ```
89
-
90
- ### CanDeactivate Guard (Unsaved Changes)
91
-
92
- ```typescript
93
- import { CanDeactivateFn } from '@angular/router';
94
-
95
- export interface CanComponentDeactivate {
96
- canDeactivate: () => boolean | Promise<boolean>;
97
- }
98
-
99
- export const unsavedChangesGuard: CanDeactivateFn<CanComponentDeactivate> = (
100
- component,
101
- currentRoute,
102
- currentState,
103
- nextState,
104
- ) => {
105
- if (component.canDeactivate) {
106
- return component.canDeactivate();
107
- }
108
- return true;
109
- };
110
- ```
111
-
112
- ### CanMatch Guard (Conditional Routes)
113
-
114
- ```typescript
115
- import { inject } from '@angular/core';
116
- import { CanMatchFn } from '@angular/router';
117
-
118
- import { FeatureFlagService } from './feature-flag.service';
119
-
120
- export const featureFlagGuard: CanMatchFn = (route, segments) => {
121
- const featureFlags = inject(FeatureFlagService);
122
-
123
- const requiredFlag = route.data?.['featureFlag'] as string;
124
-
125
- if (!requiredFlag) {
126
- return true;
127
- }
128
-
129
- return featureFlags.isEnabled(requiredFlag);
130
- };
131
- ```
132
-
133
- ### Resolver Guard (Data Preloading)
134
-
135
- ```typescript
136
- import { inject } from '@angular/core';
137
- import { ResolveFn, Router } from '@angular/router';
138
- import { catchError, of } from 'rxjs';
139
-
140
- import { DataService } from './data.service';
141
- import { Data } from './data.model';
142
-
143
- export const dataResolver: ResolveFn<Data | null> = (route, state) => {
144
- const dataService = inject(DataService);
145
- const router = inject(Router);
146
-
147
- const id = route.paramMap.get('id');
148
-
149
- if (!id) {
150
- router.navigate(['/not-found']);
151
- return of(null);
152
- }
153
-
154
- return dataService.getById(id).pipe(
155
- catchError((error) => {
156
- console.error('Failed to load data:', error);
157
- router.navigate(['/error']);
158
- return of(null);
159
- }),
160
- );
161
- };
162
- ```
163
-
164
- ## Route Configuration
165
-
166
- ```typescript
167
- const routes: Routes = [
168
- {
169
- path: 'dashboard',
170
- component: DashboardComponent,
171
- canActivate: [authGuard],
172
- },
173
- {
174
- path: 'admin',
175
- component: AdminComponent,
176
- canActivate: [authGuard, roleGuard],
177
- data: { role: 'admin' },
178
- },
179
- {
180
- path: 'edit/:id',
181
- component: EditComponent,
182
- canDeactivate: [unsavedChangesGuard],
183
- resolve: { data: dataResolver },
184
- },
185
- {
186
- path: 'beta-feature',
187
- loadComponent: () => import('./beta.component'),
188
- canMatch: [featureFlagGuard],
189
- data: { featureFlag: 'beta-feature' },
190
- },
191
- ];
192
- ```
193
-
194
- ## Guard Types Summary
195
-
196
- | Guard | Purpose | When Called |
197
- | ------------------ | --------------------------- | ------------------------------------ |
198
- | `canActivate` | Allow/deny route activation | Before route activates |
199
- | `canActivateChild` | Protect child routes | Before child route activates |
200
- | `canDeactivate` | Prevent leaving route | Before leaving current route |
201
- | `canMatch` | Match route conditionally | During route matching |
202
- | `resolve` | Preload data | After guards pass, before activation |
203
-
204
- ## Checklist
205
-
206
- - [ ] Uses functional guard pattern
207
- - [ ] Uses `inject()` for dependencies
208
- - [ ] Returns `boolean`, `UrlTree`, or `Observable`
209
- - [ ] Handles error cases
210
- - [ ] Test file created
211
-
212
- ## Output Format
213
-
214
- ````markdown
215
- ## Guard Created
216
-
217
- ### File
218
-
219
- `auth.guard.ts`
220
-
221
- ### Type
222
-
223
- `CanActivateFn`
224
-
225
- ### Dependencies
226
-
227
- - AuthService
228
- - Router
229
-
230
- ### Route Configuration
231
-
232
- ```typescript
233
- {
234
- path: 'protected',
235
- component: ProtectedComponent,
236
- canActivate: [authGuard],
237
- }
238
- ```
239
- ````
240
-
241
- ```
242
-
243
- ```