@smartsoft001-mobilems/claude-plugins 2.85.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 (132) hide show
  1. package/.claude-plugin/marketplace.json +2 -6
  2. package/package.json +2 -2
  3. package/plugins/mobilems/.claude-plugin/README.md +30 -0
  4. package/plugins/mobilems/.claude-plugin/plugin.json +5 -0
  5. package/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh +372 -0
  6. package/plugins/mobilems/skills/mobilems-docs-reader/SKILL.md +116 -0
  7. package/plugins/flow/.claude-plugin/README.md +0 -91
  8. package/plugins/flow/.claude-plugin/merge-permissions.js +0 -97
  9. package/plugins/flow/.claude-plugin/plugin.json +0 -5
  10. package/plugins/flow/.claude-plugin/settings.template.json +0 -86
  11. package/plugins/flow/agents/angular-component-scaffolder.md +0 -175
  12. package/plugins/flow/agents/angular-directive-builder.md +0 -153
  13. package/plugins/flow/agents/angular-guard-builder.md +0 -243
  14. package/plugins/flow/agents/angular-jest-test-writer.md +0 -474
  15. package/plugins/flow/agents/angular-pipe-builder.md +0 -169
  16. package/plugins/flow/agents/angular-resolver-builder.md +0 -286
  17. package/plugins/flow/agents/angular-service-builder.md +0 -161
  18. package/plugins/flow/agents/angular-signal-state-builder.md +0 -339
  19. package/plugins/flow/agents/angular-test-diagnostician.md +0 -279
  20. package/plugins/flow/agents/angular-testbed-configurator.md +0 -315
  21. package/plugins/flow/agents/arch-scaffolder.md +0 -278
  22. package/plugins/flow/agents/e2e-data-testid-injector.md +0 -197
  23. package/plugins/flow/agents/e2e-project-scaffolder.md +0 -194
  24. package/plugins/flow/agents/e2e-test-writer.md +0 -350
  25. package/plugins/flow/agents/shared-agent-evolver.md +0 -294
  26. package/plugins/flow/agents/shared-build-verifier.md +0 -160
  27. package/plugins/flow/agents/shared-config-updater.md +0 -310
  28. package/plugins/flow/agents/shared-coverage-enforcer.md +0 -184
  29. package/plugins/flow/agents/shared-error-handler.md +0 -217
  30. package/plugins/flow/agents/shared-file-creator.md +0 -344
  31. package/plugins/flow/agents/shared-impl-orchestrator.md +0 -312
  32. package/plugins/flow/agents/shared-impl-reporter.md +0 -368
  33. package/plugins/flow/agents/shared-impl-teammate.md +0 -201
  34. package/plugins/flow/agents/shared-linear-subtask-iterator.md +0 -337
  35. package/plugins/flow/agents/shared-logic-implementer.md +0 -243
  36. package/plugins/flow/agents/shared-maia-api.md +0 -26
  37. package/plugins/flow/agents/shared-parallelization-analyzer.md +0 -343
  38. package/plugins/flow/agents/shared-performance-validator.md +0 -168
  39. package/plugins/flow/agents/shared-plan-perspective.md +0 -269
  40. package/plugins/flow/agents/shared-project-standardizer.md +0 -205
  41. package/plugins/flow/agents/shared-report-synthesizer.md +0 -188
  42. package/plugins/flow/agents/shared-review-teammate.md +0 -189
  43. package/plugins/flow/agents/shared-security-scanner.md +0 -186
  44. package/plugins/flow/agents/shared-style-enforcer.md +0 -230
  45. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +0 -188
  46. package/plugins/flow/agents/shared-tdd-developer.md +0 -350
  47. package/plugins/flow/agents/shared-team-coordinator.md +0 -189
  48. package/plugins/flow/agents/shared-test-fixer.md +0 -186
  49. package/plugins/flow/agents/shared-test-runner.md +0 -191
  50. package/plugins/flow/agents/shared-ui-classifier.md +0 -263
  51. package/plugins/flow/agents/shared-verification-orchestrator.md +0 -194
  52. package/plugins/flow/agents/shared-verification-runner.md +0 -140
  53. package/plugins/flow/agents/ui-a11y-validator.md +0 -305
  54. package/plugins/flow/agents/ui-screenshot-reporter.md +0 -329
  55. package/plugins/flow/agents/ui-web-designer.md +0 -214
  56. package/plugins/flow/scripts/compute-session-tokens.sh +0 -39
  57. package/plugins/flow/skills/a11y-audit/SKILL.md +0 -214
  58. package/plugins/flow/skills/angular-patterns/SKILL.md +0 -191
  59. package/plugins/flow/skills/browser-capture/SKILL.md +0 -238
  60. package/plugins/flow/skills/commit/SKILL.md +0 -259
  61. package/plugins/flow/skills/debug-helper/SKILL.md +0 -375
  62. package/plugins/flow/skills/impl/SKILL.md +0 -992
  63. package/plugins/flow/skills/linear-suggestion/SKILL.md +0 -132
  64. package/plugins/flow/skills/maia-files-delete/SKILL.md +0 -59
  65. package/plugins/flow/skills/maia-files-upload/SKILL.md +0 -57
  66. package/plugins/flow/skills/nx-conventions/SKILL.md +0 -326
  67. package/plugins/flow/skills/plan/SKILL.md +0 -1033
  68. package/plugins/flow/skills/push/SKILL.md +0 -759
  69. package/plugins/flow/skills/review/SKILL.md +0 -443
  70. package/plugins/flow/skills/test-e2e/SKILL.md +0 -161
  71. package/plugins/flow/skills/test-unit/SKILL.md +0 -456
  72. package/plugins/flow-external/.claude-plugin/README.md +0 -152
  73. package/plugins/flow-external/.claude-plugin/merge-permissions.js +0 -80
  74. package/plugins/flow-external/.claude-plugin/plugin.json +0 -5
  75. package/plugins/flow-external/.claude-plugin/settings.template.json +0 -78
  76. package/plugins/flow-external/agents/angular-component-scaffolder.md +0 -269
  77. package/plugins/flow-external/agents/angular-directive-builder.md +0 -130
  78. package/plugins/flow-external/agents/angular-guard-builder.md +0 -70
  79. package/plugins/flow-external/agents/angular-pipe-builder.md +0 -82
  80. package/plugins/flow-external/agents/angular-resolver-builder.md +0 -74
  81. package/plugins/flow-external/agents/angular-service-builder.md +0 -160
  82. package/plugins/flow-external/agents/angular-state-builder.md +0 -254
  83. package/plugins/flow-external/agents/shared-build-verifier.md +0 -67
  84. package/plugins/flow-external/agents/shared-impl-orchestrator.md +0 -88
  85. package/plugins/flow-external/agents/shared-impl-reporter.md +0 -135
  86. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +0 -70
  87. package/plugins/flow-external/agents/shared-ui-classifier.md +0 -38
  88. package/plugins/flow-external/agents/ui-web-designer.md +0 -179
  89. package/plugins/flow-external/scripts/compute-session-tokens.sh +0 -39
  90. package/plugins/flow-external/skills/a11y-audit/SKILL.md +0 -96
  91. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +0 -267
  92. package/plugins/flow-external/skills/angular-patterns/SKILL.md +0 -170
  93. package/plugins/flow-external/skills/browser-capture/SKILL.md +0 -68
  94. package/plugins/flow-external/skills/commit/SKILL.md +0 -114
  95. package/plugins/flow-external/skills/debug-helper/SKILL.md +0 -131
  96. package/plugins/flow-external/skills/impl/SKILL.md +0 -217
  97. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +0 -62
  98. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +0 -34
  99. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +0 -41
  100. package/plugins/flow-external/skills/plan/SKILL.md +0 -334
  101. package/plugins/flow-external/skills/push/SKILL.md +0 -232
  102. package/plugins/flow-legacy/.claude-plugin/README.md +0 -143
  103. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +0 -94
  104. package/plugins/flow-legacy/.claude-plugin/plugin.json +0 -5
  105. package/plugins/flow-legacy/.claude-plugin/settings.template.json +0 -79
  106. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +0 -323
  107. package/plugins/flow-legacy/agents/angular-directive-builder.md +0 -258
  108. package/plugins/flow-legacy/agents/angular-guard-builder.md +0 -322
  109. package/plugins/flow-legacy/agents/angular-pipe-builder.md +0 -227
  110. package/plugins/flow-legacy/agents/angular-resolver-builder.md +0 -332
  111. package/plugins/flow-legacy/agents/angular-service-builder.md +0 -271
  112. package/plugins/flow-legacy/agents/angular-state-builder.md +0 -479
  113. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +0 -174
  114. package/plugins/flow-legacy/agents/shared-impl-reporter.md +0 -232
  115. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +0 -187
  116. package/plugins/flow-legacy/agents/shared-tdd-developer.md +0 -306
  117. package/plugins/flow-legacy/agents/shared-test-runner.md +0 -131
  118. package/plugins/flow-legacy/agents/shared-ui-classifier.md +0 -145
  119. package/plugins/flow-legacy/scripts/compute-session-tokens.sh +0 -39
  120. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +0 -214
  121. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +0 -346
  122. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +0 -238
  123. package/plugins/flow-legacy/skills/commit/SKILL.md +0 -215
  124. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +0 -395
  125. package/plugins/flow-legacy/skills/impl/SKILL.md +0 -710
  126. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +0 -132
  127. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +0 -59
  128. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +0 -57
  129. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +0 -368
  130. package/plugins/flow-legacy/skills/plan/SKILL.md +0 -742
  131. package/plugins/flow-legacy/skills/push/SKILL.md +0 -645
  132. package/plugins/flow-legacy/skills/test-unit/SKILL.md +0 -500
@@ -1,346 +0,0 @@
1
- ---
2
- name: angular-patterns
3
- description: Angular 14 legacy patterns including *ngIf/*ngFor directives, constructor DI, and @Input/@Output decorators
4
- ---
5
-
6
- # Angular 14 Legacy Patterns
7
-
8
- This skill provides guidance on Angular 14 patterns for legacy projects.
9
-
10
- ## CRITICAL: Use Legacy Patterns ONLY
11
-
12
- **DO NOT use modern Angular features (Angular 16+):**
13
-
14
- | Feature | CORRECT (Angular 14) | WRONG (Modern) |
15
- | ------------ | ------------------------------- | ------------------------ |
16
- | Control flow | `*ngIf`, `*ngFor`, `[ngSwitch]` | `@if`, `@for`, `@switch` |
17
- | DI | Constructor injection | `inject()` |
18
- | Inputs | `@Input()` decorator | `input()` function |
19
- | Outputs | `@Output()` decorator | `output()` function |
20
- | Two-way | `@Input()` + `@Output()` | `model()` |
21
- | State | BehaviorSubject, Observable | signals, `signal()` |
22
- | Derived | `pipe(map())` | `computed()` |
23
- | Side effects | `subscribe()` | `effect()` |
24
- | Components | NgModule-based | standalone |
25
-
26
- ## 1. Control Flow Syntax (`*ngIf`, `*ngFor`, `[ngSwitch]`)
27
-
28
- ### Conditional Rendering
29
-
30
- ```html
31
- <!-- *ngIf with else -->
32
- <div *ngIf="isLoading; else loadedContent">
33
- <app-spinner></app-spinner>
34
- </div>
35
- <ng-template #loadedContent>
36
- <div *ngIf="error; else dataContent">
37
- <app-error [message]="error?.message"></app-error>
38
- </div>
39
- </ng-template>
40
- <ng-template #dataContent>
41
- <ul>
42
- <li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
43
- </ul>
44
- <p *ngIf="items.length === 0">No data</p>
45
- </ng-template>
46
- ```
47
-
48
- ### Iteration
49
-
50
- ```html
51
- <!-- *ngFor with index and trackBy -->
52
- <ul>
53
- <li *ngFor="let item of items; let i = index; trackBy: trackById">
54
- {{ i + 1 }}. {{ item.name }}
55
- </li>
56
- </ul>
57
- ```
58
-
59
- ```typescript
60
- // trackBy function in component
61
- trackById(index: number, item: Item): string {
62
- return item.id;
63
- }
64
- ```
65
-
66
- ### Switch Statement
67
-
68
- ```html
69
- <div [ngSwitch]="status">
70
- <span *ngSwitchCase="'pending'" class="text-yellow-500">Pending</span>
71
- <span *ngSwitchCase="'active'" class="text-green-500">Active</span>
72
- <span *ngSwitchDefault class="text-gray-500">Unknown</span>
73
- </div>
74
- ```
75
-
76
- ## 2. BehaviorSubject for State Management
77
-
78
- ### When to Use
79
-
80
- | Pattern | Use Case |
81
- | ------------------ | --------------------------------------- |
82
- | `BehaviorSubject` | Local, mutable state with initial value |
83
- | `ReplaySubject(1)` | State without initial value |
84
- | `pipe(map())` | Derived/computed values |
85
- | `combineLatest` | Combine multiple observables |
86
-
87
- ### BehaviorSubject Examples
88
-
89
- ```typescript
90
- import { BehaviorSubject } from 'rxjs';
91
- import { map } from 'rxjs/operators';
92
-
93
- @Injectable({
94
- providedIn: 'root',
95
- })
96
- export class StateService {
97
- // Private BehaviorSubject
98
- private readonly _items = new BehaviorSubject<Item[]>([]);
99
- private readonly _isLoading = new BehaviorSubject<boolean>(false);
100
- private readonly _filter = new BehaviorSubject<string>('');
101
-
102
- // Public Observable (read-only)
103
- readonly items$ = this._items.asObservable();
104
- readonly isLoading$ = this._isLoading.asObservable();
105
- readonly filter$ = this._filter.asObservable();
106
-
107
- // Derived state using pipe(map())
108
- readonly filtered$ = combineLatest([this._items, this._filter]).pipe(
109
- map(([items, filter]) => {
110
- const f = filter.toLowerCase();
111
- return items.filter((i) => i.name.toLowerCase().includes(f));
112
- }),
113
- );
114
-
115
- readonly count$ = this._items.pipe(map((items) => items.length));
116
-
117
- // Methods to update state
118
- setItems(items: Item[]): void {
119
- this._items.next(items);
120
- }
121
-
122
- setLoading(loading: boolean): void {
123
- this._isLoading.next(loading);
124
- }
125
-
126
- setFilter(filter: string): void {
127
- this._filter.next(filter);
128
- }
129
-
130
- // Get current value
131
- get currentItems(): Item[] {
132
- return this._items.getValue();
133
- }
134
- }
135
- ```
136
-
137
- ## 3. Dependency Injection via Constructor
138
-
139
- ```typescript
140
- import { Component, OnInit, OnDestroy } from '@angular/core';
141
- import { Subject } from 'rxjs';
142
- import { takeUntil } from 'rxjs/operators';
143
-
144
- @Component({
145
- selector: 'app-my-component',
146
- templateUrl: './my-component.component.html',
147
- styleUrls: ['./my-component.component.scss'],
148
- })
149
- export class MyComponent implements OnInit, OnDestroy {
150
- items: Item[] = [];
151
-
152
- private readonly destroy$ = new Subject<void>();
153
-
154
- // Constructor injection (NOT inject())
155
- constructor(
156
- private readonly http: HttpClient,
157
- private readonly router: Router,
158
- private readonly myService: MyService,
159
- @Optional() private readonly optionalService: OptionalService,
160
- ) {}
161
-
162
- ngOnInit(): void {
163
- this.myService.items$.pipe(takeUntil(this.destroy$)).subscribe((items) => {
164
- this.items = items;
165
- });
166
- }
167
-
168
- ngOnDestroy(): void {
169
- this.destroy$.next();
170
- this.destroy$.complete();
171
- }
172
- }
173
- ```
174
-
175
- ### Rules
176
-
177
- - Place dependencies in constructor
178
- - Use `private readonly` for services
179
- - Use `@Optional()` for optional dependencies
180
- - Always implement `OnDestroy` with `takeUntil` pattern
181
-
182
- ## 4. Input/Output APIs: `@Input()`, `@Output()`, `EventEmitter`
183
-
184
- ### Decorator Patterns
185
-
186
- ```typescript
187
- import {
188
- Component,
189
- Input,
190
- Output,
191
- EventEmitter,
192
- OnChanges,
193
- SimpleChanges,
194
- } from '@angular/core';
195
-
196
- @Component({
197
- selector: 'app-form-field',
198
- templateUrl: './form-field.component.html',
199
- })
200
- export class FormFieldComponent implements OnChanges {
201
- // Required input (validate in ngOnChanges)
202
- @Input() label!: string;
203
-
204
- // Optional input with default
205
- @Input() disabled = false;
206
-
207
- // Input with setter for transformation
208
- @Input()
209
- set count(value: string | number) {
210
- this._count = typeof value === 'string' ? parseInt(value, 10) : value;
211
- }
212
- get count(): number {
213
- return this._count;
214
- }
215
- private _count = 0;
216
-
217
- // Output event
218
- @Output() changed = new EventEmitter<string>();
219
-
220
- // Two-way binding (banana-in-a-box)
221
- @Input() value = '';
222
- @Output() valueChange = new EventEmitter<string>();
223
-
224
- ngOnChanges(changes: SimpleChanges): void {
225
- if (changes['label'] && !this.label) {
226
- throw new Error('label is required');
227
- }
228
- }
229
-
230
- onInputChange(newValue: string): void {
231
- this.value = newValue;
232
- this.valueChange.emit(newValue);
233
- this.changed.emit(newValue);
234
- }
235
- }
236
- ```
237
-
238
- ### Usage in Templates
239
-
240
- ```html
241
- <!-- Parent template -->
242
- <app-form-field
243
- label="Name"
244
- [disabled]="isDisabled"
245
- [(value)]="name"
246
- (changed)="onChanged($event)"
247
- ></app-form-field>
248
- ```
249
-
250
- ## 5. NgModule-based Components
251
-
252
- All components must be declared in a module:
253
-
254
- ```typescript
255
- // feature.module.ts
256
- import { NgModule } from '@angular/core';
257
- import { CommonModule } from '@angular/common';
258
- import { FormsModule, ReactiveFormsModule } from '@angular/forms';
259
-
260
- import { FeatureComponent } from './feature.component';
261
- import { FeatureListComponent } from './feature-list/feature-list.component';
262
- import { FeatureItemComponent } from './feature-item/feature-item.component';
263
- import { SharedModule } from '@shared/shared.module';
264
-
265
- @NgModule({
266
- declarations: [FeatureComponent, FeatureListComponent, FeatureItemComponent],
267
- imports: [CommonModule, FormsModule, ReactiveFormsModule, SharedModule],
268
- exports: [FeatureComponent],
269
- })
270
- export class FeatureModule {}
271
- ```
272
-
273
- ```typescript
274
- // feature.component.ts
275
- @Component({
276
- selector: 'app-feature',
277
- templateUrl: './feature.component.html',
278
- styleUrls: ['./feature.component.scss'],
279
- })
280
- export class FeatureComponent implements OnInit, OnDestroy {
281
- // ... component logic
282
- }
283
- ```
284
-
285
- ## 6. Async Pipe Usage
286
-
287
- Always prefer `async` pipe over manual subscriptions in templates:
288
-
289
- ```html
290
- <!-- Using async pipe -->
291
- <div *ngIf="isLoading$ | async; else content">
292
- <app-spinner></app-spinner>
293
- </div>
294
- <ng-template #content>
295
- <ul>
296
- <li *ngFor="let item of items$ | async; trackBy: trackById">
297
- {{ item.name }}
298
- </li>
299
- </ul>
300
- </ng-template>
301
- ```
302
-
303
- ```typescript
304
- @Component({...})
305
- export class ListComponent {
306
- readonly isLoading$ = this.stateService.isLoading$;
307
- readonly items$ = this.stateService.items$;
308
-
309
- constructor(private readonly stateService: StateService) {}
310
-
311
- trackById(index: number, item: Item): string {
312
- return item.id;
313
- }
314
- }
315
- ```
316
-
317
- ## 7. Performance Guidelines
318
-
319
- - Every `*ngFor` must have a `trackBy` function
320
- - Extract complex logic from templates to component methods
321
- - Use `OnPush` change detection when appropriate
322
- - Avoid function calls in templates (use getters or properties)
323
-
324
- ```typescript
325
- @Component({
326
- selector: 'app-optimized',
327
- templateUrl: './optimized.component.html',
328
- changeDetection: ChangeDetectionStrategy.OnPush,
329
- })
330
- export class OptimizedComponent {
331
- // ...
332
- }
333
- ```
334
-
335
- ## 8. PR Checklist (Angular 14 Legacy)
336
-
337
- - [ ] Using `*ngIf`/`*ngFor` (NOT `@if`/`@for`)
338
- - [ ] Using `[ngSwitch]` (NOT `@switch`)
339
- - [ ] Every `*ngFor` has `trackBy` function
340
- - [ ] Using constructor DI (NOT `inject()`)
341
- - [ ] Using `@Input()`/`@Output()` decorators (NOT `input()`/`output()`)
342
- - [ ] Using BehaviorSubject for state (NOT signals)
343
- - [ ] Using `pipe(map())` for derived state (NOT `computed()`)
344
- - [ ] Component declared in NgModule (NOT standalone)
345
- - [ ] Using `async` pipe in templates
346
- - [ ] Implementing `OnDestroy` with `takeUntil` pattern
@@ -1,238 +0,0 @@
1
- ---
2
- name: browser-capture
3
- description: Manage browser sessions and capture screenshots. Ensures dev server is running, navigates to pages, captures responsive screenshots, and uploads them to temporary storage.
4
- allowed-tools:
5
- - Bash
6
- - Read
7
- - Glob
8
- - mcp__playwright__browser_navigate
9
- - mcp__playwright__browser_snapshot
10
- - mcp__playwright__browser_take_screenshot
11
- - mcp__playwright__browser_resize
12
- - mcp__playwright__browser_close
13
- ---
14
-
15
- # Browser Capture Skill
16
-
17
- Manage browser sessions for capturing screenshots of web pages. Automatically ensures the development server is running before capturing.
18
-
19
- ## Capabilities
20
-
21
- 1. **Server Management**: Check if dev server is running, start if needed
22
- 2. **Page Navigation**: Navigate to specified URLs using Playwright
23
- 3. **Screenshot Capture**: Take screenshots at multiple viewport sizes
24
- 4. **Upload Screenshots**: Upload captured images to maia-api for use in reports
25
-
26
- ## Server Management
27
-
28
- ### Read Port Configuration
29
-
30
- ```bash
31
- # Default port location (Nx 14 / Angular 14)
32
- grep -o '"port":[^,}]*' apps/web/project.json | head -1
33
- # Default: 4200
34
- ```
35
-
36
- ### Check if Server is Running
37
-
38
- ```bash
39
- lsof -i :4200 -t
40
- ```
41
-
42
- - If returns PID -> server is running
43
- - If returns nothing -> server needs to be started
44
-
45
- ### Start Server if Needed
46
-
47
- ```bash
48
- # Start in background (Nx 14 / @nrwl)
49
- npm start &
50
-
51
- # Wait for server to be ready (check every 2 seconds, max 30 seconds)
52
- for i in {1..15}; do
53
- curl -s http://localhost:4200 > /dev/null && break
54
- sleep 2
55
- done
56
- ```
57
-
58
- ## Screenshot Capture Process
59
-
60
- ### 1. Ensure Server is Running
61
-
62
- Before any screenshot capture:
63
-
64
- 1. Read port from `apps/web/project.json` (default: 4200)
65
- 2. Check if port is occupied: `lsof -i :PORT -t`
66
- 3. If not running: `npm start &` and wait ~15 seconds
67
-
68
- ### 2. Navigate to Page
69
-
70
- Use `mcp__playwright__browser_navigate` to open the target URL.
71
-
72
- ```
73
- URL format: http://localhost:{port}/{path}
74
- ```
75
-
76
- ### 3. Capture at Multiple Viewports
77
-
78
- Standard viewport sizes:
79
-
80
- | Name | Width | Height |
81
- | ------- | ----- | ------ |
82
- | Desktop | 1920 | 1080 |
83
- | Tablet | 768 | 1024 |
84
- | Mobile | 375 | 667 |
85
-
86
- Process for each viewport:
87
-
88
- 1. `mcp__playwright__browser_resize` -> set dimensions
89
- 2. `mcp__playwright__browser_take_screenshot` -> save to temp file
90
-
91
- ### 4. Upload Screenshots
92
-
93
- After capturing, delegate upload to `maia-api` agent:
94
-
95
- ```
96
- Input: /tmp/screenshot-desktop.png
97
- Output: { id: "abc123", url: "https://maia-ai-api.smartsoft.biz.pl/files/abc123" }
98
- ```
99
-
100
- ## Usage Examples
101
-
102
- ### Capture Single Page
103
-
104
- ```
105
- Input: { path: "/articles", viewports: ["desktop", "mobile"] }
106
-
107
- Process:
108
- 1. Check server running on port 4200
109
- 2. Start if needed, wait for ready
110
- 3. Navigate to http://localhost:4200/articles
111
- 4. Resize to 1920x1080, screenshot -> /tmp/articles-desktop.png
112
- 5. Resize to 375x667, screenshot -> /tmp/articles-mobile.png
113
- 6. Upload both via maia-api agent
114
- 7. Return URLs
115
-
116
- Output:
117
- {
118
- "desktop": "https://maia-ai-api.smartsoft.biz.pl/files/abc123",
119
- "mobile": "https://maia-ai-api.smartsoft.biz.pl/files/def456"
120
- }
121
- ```
122
-
123
- ### Capture Before/After
124
-
125
- ```
126
- Input: {
127
- path: "/profile",
128
- phase: "before" | "after",
129
- viewports: ["desktop", "mobile"]
130
- }
131
-
132
- Output:
133
- {
134
- "phase": "before",
135
- "desktop": { "id": "abc123", "url": "https://..." },
136
- "mobile": { "id": "def456", "url": "https://..." }
137
- }
138
- ```
139
-
140
- ## Viewport Presets
141
-
142
- | Preset | Dimensions | Use Case |
143
- | ---------- | ---------- | ------------------------ |
144
- | `desktop` | 1920x1080 | Full desktop view |
145
- | `laptop` | 1366x768 | Common laptop resolution |
146
- | `tablet` | 768x1024 | iPad portrait |
147
- | `mobile` | 375x667 | iPhone SE/8 |
148
- | `mobile-l` | 414x896 | iPhone XR/11 |
149
-
150
- ## Server Ready Check
151
-
152
- ```bash
153
- # Check if server responds
154
- check_server() {
155
- local port=$1
156
- local max_attempts=$2
157
- local attempt=1
158
-
159
- while [ $attempt -le $max_attempts ]; do
160
- if curl -s "http://localhost:$port" > /dev/null 2>&1; then
161
- echo "Server ready"
162
- return 0
163
- fi
164
- echo "Waiting for server... ($attempt/$max_attempts)"
165
- sleep 2
166
- ((attempt++))
167
- done
168
-
169
- echo "Server not ready after $max_attempts attempts"
170
- return 1
171
- }
172
-
173
- check_server 4200 15
174
- ```
175
-
176
- ## Output Format
177
-
178
- When capturing screenshots, return structured data:
179
-
180
- ```json
181
- {
182
- "serverStarted": true,
183
- "port": 4200,
184
- "screenshots": [
185
- {
186
- "viewport": "desktop",
187
- "dimensions": "1920x1080",
188
- "localPath": "/tmp/screenshot-desktop.png",
189
- "uploadedId": "abc123",
190
- "uploadedUrl": "https://maia-ai-api.smartsoft.biz.pl/files/abc123"
191
- },
192
- {
193
- "viewport": "mobile",
194
- "dimensions": "375x667",
195
- "localPath": "/tmp/screenshot-mobile.png",
196
- "uploadedId": "def456",
197
- "uploadedUrl": "https://maia-ai-api.smartsoft.biz.pl/files/def456"
198
- }
199
- ]
200
- }
201
- ```
202
-
203
- ## Cleanup
204
-
205
- After screenshots are used (embedded in Linear comments), cleanup local temp files:
206
-
207
- ```bash
208
- rm /tmp/screenshot-*.png
209
- ```
210
-
211
- For API cleanup, delegate to `maia-api` agent with collected IDs.
212
-
213
- ## Error Handling
214
-
215
- ### Server Won't Start
216
-
217
- If server fails to start after 30 seconds:
218
-
219
- 1. Check for port conflicts: `lsof -i :4200`
220
- 2. Check npm logs for errors
221
- 3. Report error and skip screenshot capture
222
-
223
- ### Screenshot Fails
224
-
225
- If Playwright screenshot fails:
226
-
227
- 1. Verify navigation succeeded
228
- 2. Check for JavaScript errors: `mcp__playwright__browser_console_messages`
229
- 3. Try alternative viewport
230
- 4. Report partial success
231
-
232
- ### Upload Fails
233
-
234
- If maia-api upload fails:
235
-
236
- 1. Verify file exists and has content
237
- 2. Retry upload once
238
- 3. Report error with local file path as fallback