@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.
- package/.claude-plugin/marketplace.json +26 -0
- package/README.md +56 -0
- package/package.json +14 -0
- package/plugins/flow/.claude-plugin/README.md +91 -0
- package/plugins/flow/.claude-plugin/merge-permissions.js +115 -0
- package/plugins/flow/.claude-plugin/plugin.json +5 -0
- package/plugins/flow/.claude-plugin/settings.template.json +86 -0
- package/plugins/flow/agents/angular-component-scaffolder.md +176 -0
- package/plugins/flow/agents/angular-directive-builder.md +154 -0
- package/plugins/flow/agents/angular-guard-builder.md +244 -0
- package/plugins/flow/agents/angular-jest-test-writer.md +475 -0
- package/plugins/flow/agents/angular-pipe-builder.md +170 -0
- package/plugins/flow/agents/angular-resolver-builder.md +287 -0
- package/plugins/flow/agents/angular-service-builder.md +162 -0
- package/plugins/flow/agents/angular-signal-state-builder.md +340 -0
- package/plugins/flow/agents/angular-test-diagnostician.md +279 -0
- package/plugins/flow/agents/angular-testbed-configurator.md +315 -0
- package/plugins/flow/agents/arch-scaffolder.md +278 -0
- package/plugins/flow/agents/e2e-data-testid-injector.md +195 -0
- package/plugins/flow/agents/e2e-project-scaffolder.md +194 -0
- package/plugins/flow/agents/e2e-test-writer.md +357 -0
- package/plugins/flow/agents/shared-agent-evolver.md +294 -0
- package/plugins/flow/agents/shared-build-verifier.md +160 -0
- package/plugins/flow/agents/shared-config-updater.md +310 -0
- package/plugins/flow/agents/shared-coverage-enforcer.md +184 -0
- package/plugins/flow/agents/shared-error-handler.md +217 -0
- package/plugins/flow/agents/shared-file-creator.md +344 -0
- package/plugins/flow/agents/shared-impl-orchestrator.md +312 -0
- package/plugins/flow/agents/shared-impl-reporter.md +368 -0
- package/plugins/flow/agents/shared-impl-teammate.md +201 -0
- package/plugins/flow/agents/shared-linear-subtask-iterator.md +337 -0
- package/plugins/flow/agents/shared-logic-implementer.md +244 -0
- package/plugins/flow/agents/shared-maia-api.md +26 -0
- package/plugins/flow/agents/shared-parallelization-analyzer.md +343 -0
- package/plugins/flow/agents/shared-performance-validator.md +168 -0
- package/plugins/flow/agents/shared-plan-perspective.md +271 -0
- package/plugins/flow/agents/shared-project-standardizer.md +205 -0
- package/plugins/flow/agents/shared-report-synthesizer.md +188 -0
- package/plugins/flow/agents/shared-review-teammate.md +189 -0
- package/plugins/flow/agents/shared-security-scanner.md +186 -0
- package/plugins/flow/agents/shared-style-enforcer.md +230 -0
- package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +189 -0
- package/plugins/flow/agents/shared-tdd-developer.md +350 -0
- package/plugins/flow/agents/shared-team-coordinator.md +192 -0
- package/plugins/flow/agents/shared-test-fixer.md +186 -0
- package/plugins/flow/agents/shared-test-runner.md +191 -0
- package/plugins/flow/agents/shared-ui-classifier.md +263 -0
- package/plugins/flow/agents/shared-verification-orchestrator.md +194 -0
- package/plugins/flow/agents/shared-verification-runner.md +140 -0
- package/plugins/flow/agents/ui-a11y-validator.md +305 -0
- package/plugins/flow/agents/ui-screenshot-reporter.md +329 -0
- package/plugins/flow/agents/ui-web-designer.md +214 -0
- package/plugins/flow/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow/skills/angular-patterns/SKILL.md +191 -0
- package/plugins/flow/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow/skills/commit/SKILL.md +259 -0
- package/plugins/flow/skills/debug-helper/SKILL.md +375 -0
- package/plugins/flow/skills/impl/SKILL.md +992 -0
- package/plugins/flow/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow/skills/nx-conventions/SKILL.md +326 -0
- package/plugins/flow/skills/plan/SKILL.md +1033 -0
- package/plugins/flow/skills/push/SKILL.md +759 -0
- package/plugins/flow/skills/review/SKILL.md +443 -0
- package/plugins/flow/skills/test-e2e/SKILL.md +164 -0
- package/plugins/flow/skills/test-unit/SKILL.md +456 -0
- package/plugins/flow-external/.claude-plugin/README.md +146 -0
- package/plugins/flow-external/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-external/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-external/.claude-plugin/settings.template.json +78 -0
- package/plugins/flow-external/agents/angular-component-scaffolder.md +271 -0
- package/plugins/flow-external/agents/angular-directive-builder.md +134 -0
- package/plugins/flow-external/agents/angular-guard-builder.md +73 -0
- package/plugins/flow-external/agents/angular-pipe-builder.md +90 -0
- package/plugins/flow-external/agents/angular-resolver-builder.md +79 -0
- package/plugins/flow-external/agents/angular-service-builder.md +168 -0
- package/plugins/flow-external/agents/angular-state-builder.md +263 -0
- package/plugins/flow-external/agents/shared-build-verifier.md +67 -0
- package/plugins/flow-external/agents/shared-impl-orchestrator.md +90 -0
- package/plugins/flow-external/agents/shared-impl-reporter.md +135 -0
- package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +70 -0
- package/plugins/flow-external/agents/shared-ui-classifier.md +38 -0
- package/plugins/flow-external/agents/ui-web-designer.md +203 -0
- package/plugins/flow-external/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-external/skills/a11y-audit/SKILL.md +97 -0
- package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +268 -0
- package/plugins/flow-external/skills/angular-patterns/SKILL.md +182 -0
- package/plugins/flow-external/skills/browser-capture/SKILL.md +74 -0
- package/plugins/flow-external/skills/commit/SKILL.md +114 -0
- package/plugins/flow-external/skills/debug-helper/SKILL.md +135 -0
- package/plugins/flow-external/skills/impl/SKILL.md +218 -0
- package/plugins/flow-external/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-external/skills/linear-suggestion/SKILL.md +62 -0
- package/plugins/flow-external/skills/maia-files-delete/SKILL.md +34 -0
- package/plugins/flow-external/skills/maia-files-upload/SKILL.md +41 -0
- package/plugins/flow-external/skills/plan/SKILL.md +334 -0
- package/plugins/flow-external/skills/push/SKILL.md +232 -0
- package/plugins/flow-legacy/.claude-plugin/README.md +143 -0
- package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +94 -0
- package/plugins/flow-legacy/.claude-plugin/plugin.json +5 -0
- package/plugins/flow-legacy/.claude-plugin/settings.template.json +79 -0
- package/plugins/flow-legacy/agents/angular-component-scaffolder.md +327 -0
- package/plugins/flow-legacy/agents/angular-directive-builder.md +253 -0
- package/plugins/flow-legacy/agents/angular-guard-builder.md +326 -0
- package/plugins/flow-legacy/agents/angular-pipe-builder.md +238 -0
- package/plugins/flow-legacy/agents/angular-resolver-builder.md +339 -0
- package/plugins/flow-legacy/agents/angular-service-builder.md +271 -0
- package/plugins/flow-legacy/agents/angular-state-builder.md +480 -0
- package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +174 -0
- package/plugins/flow-legacy/agents/shared-impl-reporter.md +232 -0
- package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +198 -0
- package/plugins/flow-legacy/agents/shared-tdd-developer.md +307 -0
- package/plugins/flow-legacy/agents/shared-test-runner.md +133 -0
- package/plugins/flow-legacy/agents/shared-ui-classifier.md +145 -0
- package/plugins/flow-legacy/scripts/compute-session-tokens.sh +39 -0
- package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +214 -0
- package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +346 -0
- package/plugins/flow-legacy/skills/browser-capture/SKILL.md +238 -0
- package/plugins/flow-legacy/skills/commit/SKILL.md +215 -0
- package/plugins/flow-legacy/skills/debug-helper/SKILL.md +395 -0
- package/plugins/flow-legacy/skills/impl/SKILL.md +710 -0
- package/plugins/flow-legacy/skills/karpathy-guidelines/SKILL.md +72 -0
- package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +132 -0
- package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +59 -0
- package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +57 -0
- package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +368 -0
- package/plugins/flow-legacy/skills/plan/SKILL.md +742 -0
- package/plugins/flow-legacy/skills/push/SKILL.md +645 -0
- package/plugins/flow-legacy/skills/test-unit/SKILL.md +500 -0
- package/plugins/smart-pro/.claude-plugin/README.md +115 -0
- package/plugins/smart-pro/.claude-plugin/merge-permissions.js +129 -0
- package/plugins/smart-pro/.claude-plugin/plugin.json +5 -0
- package/plugins/smart-pro/.claude-plugin/settings.template.json +94 -0
- package/plugins/smart-pro/agents/angular-components/AGENT.md +214 -0
- package/plugins/smart-pro/hooks/CONFIG.md +198 -0
- package/plugins/smart-pro/hooks/README.md +139 -0
- package/plugins/smart-pro/hooks/audit_logger.py +107 -0
- package/plugins/smart-pro/hooks/auto_format.sh +11 -0
- package/plugins/smart-pro/hooks/hooks.json +79 -0
- package/plugins/smart-pro/hooks/safety_validator.py +129 -0
- package/plugins/smart-pro/hooks/sensitive_file_blocker.py +58 -0
- package/plugins/smart-pro/hooks/skill_validator.py +220 -0
- package/plugins/smart-pro/skills/angular-components-action-panel/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-avatar/SKILL.md +142 -0
- package/plugins/smart-pro/skills/angular-components-badge/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-breadcrumbs/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-button/SKILL.md +146 -0
- package/plugins/smart-pro/skills/angular-components-button-group/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-calendar/SKILL.md +78 -0
- package/plugins/smart-pro/skills/angular-components-card/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-card-heading/SKILL.md +105 -0
- package/plugins/smart-pro/skills/angular-components-command-palette/SKILL.md +168 -0
- package/plugins/smart-pro/skills/angular-components-container/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-description-list/SKILL.md +102 -0
- package/plugins/smart-pro/skills/angular-components-details/SKILL.md +70 -0
- package/plugins/smart-pro/skills/angular-components-divider/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-drawer/SKILL.md +136 -0
- package/plugins/smart-pro/skills/angular-components-dropdown/SKILL.md +131 -0
- package/plugins/smart-pro/skills/angular-components-empty-state/SKILL.md +103 -0
- package/plugins/smart-pro/skills/angular-components-feed/SKILL.md +110 -0
- package/plugins/smart-pro/skills/angular-components-form/SKILL.md +77 -0
- package/plugins/smart-pro/skills/angular-components-grid-list/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-input/SKILL.md +118 -0
- package/plugins/smart-pro/skills/angular-components-list/SKILL.md +75 -0
- package/plugins/smart-pro/skills/angular-components-list-container/SKILL.md +106 -0
- package/plugins/smart-pro/skills/angular-components-media-object/SKILL.md +133 -0
- package/plugins/smart-pro/skills/angular-components-modal/SKILL.md +159 -0
- package/plugins/smart-pro/skills/angular-components-multi-column-layout/SKILL.md +84 -0
- package/plugins/smart-pro/skills/angular-components-navbar/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-notification/SKILL.md +147 -0
- package/plugins/smart-pro/skills/angular-components-page/SKILL.md +162 -0
- package/plugins/smart-pro/skills/angular-components-page-heading/SKILL.md +96 -0
- package/plugins/smart-pro/skills/angular-components-paging/SKILL.md +86 -0
- package/plugins/smart-pro/skills/angular-components-progress-bars/SKILL.md +94 -0
- package/plugins/smart-pro/skills/angular-components-searchbar/SKILL.md +113 -0
- package/plugins/smart-pro/skills/angular-components-section-heading/SKILL.md +156 -0
- package/plugins/smart-pro/skills/angular-components-select-menu/SKILL.md +101 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-layout/SKILL.md +121 -0
- package/plugins/smart-pro/skills/angular-components-sidebar-navigation/SKILL.md +80 -0
- package/plugins/smart-pro/skills/angular-components-sign-in-form/SKILL.md +91 -0
- package/plugins/smart-pro/skills/angular-components-stacked-layout/SKILL.md +114 -0
- package/plugins/smart-pro/skills/angular-components-stacked-list/SKILL.md +93 -0
- package/plugins/smart-pro/skills/angular-components-stats/SKILL.md +87 -0
- package/plugins/smart-pro/skills/angular-components-table/SKILL.md +98 -0
- package/plugins/smart-pro/skills/angular-components-tabs/SKILL.md +99 -0
- package/plugins/smart-pro/skills/angular-components-textarea/SKILL.md +111 -0
- package/plugins/smart-pro/skills/angular-components-toggle/SKILL.md +109 -0
- package/plugins/smart-pro/skills/angular-components-vertical-navigation/SKILL.md +139 -0
- package/plugins/smart-pro/skills/audit-log/SKILL.md +82 -0
- package/plugins/smart-pro/skills/format-code/SKILL.md +46 -0
- package/plugins/smart-pro/skills/project-conventions/SKILL.md +90 -0
- package/plugins/smart-pro/skills/safety-check/SKILL.md +0 -0
- package/src/index.d.ts +6 -0
- package/src/index.js +7 -0
- package/src/index.js.map +1 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/anthropics/claude-code/main/schemas/settings.schema.json",
|
|
3
|
+
"_description": "Template permissions for flow-external@smart-pro 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__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-external:maia-files-upload)",
|
|
60
|
+
"Skill(flow-external:maia-files-delete)",
|
|
61
|
+
"Skill(flow-external:browser-capture)",
|
|
62
|
+
"Skill(flow-external:linear-suggestion)",
|
|
63
|
+
"Skill(flow-external:a11y-audit)"
|
|
64
|
+
],
|
|
65
|
+
"ask": [
|
|
66
|
+
"Skill(flow-external:commit)",
|
|
67
|
+
"Skill(flow-external:impl)",
|
|
68
|
+
"Skill(flow-external:plan)",
|
|
69
|
+
"Skill(flow-external:push)",
|
|
70
|
+
"Bash(git commit:*)",
|
|
71
|
+
"Bash(git push:*)",
|
|
72
|
+
"Bash(gh pr create:*)"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"enabledPlugins": {
|
|
76
|
+
"flow-external@smart-pro": true
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
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
|
+
skills: karpathy-guidelines
|
|
6
|
+
model: sonnet
|
|
7
|
+
color: '#DD0031'
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an expert at creating Angular components for standalone museum projects (Angular 6-11).
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create Angular components using Angular 6-11 patterns including NgModules, `*ngIf`/`*ngFor`, constructor injection, `@Input()`/`@Output()` decorators, and Bootstrap 4 styling.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- Creating new Angular components in standalone Angular CLI projects
|
|
19
|
+
- Scaffolding component structure with template and styles
|
|
20
|
+
- Setting up component with proper constructor DI and Bootstrap 4
|
|
21
|
+
|
|
22
|
+
## CRITICAL: Angular 6-11 Patterns (MANDATORY)
|
|
23
|
+
|
|
24
|
+
**NEVER use modern Angular patterns. ALWAYS use these legacy patterns:**
|
|
25
|
+
|
|
26
|
+
| Feature | CORRECT (Angular 6-11) | WRONG (Angular 14+/20+) |
|
|
27
|
+
| --------------- | --------------------------------- | ----------------------------- |
|
|
28
|
+
| Control flow | `*ngIf`, `*ngFor` | `@if`, `@for` |
|
|
29
|
+
| DI | Constructor injection | `inject()` |
|
|
30
|
+
| Inputs | `@Input()` decorator | `input()`, `input.required()` |
|
|
31
|
+
| Outputs | `@Output()` decorator | `output()` |
|
|
32
|
+
| Two-way binding | `@Input()` + `@Output()` | `model()` |
|
|
33
|
+
| State | Class properties, BehaviorSubject | `signal()` |
|
|
34
|
+
| Derived state | Getters | `computed()` |
|
|
35
|
+
| Styling | Bootstrap 4 + SCSS | Tailwind CSS |
|
|
36
|
+
| Components | NgModules | Standalone |
|
|
37
|
+
|
|
38
|
+
## Project-Specific Patterns
|
|
39
|
+
|
|
40
|
+
These projects use:
|
|
41
|
+
|
|
42
|
+
- **NgModules** - components must be declared in modules
|
|
43
|
+
- **`*ngIf` and `*ngFor`** for control flow
|
|
44
|
+
- **Constructor injection** for DI
|
|
45
|
+
- **`@Input()` and `@Output()`** decorators
|
|
46
|
+
- **Bootstrap 4** with ng-bootstrap for UI
|
|
47
|
+
- **ngx-translate** for i18n (`TranslateModule`, `| translate` pipe)
|
|
48
|
+
- **SCSS** for styles (not Tailwind)
|
|
49
|
+
- **No signals** - use class properties and BehaviorSubject
|
|
50
|
+
|
|
51
|
+
## Component Templates
|
|
52
|
+
|
|
53
|
+
### Basic Component
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
57
|
+
import { Subject } from 'rxjs';
|
|
58
|
+
import { takeUntil } from 'rxjs/operators';
|
|
59
|
+
|
|
60
|
+
@Component({
|
|
61
|
+
selector: 'app-feature-name',
|
|
62
|
+
templateUrl: './feature-name.component.html',
|
|
63
|
+
styleUrls: ['./feature-name.component.scss'],
|
|
64
|
+
})
|
|
65
|
+
export class FeatureNameComponent implements OnInit, OnDestroy {
|
|
66
|
+
isLoading = false;
|
|
67
|
+
data: DataType[] = [];
|
|
68
|
+
error: string | null = null;
|
|
69
|
+
|
|
70
|
+
private readonly destroy$ = new Subject<void>();
|
|
71
|
+
|
|
72
|
+
constructor(
|
|
73
|
+
private readonly dataService: DataService,
|
|
74
|
+
private readonly router: Router,
|
|
75
|
+
) {}
|
|
76
|
+
|
|
77
|
+
ngOnInit(): void {
|
|
78
|
+
this.loadData();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
ngOnDestroy(): void {
|
|
82
|
+
this.destroy$.next();
|
|
83
|
+
this.destroy$.complete();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private loadData(): void {
|
|
87
|
+
this.isLoading = true;
|
|
88
|
+
this.dataService
|
|
89
|
+
.getData()
|
|
90
|
+
.pipe(takeUntil(this.destroy$))
|
|
91
|
+
.subscribe({
|
|
92
|
+
next: (data) => {
|
|
93
|
+
this.data = data;
|
|
94
|
+
this.isLoading = false;
|
|
95
|
+
},
|
|
96
|
+
error: (err) => {
|
|
97
|
+
this.error = err.message;
|
|
98
|
+
this.isLoading = false;
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get itemCount(): number {
|
|
104
|
+
return this.data.length;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get hasData(): boolean {
|
|
108
|
+
return this.data.length > 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Component with Inputs/Outputs
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import {
|
|
117
|
+
Component,
|
|
118
|
+
Input,
|
|
119
|
+
Output,
|
|
120
|
+
EventEmitter,
|
|
121
|
+
OnChanges,
|
|
122
|
+
SimpleChanges,
|
|
123
|
+
} from '@angular/core';
|
|
124
|
+
|
|
125
|
+
@Component({
|
|
126
|
+
selector: 'app-item-card',
|
|
127
|
+
templateUrl: './item-card.component.html',
|
|
128
|
+
styleUrls: ['./item-card.component.scss'],
|
|
129
|
+
})
|
|
130
|
+
export class ItemCardComponent implements OnChanges {
|
|
131
|
+
@Input() label!: string;
|
|
132
|
+
@Input() item!: Item;
|
|
133
|
+
@Input() showActions = true;
|
|
134
|
+
|
|
135
|
+
@Output() selected = new EventEmitter<Item>();
|
|
136
|
+
@Output() closed = new EventEmitter<void>();
|
|
137
|
+
|
|
138
|
+
isOpen = false;
|
|
139
|
+
|
|
140
|
+
ngOnChanges(changes: SimpleChanges): void {
|
|
141
|
+
if (changes['item']) {
|
|
142
|
+
console.log('Item changed:', this.item);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
onSelect(): void {
|
|
147
|
+
this.selected.emit(this.item);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
onClose(): void {
|
|
151
|
+
this.closed.emit();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Template Patterns (Bootstrap 4 + ngx-translate)
|
|
157
|
+
|
|
158
|
+
```html
|
|
159
|
+
<!-- Loading state -->
|
|
160
|
+
<div *ngIf="isLoading" class="d-flex justify-content-center p-5">
|
|
161
|
+
<div class="spinner-border text-primary" role="status">
|
|
162
|
+
<span class="sr-only">{{ 'COMMON.loading' | translate }}</span>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<!-- Error state -->
|
|
167
|
+
<div *ngIf="error" class="alert alert-danger" role="alert">{{ error }}</div>
|
|
168
|
+
|
|
169
|
+
<!-- Content -->
|
|
170
|
+
<div *ngIf="!isLoading && !error">
|
|
171
|
+
<div class="row" *ngIf="hasData; else emptyTemplate">
|
|
172
|
+
<div class="col-md-4 mb-4" *ngFor="let item of data; trackBy: trackByFn">
|
|
173
|
+
<div class="card h-100">
|
|
174
|
+
<img
|
|
175
|
+
*ngIf="item.image"
|
|
176
|
+
[src]="item.image"
|
|
177
|
+
class="card-img-top"
|
|
178
|
+
[alt]="item.title"
|
|
179
|
+
/>
|
|
180
|
+
<div class="card-body">
|
|
181
|
+
<h5 class="card-title">{{ item.title }}</h5>
|
|
182
|
+
<p class="card-text">{{ item.description | truncate:150 }}</p>
|
|
183
|
+
</div>
|
|
184
|
+
<div class="card-footer">
|
|
185
|
+
<button class="btn btn-primary btn-sm" (click)="onSelect(item)">
|
|
186
|
+
{{ 'COMMON.details' | translate }}
|
|
187
|
+
</button>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<ng-template #emptyTemplate>
|
|
194
|
+
<div class="text-center p-5 text-muted">
|
|
195
|
+
<p>{{ 'COMMON.noItems' | translate }}</p>
|
|
196
|
+
</div>
|
|
197
|
+
</ng-template>
|
|
198
|
+
</div>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### TrackBy Function
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
trackByFn(index: number, item: Item): string {
|
|
205
|
+
return item.id;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## SCSS Styling (Bootstrap 4)
|
|
210
|
+
|
|
211
|
+
```scss
|
|
212
|
+
:host {
|
|
213
|
+
display: block;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.card {
|
|
217
|
+
transition: box-shadow 0.2s ease;
|
|
218
|
+
|
|
219
|
+
&:hover {
|
|
220
|
+
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.card-img-top {
|
|
224
|
+
height: 200px;
|
|
225
|
+
object-fit: cover;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Module Declaration
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { NgModule } from '@angular/core';
|
|
234
|
+
import { CommonModule } from '@angular/common';
|
|
235
|
+
import { TranslateModule } from '@ngx-translate/core';
|
|
236
|
+
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
|
237
|
+
|
|
238
|
+
import { FeatureNameComponent } from './feature-name.component';
|
|
239
|
+
import { ItemCardComponent } from './item-card/item-card.component';
|
|
240
|
+
|
|
241
|
+
@NgModule({
|
|
242
|
+
declarations: [FeatureNameComponent, ItemCardComponent],
|
|
243
|
+
imports: [CommonModule, TranslateModule, NgbModule],
|
|
244
|
+
exports: [FeatureNameComponent, ItemCardComponent],
|
|
245
|
+
})
|
|
246
|
+
export class FeatureModule {}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## File Structure
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
feature-name/
|
|
253
|
+
feature-name.component.ts
|
|
254
|
+
feature-name.component.html
|
|
255
|
+
feature-name.component.scss
|
|
256
|
+
feature-name.component.spec.ts
|
|
257
|
+
feature-name.module.ts
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Checklist
|
|
261
|
+
|
|
262
|
+
- [ ] Uses NgModule (NOT standalone)
|
|
263
|
+
- [ ] Uses constructor injection (NOT `inject()`)
|
|
264
|
+
- [ ] Uses `@Input()` / `@Output()` decorators (NOT `input()` / `output()`)
|
|
265
|
+
- [ ] Uses `*ngIf` / `*ngFor` in template (NOT `@if` / `@for`)
|
|
266
|
+
- [ ] Has `trackBy` function for all `*ngFor` loops
|
|
267
|
+
- [ ] Uses Bootstrap 4 classes for layout (NOT Tailwind)
|
|
268
|
+
- [ ] Uses ngx-translate `| translate` pipe for i18n
|
|
269
|
+
- [ ] Has `OnDestroy` with Subject for cleanup
|
|
270
|
+
- [ ] Declared in a module with TranslateModule and NgbModule imports
|
|
271
|
+
- [ ] Has proper TypeScript types
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-directive-builder
|
|
3
|
+
description: Create Angular 6-11 directives with constructor DI. Use when building attribute or structural directives for standalone museum 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 6-11 directives for standalone museum projects.
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create Angular directives using Angular 6-11 patterns including constructor injection and `@Input()` decorators.
|
|
15
|
+
|
|
16
|
+
## CRITICAL: Angular 6-11 Patterns (MANDATORY)
|
|
17
|
+
|
|
18
|
+
| Feature | CORRECT (Angular 6-11) | WRONG (Angular 14+/20+) |
|
|
19
|
+
| ------------- | ---------------------- | ----------------------- |
|
|
20
|
+
| DI | Constructor injection | `inject()` |
|
|
21
|
+
| Inputs | `@Input()` decorator | `input()` |
|
|
22
|
+
| Host binding | `@HostBinding()` | `host: {}` in decorator |
|
|
23
|
+
| Host listener | `@HostListener()` | `host: {}` in decorator |
|
|
24
|
+
|
|
25
|
+
## Directive Templates
|
|
26
|
+
|
|
27
|
+
### Attribute Directive
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import {
|
|
31
|
+
Directive,
|
|
32
|
+
ElementRef,
|
|
33
|
+
Input,
|
|
34
|
+
OnInit,
|
|
35
|
+
OnDestroy,
|
|
36
|
+
Renderer2,
|
|
37
|
+
HostBinding,
|
|
38
|
+
HostListener,
|
|
39
|
+
} from '@angular/core';
|
|
40
|
+
|
|
41
|
+
@Directive({
|
|
42
|
+
selector: '[appHighlight]',
|
|
43
|
+
})
|
|
44
|
+
export class HighlightDirective implements OnInit, OnDestroy {
|
|
45
|
+
@Input() appHighlight = '';
|
|
46
|
+
@Input() highlightColor = 'yellow';
|
|
47
|
+
|
|
48
|
+
@HostBinding('style.backgroundColor') backgroundColor: string | null = null;
|
|
49
|
+
|
|
50
|
+
constructor(
|
|
51
|
+
private readonly el: ElementRef,
|
|
52
|
+
private readonly renderer: Renderer2,
|
|
53
|
+
) {}
|
|
54
|
+
|
|
55
|
+
ngOnInit(): void {
|
|
56
|
+
this.setBackgroundColor(this.highlightColor);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ngOnDestroy(): void {}
|
|
60
|
+
|
|
61
|
+
@HostListener('mouseenter')
|
|
62
|
+
onMouseEnter(): void {
|
|
63
|
+
this.setBackgroundColor(this.appHighlight || this.highlightColor);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@HostListener('mouseleave')
|
|
67
|
+
onMouseLeave(): void {
|
|
68
|
+
this.setBackgroundColor(null);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private setBackgroundColor(color: string | null): void {
|
|
72
|
+
this.backgroundColor = color;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## WCAG Accessibility Directive (Common Pattern)
|
|
78
|
+
|
|
79
|
+
These museum projects often implement WCAG accessibility directives:
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Directive, HostBinding, Input, OnInit } from '@angular/core';
|
|
83
|
+
|
|
84
|
+
@Directive({
|
|
85
|
+
selector: '[appWcagFontSize]',
|
|
86
|
+
})
|
|
87
|
+
export class WcagFontSizeDirective implements OnInit {
|
|
88
|
+
@Input() appWcagFontSize: 'normal' | 'large' | 'x-large' = 'normal';
|
|
89
|
+
|
|
90
|
+
@HostBinding('style.fontSize') fontSize: string;
|
|
91
|
+
|
|
92
|
+
constructor(private readonly wcagService: WcagService) {}
|
|
93
|
+
|
|
94
|
+
ngOnInit(): void {
|
|
95
|
+
this.wcagService.fontSize$.subscribe((size) => {
|
|
96
|
+
this.fontSize = this.getSizeValue(size);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private getSizeValue(size: string): string {
|
|
101
|
+
switch (size) {
|
|
102
|
+
case 'large':
|
|
103
|
+
return '120%';
|
|
104
|
+
case 'x-large':
|
|
105
|
+
return '150%';
|
|
106
|
+
default:
|
|
107
|
+
return '100%';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Module Declaration
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { NgModule } from '@angular/core';
|
|
117
|
+
|
|
118
|
+
import { HighlightDirective } from './highlight.directive';
|
|
119
|
+
import { WcagFontSizeDirective } from './wcag-font-size.directive';
|
|
120
|
+
|
|
121
|
+
@NgModule({
|
|
122
|
+
declarations: [HighlightDirective, WcagFontSizeDirective],
|
|
123
|
+
exports: [HighlightDirective, WcagFontSizeDirective],
|
|
124
|
+
})
|
|
125
|
+
export class DirectivesModule {}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Checklist
|
|
129
|
+
|
|
130
|
+
- [ ] Uses constructor injection (NOT `inject()`)
|
|
131
|
+
- [ ] Uses `@Input()` decorator (NOT `input()`)
|
|
132
|
+
- [ ] Uses `@HostBinding()` and `@HostListener()`
|
|
133
|
+
- [ ] Implements `OnDestroy` for cleanup
|
|
134
|
+
- [ ] Declared in a module
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-guard-builder
|
|
3
|
+
description: Create Angular 6-11 class-based route guards with constructor DI. Use when building CanActivate, CanDeactivate, or other guards for standalone museum 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 6-11 route guards for standalone museum projects.
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create class-based route guards using Angular 6-11 patterns with constructor injection.
|
|
15
|
+
|
|
16
|
+
## CRITICAL: Angular 6-11 Patterns (MANDATORY)
|
|
17
|
+
|
|
18
|
+
| Feature | CORRECT (Angular 6-11) | WRONG (Angular 15+) |
|
|
19
|
+
| ---------- | ---------------------------- | ------------------- |
|
|
20
|
+
| Guard type | Class implementing interface | Functional guard |
|
|
21
|
+
| DI | Constructor injection | `inject()` |
|
|
22
|
+
|
|
23
|
+
## Guard Template
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { Injectable } from '@angular/core';
|
|
27
|
+
import {
|
|
28
|
+
CanActivate,
|
|
29
|
+
ActivatedRouteSnapshot,
|
|
30
|
+
RouterStateSnapshot,
|
|
31
|
+
Router,
|
|
32
|
+
} from '@angular/router';
|
|
33
|
+
import { Observable } from 'rxjs';
|
|
34
|
+
import { map, take } from 'rxjs/operators';
|
|
35
|
+
|
|
36
|
+
@Injectable({
|
|
37
|
+
providedIn: 'root',
|
|
38
|
+
})
|
|
39
|
+
export class AuthGuard implements CanActivate {
|
|
40
|
+
constructor(
|
|
41
|
+
private readonly authService: AuthService,
|
|
42
|
+
private readonly router: Router,
|
|
43
|
+
) {}
|
|
44
|
+
|
|
45
|
+
canActivate(
|
|
46
|
+
route: ActivatedRouteSnapshot,
|
|
47
|
+
state: RouterStateSnapshot,
|
|
48
|
+
): Observable<boolean> | boolean {
|
|
49
|
+
return this.authService.isAuthenticated$.pipe(
|
|
50
|
+
take(1),
|
|
51
|
+
map((isAuthenticated) => {
|
|
52
|
+
if (isAuthenticated) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
this.router.navigate(['/login'], {
|
|
56
|
+
queryParams: { returnUrl: state.url },
|
|
57
|
+
});
|
|
58
|
+
return false;
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Note: Angular 6-7 guards often use `router.navigate()` instead of `UrlTree` (UrlTree was introduced in Angular 7.1).
|
|
66
|
+
|
|
67
|
+
## Checklist
|
|
68
|
+
|
|
69
|
+
- [ ] Uses class implementing guard interface (NOT functional guard)
|
|
70
|
+
- [ ] Uses constructor injection (NOT `inject()`)
|
|
71
|
+
- [ ] Uses `Observable<boolean>` or `boolean` return
|
|
72
|
+
- [ ] Uses `take(1)` for observable returns
|
|
73
|
+
- [ ] Has `providedIn: 'root'`
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-pipe-builder
|
|
3
|
+
description: Create Angular 6-11 pipes with constructor DI. Use when building transform pipes for templates in standalone museum 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 6-11 pipes for standalone museum projects.
|
|
11
|
+
|
|
12
|
+
## Primary Responsibility
|
|
13
|
+
|
|
14
|
+
Create Angular pipes using Angular 6-11 patterns including constructor injection for dependencies.
|
|
15
|
+
|
|
16
|
+
## CRITICAL: Angular 6-11 Patterns (MANDATORY)
|
|
17
|
+
|
|
18
|
+
| Feature | CORRECT (Angular 6-11) | WRONG (Angular 14+/20+) |
|
|
19
|
+
| ---------- | ---------------------- | ----------------------- |
|
|
20
|
+
| DI | Constructor injection | `inject()` |
|
|
21
|
+
| Standalone | NO (use modules) | `standalone: true` |
|
|
22
|
+
|
|
23
|
+
## Pipe Templates
|
|
24
|
+
|
|
25
|
+
### Pure Pipe
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
29
|
+
|
|
30
|
+
@Pipe({
|
|
31
|
+
name: 'truncate',
|
|
32
|
+
})
|
|
33
|
+
export class TruncatePipe implements PipeTransform {
|
|
34
|
+
transform(
|
|
35
|
+
value: string | null | undefined,
|
|
36
|
+
limit: number = 100,
|
|
37
|
+
ellipsis: string = '...',
|
|
38
|
+
): string {
|
|
39
|
+
if (!value) return '';
|
|
40
|
+
if (value.length <= limit) return value;
|
|
41
|
+
return value.substring(0, limit) + ellipsis;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Pipe with Service Injection
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { Pipe, PipeTransform } from '@angular/core';
|
|
50
|
+
import { TranslateService } from '@ngx-translate/core';
|
|
51
|
+
|
|
52
|
+
@Pipe({
|
|
53
|
+
name: 'localizedDate',
|
|
54
|
+
})
|
|
55
|
+
export class LocalizedDatePipe implements PipeTransform {
|
|
56
|
+
constructor(private readonly translateService: TranslateService) {}
|
|
57
|
+
|
|
58
|
+
transform(
|
|
59
|
+
value: Date | string | null | undefined,
|
|
60
|
+
format: string = 'short',
|
|
61
|
+
): string {
|
|
62
|
+
if (!value) return '';
|
|
63
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
64
|
+
const locale = this.translateService.currentLang || 'pl';
|
|
65
|
+
return date.toLocaleDateString(locale);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Module Declaration
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { NgModule } from '@angular/core';
|
|
74
|
+
|
|
75
|
+
import { TruncatePipe } from './truncate.pipe';
|
|
76
|
+
import { LocalizedDatePipe } from './localized-date.pipe';
|
|
77
|
+
|
|
78
|
+
@NgModule({
|
|
79
|
+
declarations: [TruncatePipe, LocalizedDatePipe],
|
|
80
|
+
exports: [TruncatePipe, LocalizedDatePipe],
|
|
81
|
+
})
|
|
82
|
+
export class PipesModule {}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Checklist
|
|
86
|
+
|
|
87
|
+
- [ ] Uses constructor injection (NOT `inject()`)
|
|
88
|
+
- [ ] Implements `PipeTransform`
|
|
89
|
+
- [ ] Handles null/undefined input
|
|
90
|
+
- [ ] Declared in a module
|