@smartsoft001-mobilems/claude-plugins 2.77.0 → 2.78.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 (32) hide show
  1. package/package.json +1 -1
  2. package/plugins/flow/.claude-plugin/plugin.json +1 -1
  3. package/plugins/flow-external/.claude-plugin/README.md +152 -0
  4. package/plugins/flow-external/.claude-plugin/merge-permissions.js +80 -0
  5. package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
  6. package/plugins/flow-external/.claude-plugin/settings.template.json +75 -0
  7. package/plugins/flow-external/agents/angular-component-scaffolder.md +269 -0
  8. package/plugins/flow-external/agents/angular-directive-builder.md +130 -0
  9. package/plugins/flow-external/agents/angular-guard-builder.md +70 -0
  10. package/plugins/flow-external/agents/angular-pipe-builder.md +82 -0
  11. package/plugins/flow-external/agents/angular-resolver-builder.md +74 -0
  12. package/plugins/flow-external/agents/angular-service-builder.md +160 -0
  13. package/plugins/flow-external/agents/angular-state-builder.md +254 -0
  14. package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
  15. package/plugins/flow-external/agents/shared-impl-orchestrator.md +88 -0
  16. package/plugins/flow-external/agents/shared-impl-reporter.md +107 -0
  17. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
  18. package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
  19. package/plugins/flow-external/agents/ui-web-designer.md +179 -0
  20. package/plugins/flow-external/skills/a11y-audit/SKILL.md +96 -0
  21. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +267 -0
  22. package/plugins/flow-external/skills/angular-patterns/SKILL.md +170 -0
  23. package/plugins/flow-external/skills/browser-capture/SKILL.md +68 -0
  24. package/plugins/flow-external/skills/commit/SKILL.md +113 -0
  25. package/plugins/flow-external/skills/debug-helper/SKILL.md +131 -0
  26. package/plugins/flow-external/skills/impl/SKILL.md +158 -0
  27. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
  28. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
  29. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
  30. package/plugins/flow-external/skills/plan/SKILL.md +163 -0
  31. package/plugins/flow-external/skills/push/SKILL.md +201 -0
  32. package/plugins/flow-legacy/.claude-plugin/plugin.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartsoft001-mobilems/claude-plugins",
3
- "version": "2.77.0",
3
+ "version": "2.78.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "flow",
3
3
  "description": "Development flow skills for Linear-driven development workflow",
4
- "version": "2.77.0"
4
+ "version": "2.78.0"
5
5
  }
@@ -0,0 +1,152 @@
1
+ # Flow-External Plugin for Claude Code
2
+
3
+ Development flow skills for **standalone Angular 6-11 projects** without the MobileMS framework. These are external projects using Angular CLI with their own styling approach (Bootstrap 4, custom SCSS, or other).
4
+
5
+ ## Target Projects
6
+
7
+ This plugin is designed for standalone MobileMS projects:
8
+
9
+ - **mobilems-asp** (Angular 11)
10
+ - **mobilems-etno** (Angular 11)
11
+ - **mobilems-mnw** (Angular 9)
12
+ - **mobilems-muzuem-malopolskie** (Angular 8)
13
+ - **mobilems-muzeum-powstan-slaskich** (Angular 6)
14
+
15
+ ### Technology Stack
16
+
17
+ | Feature | External Projects |
18
+ |---------|-------------------|
19
+ | Angular | 6 - 11 |
20
+ | Build system | Angular CLI (`ng`) |
21
+ | Styling | Project-specific (Bootstrap 4 / custom SCSS) |
22
+ | i18n | ngx-translate + LocalizeRouter |
23
+ | State | NgRx + localStorage sync |
24
+ | Project structure | Standalone (app/cli/docker) |
25
+
26
+ ### Patterns (what this plugin supports)
27
+
28
+ | Feature | External (Angular 6-11) | Legacy (Angular 14) | Modern (Angular 20+) |
29
+ |---------|-------------------------|---------------------|----------------------|
30
+ | Control flow | `*ngIf`, `*ngFor` | `*ngIf`, `*ngFor` | `@if`, `@for` |
31
+ | DI | Constructor injection | Constructor injection | `inject()` |
32
+ | Inputs/Outputs | `@Input()`, `@Output()` | `@Input()`, `@Output()` | `input()`, `output()` |
33
+ | State | BehaviorSubject, NgRx | BehaviorSubject | Signals |
34
+ | Components | NgModules | NgModules | Standalone |
35
+ | Styling | Bootstrap 4 / custom SCSS | Tailwind CSS | Tailwind CSS |
36
+ | Build | `ng build` | `nx build` | `nx build` |
37
+
38
+ ## Workflow Skills
39
+
40
+ | Skill | Description |
41
+ |-------|-------------|
42
+ | `/commit` | Create conventional commit based on Linear task |
43
+ | `/impl` | Implement plans from Linear task comments |
44
+ | `/plan` | Create implementation plan and save to Linear |
45
+ | `/push` | Push changes and update Linear status |
46
+
47
+ ## Installation
48
+
49
+ ### 1. Enable plugin in project's `.claude/settings.json`:
50
+
51
+ ```json
52
+ {
53
+ "enabledPlugins": {
54
+ "flow-external@mobilems": true
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 2. Merge permissions from template
60
+
61
+ Run the merge script:
62
+
63
+ ```bash
64
+ node node_modules/@smartsoft001-mobilems/claude-plugins/plugins/flow-external/.claude-plugin/merge-permissions.js
65
+ ```
66
+
67
+ ## Required MCP Servers
68
+
69
+ Configure these in your `.mcp.json`:
70
+
71
+ - `linear-server` - Linear API integration
72
+ - `playwright` - Browser automation for screenshots
73
+
74
+ ## Permission Strategy
75
+
76
+ ### Automatic (allow)
77
+ - Git read operations (status, diff, log, show)
78
+ - Angular CLI commands (ng build, ng lint, ng serve)
79
+ - Linear API (read/write issues, comments)
80
+ - Playwright (screenshots)
81
+ - Utility skills
82
+
83
+ ### Requires Confirmation (ask)
84
+ - Workflow skills (/commit, /impl, /plan, /push)
85
+ - `git commit` - creating commits
86
+ - `git push` - pushing to remote
87
+ - `gh pr create` - creating pull requests
88
+
89
+ ## Utility Skills
90
+
91
+ | Skill | Description |
92
+ |-------|-------------|
93
+ | `maia-files-upload` | Upload files to Maia API |
94
+ | `maia-files-delete` | Delete files from Maia API |
95
+ | `browser-capture` | Capture screenshots with Playwright |
96
+ | `linear-suggestion` | Create Linear issues for improvements |
97
+ | `a11y-audit` | Accessibility audit |
98
+
99
+ ## Agents
100
+
101
+ ### Angular Agents (Legacy CLI patterns)
102
+ - `angular-component-scaffolder` - Components with NgModules, `*ngIf`/`*ngFor`, constructor DI
103
+ - `angular-service-builder` - Services with BehaviorSubject, constructor DI
104
+ - `angular-state-builder` - NgRx state management with reducers and effects
105
+ - `angular-directive-builder` - Directives with constructor DI
106
+ - `angular-pipe-builder` - Pipes with constructor DI
107
+ - `angular-guard-builder` - Class-based guards with constructor DI
108
+ - `angular-resolver-builder` - Class-based resolvers with constructor DI
109
+
110
+ ### Shared Agents
111
+ - `shared-impl-orchestrator` - Implementation orchestration
112
+ - `shared-impl-reporter` - Implementation reporting
113
+ - `shared-linear-subtask-iterator` - Linear subtask iteration
114
+ - `shared-build-verifier` - Build verification via `ng build`
115
+ - `shared-ui-classifier` - UI change classification
116
+ - `ui-web-designer` - Styling with project-specific approach (Bootstrap 4 or custom SCSS)
117
+
118
+ ## Differences from other plugins
119
+
120
+ | Aspect | `flow` (modern) | `flow-legacy` | `flow-external` |
121
+ |--------|-----------------|---------------|-----------------|
122
+ | Angular version | 20+ | 14 | 6-11 |
123
+ | Build system | Nx | Nx | Angular CLI |
124
+ | Styling | Tailwind | Tailwind | Project-specific |
125
+ | State | Signals | BehaviorSubject | NgRx + BehaviorSubject |
126
+ | Project structure | Nx monorepo | Nx monorepo | Standalone app/ |
127
+
128
+ ## Example Project Structure
129
+
130
+ ```
131
+ project-root/
132
+ app/ # Frontend Angular application
133
+ src/
134
+ app/
135
+ components/
136
+ services/
137
+ pipes/
138
+ directives/
139
+ interceptors/
140
+ guards/
141
+ state/ # NgRx store
142
+ assets/
143
+ environments/
144
+ angular.json
145
+ package.json
146
+ tsconfig.json
147
+ cli/ # CLI scripts
148
+ frontend-cli
149
+ docker/ # Docker configuration
150
+ Dockerfile
151
+ .env
152
+ ```
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Merge flow-external plugin permissions into project's .claude/settings.json
4
+ *
5
+ * Usage:
6
+ * npx @smartsoft001-mobilems/claude-plugins flow-external:merge-permissions
7
+ *
8
+ * Or directly:
9
+ * node node_modules/@smartsoft001-mobilems/claude-plugins/plugins/flow-external/.claude-plugin/merge-permissions.js
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ const SETTINGS_PATH = path.join(process.cwd(), '.claude', 'settings.json');
16
+ const TEMPLATE_PATH = path.join(__dirname, 'settings.template.json');
17
+
18
+ function loadJson(filePath) {
19
+ try {
20
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
21
+ } catch (e) {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function mergeArrays(existing, template) {
27
+ return [...new Set([...existing, ...template])];
28
+ }
29
+
30
+ function main() {
31
+ console.log('Flow-External Plugin - Merge Permissions\n');
32
+
33
+ // Load template
34
+ const template = loadJson(TEMPLATE_PATH);
35
+ if (!template) {
36
+ console.error('ERROR: Could not load template from:', TEMPLATE_PATH);
37
+ process.exit(1);
38
+ }
39
+
40
+ // Load or create settings
41
+ let settings = loadJson(SETTINGS_PATH);
42
+ if (!settings) {
43
+ console.log('Creating new .claude/settings.json...');
44
+ fs.mkdirSync(path.dirname(SETTINGS_PATH), { recursive: true });
45
+ settings = { permissions: { allow: [], deny: [], ask: [] } };
46
+ }
47
+
48
+ // Ensure permissions structure exists
49
+ settings.permissions = settings.permissions || { allow: [], deny: [], ask: [] };
50
+ settings.permissions.allow = settings.permissions.allow || [];
51
+ settings.permissions.ask = settings.permissions.ask || [];
52
+ settings.permissions.deny = settings.permissions.deny || [];
53
+
54
+ // Count before
55
+ const beforeAllow = settings.permissions.allow.length;
56
+ const beforeAsk = settings.permissions.ask.length;
57
+
58
+ // Merge permissions
59
+ settings.permissions.allow = mergeArrays(settings.permissions.allow, template.permissions.allow);
60
+ settings.permissions.ask = mergeArrays(settings.permissions.ask, template.permissions.ask);
61
+
62
+ // Enable plugin
63
+ settings.enabledPlugins = settings.enabledPlugins || {};
64
+ settings.enabledPlugins['flow-external@mobilems'] = true;
65
+
66
+ // Write back
67
+ fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n');
68
+
69
+ // Report
70
+ const addedAllow = settings.permissions.allow.length - beforeAllow;
71
+ const addedAsk = settings.permissions.ask.length - beforeAsk;
72
+
73
+ console.log('Permissions merged successfully!\n');
74
+ console.log(` allow: ${beforeAllow} -> ${settings.permissions.allow.length} (+${addedAllow})`);
75
+ console.log(` ask: ${beforeAsk} -> ${settings.permissions.ask.length} (+${addedAsk})`);
76
+ console.log(`\nPlugin enabled: flow-external@mobilems`);
77
+ console.log(`\nFile updated: ${SETTINGS_PATH}`);
78
+ }
79
+
80
+ main();
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "flow-external",
3
+ "description": "Development flow skills for standalone Angular 6-11 museum projects without framework (Angular CLI, Karma/Jasmine, Bootstrap 4)",
4
+ "version": "2.78.0"
5
+ }
@@ -0,0 +1,75 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/anthropics/claude-code/main/schemas/settings.schema.json",
3
+ "_description": "Template permissions for flow-external@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(ng:*)",
17
+ "Bash(npx ng:*)",
18
+ "Bash(npx tsc:*)",
19
+ "Bash(npm start)",
20
+ "Bash(npm run:*)",
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-server__get_issue",
38
+ "mcp__linear-server__list_issues",
39
+ "mcp__linear-server__list_comments",
40
+ "mcp__linear-server__create_comment",
41
+ "mcp__linear-server__delete_comment",
42
+ "mcp__linear-server__update_issue",
43
+ "mcp__linear-server__list_issue_statuses",
44
+ "mcp__linear-server__create_issue",
45
+ "mcp__playwright__browser_snapshot",
46
+ "mcp__playwright__browser_take_screenshot",
47
+ "mcp__playwright__browser_navigate",
48
+ "mcp__playwright__browser_close",
49
+ "mcp__playwright__browser_wait_for",
50
+ "mcp__playwright__browser_click",
51
+ "mcp__playwright__browser_resize",
52
+ "mcp__playwright__browser_evaluate",
53
+ "mcp__playwright__browser_console_messages",
54
+ "mcp__playwright__browser_press_key",
55
+ "mcp__playwright__browser_network_requests",
56
+ "Skill(flow-external:maia-files-upload)",
57
+ "Skill(flow-external:maia-files-delete)",
58
+ "Skill(flow-external:browser-capture)",
59
+ "Skill(flow-external:linear-suggestion)",
60
+ "Skill(flow-external:a11y-audit)"
61
+ ],
62
+ "ask": [
63
+ "Skill(flow-external:commit)",
64
+ "Skill(flow-external:impl)",
65
+ "Skill(flow-external:plan)",
66
+ "Skill(flow-external:push)",
67
+ "Bash(git commit:*)",
68
+ "Bash(git push:*)",
69
+ "Bash(gh pr create:*)"
70
+ ]
71
+ },
72
+ "enabledPlugins": {
73
+ "flow-external@mobilems": true
74
+ }
75
+ }
@@ -0,0 +1,269 @@
1
+ ---
2
+ name: angular-component-scaffolder
3
+ description: Create Angular 6-11 components with NgModules and legacy patterns. Use when scaffolding new components for standalone museum projects (Bootstrap 4, *ngIf/*ngFor, constructor DI).
4
+ tools: Read, Write, Glob, Grep
5
+ model: sonnet
6
+ color: "#DD0031"
7
+ ---
8
+
9
+ You are an expert at creating Angular components for standalone museum projects (Angular 6-11).
10
+
11
+ ## Primary Responsibility
12
+
13
+ Create Angular components using Angular 6-11 patterns including NgModules, `*ngIf`/`*ngFor`, constructor injection, `@Input()`/`@Output()` decorators, and Bootstrap 4 styling.
14
+
15
+ ## When to Use
16
+
17
+ - Creating new Angular components in standalone Angular CLI projects
18
+ - Scaffolding component structure with template and styles
19
+ - Setting up component with proper constructor DI and Bootstrap 4
20
+
21
+ ## CRITICAL: Angular 6-11 Patterns (MANDATORY)
22
+
23
+ **NEVER use modern Angular patterns. ALWAYS use these legacy patterns:**
24
+
25
+ | Feature | CORRECT (Angular 6-11) | WRONG (Angular 14+/20+) |
26
+ |---------|------------------------|-------------------------|
27
+ | Control flow | `*ngIf`, `*ngFor` | `@if`, `@for` |
28
+ | DI | Constructor injection | `inject()` |
29
+ | Inputs | `@Input()` decorator | `input()`, `input.required()` |
30
+ | Outputs | `@Output()` decorator | `output()` |
31
+ | Two-way binding | `@Input()` + `@Output()` | `model()` |
32
+ | State | Class properties, BehaviorSubject | `signal()` |
33
+ | Derived state | Getters | `computed()` |
34
+ | Styling | Bootstrap 4 + SCSS | Tailwind CSS |
35
+ | Components | NgModules | Standalone |
36
+
37
+ ## Project-Specific Patterns
38
+
39
+ These projects use:
40
+
41
+ - **NgModules** - components must be declared in modules
42
+ - **`*ngIf` and `*ngFor`** for control flow
43
+ - **Constructor injection** for DI
44
+ - **`@Input()` and `@Output()`** decorators
45
+ - **Bootstrap 4** with ng-bootstrap for UI
46
+ - **ngx-translate** for i18n (`TranslateModule`, `| translate` pipe)
47
+ - **SCSS** for styles (not Tailwind)
48
+ - **No signals** - use class properties and BehaviorSubject
49
+
50
+ ## Component Templates
51
+
52
+ ### Basic Component
53
+
54
+ ```typescript
55
+ import { Component, OnInit, OnDestroy } from '@angular/core';
56
+ import { Subject } from 'rxjs';
57
+ import { takeUntil } from 'rxjs/operators';
58
+
59
+ @Component({
60
+ selector: 'app-feature-name',
61
+ templateUrl: './feature-name.component.html',
62
+ styleUrls: ['./feature-name.component.scss'],
63
+ })
64
+ export class FeatureNameComponent implements OnInit, OnDestroy {
65
+ isLoading = false;
66
+ data: DataType[] = [];
67
+ error: string | null = null;
68
+
69
+ private readonly destroy$ = new Subject<void>();
70
+
71
+ constructor(
72
+ private readonly dataService: DataService,
73
+ private readonly router: Router
74
+ ) {}
75
+
76
+ ngOnInit(): void {
77
+ this.loadData();
78
+ }
79
+
80
+ ngOnDestroy(): void {
81
+ this.destroy$.next();
82
+ this.destroy$.complete();
83
+ }
84
+
85
+ private loadData(): void {
86
+ this.isLoading = true;
87
+ this.dataService.getData()
88
+ .pipe(takeUntil(this.destroy$))
89
+ .subscribe({
90
+ next: (data) => {
91
+ this.data = data;
92
+ this.isLoading = false;
93
+ },
94
+ error: (err) => {
95
+ this.error = err.message;
96
+ this.isLoading = false;
97
+ },
98
+ });
99
+ }
100
+
101
+ get itemCount(): number {
102
+ return this.data.length;
103
+ }
104
+
105
+ get hasData(): boolean {
106
+ return this.data.length > 0;
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### Component with Inputs/Outputs
112
+
113
+ ```typescript
114
+ import { Component, Input, Output, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
115
+
116
+ @Component({
117
+ selector: 'app-item-card',
118
+ templateUrl: './item-card.component.html',
119
+ styleUrls: ['./item-card.component.scss'],
120
+ })
121
+ export class ItemCardComponent implements OnChanges {
122
+ @Input() label!: string;
123
+ @Input() item!: Item;
124
+ @Input() showActions = true;
125
+
126
+ @Output() selected = new EventEmitter<Item>();
127
+ @Output() closed = new EventEmitter<void>();
128
+
129
+ isOpen = false;
130
+
131
+ ngOnChanges(changes: SimpleChanges): void {
132
+ if (changes['item']) {
133
+ console.log('Item changed:', this.item);
134
+ }
135
+ }
136
+
137
+ onSelect(): void {
138
+ this.selected.emit(this.item);
139
+ }
140
+
141
+ onClose(): void {
142
+ this.closed.emit();
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## Template Patterns (Bootstrap 4 + ngx-translate)
148
+
149
+ ```html
150
+ <!-- Loading state -->
151
+ <div *ngIf="isLoading" class="d-flex justify-content-center p-5">
152
+ <div class="spinner-border text-primary" role="status">
153
+ <span class="sr-only">{{ 'COMMON.loading' | translate }}</span>
154
+ </div>
155
+ </div>
156
+
157
+ <!-- Error state -->
158
+ <div *ngIf="error" class="alert alert-danger" role="alert">
159
+ {{ error }}
160
+ </div>
161
+
162
+ <!-- Content -->
163
+ <div *ngIf="!isLoading && !error">
164
+ <div class="row" *ngIf="hasData; else emptyTemplate">
165
+ <div class="col-md-4 mb-4" *ngFor="let item of data; trackBy: trackByFn">
166
+ <div class="card h-100">
167
+ <img *ngIf="item.image" [src]="item.image" class="card-img-top" [alt]="item.title">
168
+ <div class="card-body">
169
+ <h5 class="card-title">{{ item.title }}</h5>
170
+ <p class="card-text">{{ item.description | truncate:150 }}</p>
171
+ </div>
172
+ <div class="card-footer">
173
+ <button class="btn btn-primary btn-sm" (click)="onSelect(item)">
174
+ {{ 'COMMON.details' | translate }}
175
+ </button>
176
+ </div>
177
+ </div>
178
+ </div>
179
+ </div>
180
+
181
+ <ng-template #emptyTemplate>
182
+ <div class="text-center p-5 text-muted">
183
+ <p>{{ 'COMMON.noItems' | translate }}</p>
184
+ </div>
185
+ </ng-template>
186
+ </div>
187
+ ```
188
+
189
+ ### TrackBy Function
190
+
191
+ ```typescript
192
+ trackByFn(index: number, item: Item): string {
193
+ return item.id;
194
+ }
195
+ ```
196
+
197
+ ## SCSS Styling (Bootstrap 4)
198
+
199
+ ```scss
200
+ :host {
201
+ display: block;
202
+ }
203
+
204
+ .card {
205
+ transition: box-shadow 0.2s ease;
206
+
207
+ &:hover {
208
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
209
+ }
210
+
211
+ .card-img-top {
212
+ height: 200px;
213
+ object-fit: cover;
214
+ }
215
+ }
216
+ ```
217
+
218
+ ## Module Declaration
219
+
220
+ ```typescript
221
+ import { NgModule } from '@angular/core';
222
+ import { CommonModule } from '@angular/common';
223
+ import { TranslateModule } from '@ngx-translate/core';
224
+ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
225
+
226
+ import { FeatureNameComponent } from './feature-name.component';
227
+ import { ItemCardComponent } from './item-card/item-card.component';
228
+
229
+ @NgModule({
230
+ declarations: [
231
+ FeatureNameComponent,
232
+ ItemCardComponent,
233
+ ],
234
+ imports: [
235
+ CommonModule,
236
+ TranslateModule,
237
+ NgbModule,
238
+ ],
239
+ exports: [
240
+ FeatureNameComponent,
241
+ ItemCardComponent,
242
+ ],
243
+ })
244
+ export class FeatureModule {}
245
+ ```
246
+
247
+ ## File Structure
248
+
249
+ ```
250
+ feature-name/
251
+ feature-name.component.ts
252
+ feature-name.component.html
253
+ feature-name.component.scss
254
+ feature-name.component.spec.ts
255
+ feature-name.module.ts
256
+ ```
257
+
258
+ ## Checklist
259
+
260
+ - [ ] Uses NgModule (NOT standalone)
261
+ - [ ] Uses constructor injection (NOT `inject()`)
262
+ - [ ] Uses `@Input()` / `@Output()` decorators (NOT `input()` / `output()`)
263
+ - [ ] Uses `*ngIf` / `*ngFor` in template (NOT `@if` / `@for`)
264
+ - [ ] Has `trackBy` function for all `*ngFor` loops
265
+ - [ ] Uses Bootstrap 4 classes for layout (NOT Tailwind)
266
+ - [ ] Uses ngx-translate `| translate` pipe for i18n
267
+ - [ ] Has `OnDestroy` with Subject for cleanup
268
+ - [ ] Declared in a module with TranslateModule and NgbModule imports
269
+ - [ ] Has proper TypeScript types