claude-code-pilot 3.1.1 → 3.3.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/CHANGELOG.md +57 -0
- package/README.md +16 -11
- package/bin/install.js +127 -11
- package/manifest.json +20 -1
- package/package.json +4 -3
- package/src/agents/a11y-architect.md +141 -0
- package/src/agents/code-architect.md +71 -0
- package/src/agents/code-explorer.md +69 -0
- package/src/agents/code-simplifier.md +47 -0
- package/src/agents/comment-analyzer.md +45 -0
- package/src/agents/csharp-reviewer.md +101 -0
- package/src/agents/dart-build-resolver.md +201 -0
- package/src/agents/django-build-resolver.md +252 -0
- package/src/agents/django-reviewer.md +169 -0
- package/src/agents/fastapi-reviewer.md +79 -0
- package/src/agents/fsharp-reviewer.md +109 -0
- package/src/agents/pr-test-analyzer.md +45 -0
- package/src/agents/silent-failure-hunter.md +50 -0
- package/src/agents/swift-build-resolver.md +170 -0
- package/src/agents/swift-reviewer.md +116 -0
- package/src/agents/type-design-analyzer.md +41 -0
- package/src/available-rules/README.md +3 -1
- package/src/available-rules/dart/coding-style.md +159 -0
- package/src/available-rules/dart/hooks.md +66 -0
- package/src/available-rules/dart/patterns.md +261 -0
- package/src/available-rules/dart/security.md +135 -0
- package/src/available-rules/dart/testing.md +215 -0
- package/src/available-rules/web/coding-style.md +105 -0
- package/src/available-rules/web/design-quality.md +72 -0
- package/src/available-rules/web/hooks.md +129 -0
- package/src/available-rules/web/patterns.md +88 -0
- package/src/available-rules/web/performance.md +73 -0
- package/src/available-rules/web/security.md +66 -0
- package/src/available-rules/web/testing.md +64 -0
- package/src/commands/ccp/ai-integration-phase.md +36 -0
- package/src/commands/ccp/audit-fix.md +33 -0
- package/src/commands/ccp/code-review-fix.md +52 -0
- package/src/commands/ccp/cost-report.md +107 -0
- package/src/commands/ccp/eval-review.md +32 -0
- package/src/commands/ccp/extract_learnings.md +22 -0
- package/src/commands/ccp/import.md +37 -0
- package/src/commands/ccp/ingest-docs.md +42 -0
- package/src/commands/ccp/intel.md +179 -0
- package/src/commands/ccp/mvp-phase.md +45 -0
- package/src/commands/ccp/plan-prd.md +160 -0
- package/src/commands/ccp/plan-review-convergence.md +58 -0
- package/src/commands/ccp/pr-ecc.md +184 -0
- package/src/commands/ccp/scan.md +26 -0
- package/src/commands/ccp/security-scan.md +74 -0
- package/src/commands/ccp/sketch-wrap-up.md +31 -0
- package/src/commands/ccp/sketch.md +54 -0
- package/src/commands/ccp/spec-phase.md +62 -0
- package/src/commands/ccp/spike-wrap-up.md +31 -0
- package/src/commands/ccp/spike.md +51 -0
- package/src/commands/ccp/ultraplan-phase.md +33 -0
- package/src/hooks/ccp-bash-hook-dispatcher.js +96 -0
- package/src/hooks/ccp-context-monitor.js +23 -0
- package/src/hooks/ccp-doc-file-warning.js +93 -0
- package/src/hooks/ccp-pre-bash-dispatcher.js +24 -0
- package/src/hooks/ccp-read-injection-scanner.js +152 -0
- package/src/hooks/ccp-write-gateguard.js +868 -0
- package/src/hooks/kit-check-update.js +59 -7
- package/src/hooks/run-with-flags-shell.sh +1 -0
- package/src/hooks/run-with-flags.js +48 -1
- package/src/hooks/session-end.js +88 -1
- package/src/lib/hook-flags.js +14 -0
- package/src/lib/project-detect.js +0 -2
- package/src/lib/shell-substitution.js +499 -0
- package/src/pilot/references/agent-contracts.md +79 -0
- package/src/pilot/references/ai-evals.md +156 -0
- package/src/pilot/references/ai-frameworks.md +186 -0
- package/src/pilot/references/doc-conflict-engine.md +91 -0
- package/src/pilot/references/execute-mvp-tdd.md +81 -0
- package/src/pilot/references/gate-prompts.md +100 -0
- package/src/pilot/references/gates.md +70 -0
- package/src/pilot/references/mandatory-initial-read.md +2 -0
- package/src/pilot/references/mvp-concepts.md +49 -0
- package/src/pilot/references/planner-graphify-auto-update.md +67 -0
- package/src/pilot/references/planner-human-verify-mode.md +57 -0
- package/src/pilot/references/planner-mvp-mode.md +53 -0
- package/src/pilot/references/project-skills-discovery.md +19 -0
- package/src/pilot/references/revision-loop.md +97 -0
- package/src/pilot/references/skeleton-template.md +48 -0
- package/src/pilot/references/sketch-interactivity.md +41 -0
- package/src/pilot/references/sketch-theme-system.md +94 -0
- package/src/pilot/references/sketch-tooling.md +45 -0
- package/src/pilot/references/sketch-variant-patterns.md +81 -0
- package/src/pilot/references/spidr-splitting.md +69 -0
- package/src/pilot/references/thinking-models-debug.md +44 -0
- package/src/pilot/references/thinking-models-execution.md +50 -0
- package/src/pilot/references/thinking-models-planning.md +62 -0
- package/src/pilot/references/thinking-models-research.md +50 -0
- package/src/pilot/references/thinking-models-verification.md +55 -0
- package/src/pilot/references/user-story-template.md +58 -0
- package/src/pilot/references/verify-mvp-mode.md +85 -0
- package/src/pilot/references/worktree-path-safety.md +89 -0
- package/src/pilot/templates/AI-SPEC.md +246 -0
- package/src/pilot/templates/spec.md +307 -0
- package/src/pilot/workflows/ai-integration-phase.md +284 -0
- package/src/pilot/workflows/audit-fix.md +175 -0
- package/src/pilot/workflows/code-review-fix.md +497 -0
- package/src/pilot/workflows/eval-review.md +155 -0
- package/src/pilot/workflows/extract_learnings.md +242 -0
- package/src/pilot/workflows/help.md +5 -0
- package/src/pilot/workflows/import.md +246 -0
- package/src/pilot/workflows/ingest-docs.md +328 -0
- package/src/pilot/workflows/mvp-phase.md +199 -0
- package/src/pilot/workflows/plan-review-convergence.md +329 -0
- package/src/pilot/workflows/scan.md +102 -0
- package/src/pilot/workflows/sketch-wrap-up.md +285 -0
- package/src/pilot/workflows/sketch.md +360 -0
- package/src/pilot/workflows/spec-phase.md +262 -0
- package/src/pilot/workflows/spike-wrap-up.md +306 -0
- package/src/pilot/workflows/spike.md +452 -0
- package/src/pilot/workflows/ultraplan-phase.md +189 -0
- package/src/skills/accessibility/SKILL.md +146 -0
- package/src/skills/agent-architecture-audit/SKILL.md +256 -0
- package/src/skills/agent-eval/SKILL.md +145 -0
- package/src/skills/agent-harness-design/SKILL.md +73 -0
- package/src/skills/agent-introspection-debugging/SKILL.md +153 -0
- package/src/skills/android-clean-architecture/SKILL.md +339 -0
- package/src/skills/angular-developer/SKILL.md +154 -0
- package/src/skills/angular-developer/references/angular-animations.md +160 -0
- package/src/skills/angular-developer/references/angular-aria.md +410 -0
- package/src/skills/angular-developer/references/cli.md +86 -0
- package/src/skills/angular-developer/references/component-harnesses.md +59 -0
- package/src/skills/angular-developer/references/component-styling.md +91 -0
- package/src/skills/angular-developer/references/components.md +117 -0
- package/src/skills/angular-developer/references/creating-services.md +97 -0
- package/src/skills/angular-developer/references/data-resolvers.md +69 -0
- package/src/skills/angular-developer/references/define-routes.md +67 -0
- package/src/skills/angular-developer/references/defining-providers.md +72 -0
- package/src/skills/angular-developer/references/di-fundamentals.md +120 -0
- package/src/skills/angular-developer/references/e2e-testing.md +56 -0
- package/src/skills/angular-developer/references/effects.md +83 -0
- package/src/skills/angular-developer/references/hierarchical-injectors.md +43 -0
- package/src/skills/angular-developer/references/host-elements.md +80 -0
- package/src/skills/angular-developer/references/injection-context.md +63 -0
- package/src/skills/angular-developer/references/inputs.md +101 -0
- package/src/skills/angular-developer/references/linked-signal.md +59 -0
- package/src/skills/angular-developer/references/loading-strategies.md +61 -0
- package/src/skills/angular-developer/references/mcp.md +108 -0
- package/src/skills/angular-developer/references/navigate-to-routes.md +69 -0
- package/src/skills/angular-developer/references/outputs.md +86 -0
- package/src/skills/angular-developer/references/reactive-forms.md +122 -0
- package/src/skills/angular-developer/references/rendering-strategies.md +44 -0
- package/src/skills/angular-developer/references/resource.md +77 -0
- package/src/skills/angular-developer/references/route-animations.md +56 -0
- package/src/skills/angular-developer/references/route-guards.md +52 -0
- package/src/skills/angular-developer/references/router-lifecycle.md +45 -0
- package/src/skills/angular-developer/references/router-testing.md +87 -0
- package/src/skills/angular-developer/references/show-routes-with-outlets.md +68 -0
- package/src/skills/angular-developer/references/signal-forms.md +795 -0
- package/src/skills/angular-developer/references/signals-overview.md +94 -0
- package/src/skills/angular-developer/references/tailwind-css.md +69 -0
- package/src/skills/angular-developer/references/template-driven-forms.md +114 -0
- package/src/skills/angular-developer/references/testing-fundamentals.md +65 -0
- package/src/skills/api-connector-builder/SKILL.md +120 -0
- package/src/skills/code-tour/SKILL.md +236 -0
- package/src/skills/compose-multiplatform-patterns/SKILL.md +299 -0
- package/src/skills/csharp-testing/SKILL.md +321 -0
- package/src/skills/dart-flutter-patterns/SKILL.md +563 -0
- package/src/skills/dashboard-builder/SKILL.md +108 -0
- package/src/skills/dotnet-patterns/SKILL.md +321 -0
- package/src/skills/error-handling/SKILL.md +376 -0
- package/src/skills/fastapi-patterns/SKILL.md +327 -0
- package/src/skills/flox-environments/SKILL.md +496 -0
- package/src/skills/frontend-design/SKILL.md +145 -0
- package/src/skills/frontend-slides/SKILL.md +184 -0
- package/src/skills/frontend-slides/STYLE_PRESETS.md +330 -0
- package/src/skills/fsharp-testing/SKILL.md +280 -0
- package/src/skills/gateguard/SKILL.md +121 -0
- package/src/skills/github-ops/SKILL.md +144 -0
- package/src/skills/hookify-rules/SKILL.md +128 -0
- package/src/skills/ios-icon-gen/SKILL.md +157 -0
- package/src/skills/ios-icon-gen/scripts/generate_icons.swift +258 -0
- package/src/skills/ios-icon-gen/scripts/iconify_gen.sh +235 -0
- package/src/skills/knowledge-ops/SKILL.md +154 -0
- package/src/skills/liquid-glass-design/SKILL.md +279 -0
- package/src/skills/make-interfaces-feel-better/SKILL.md +151 -0
- package/src/skills/mysql-patterns/SKILL.md +412 -0
- package/src/skills/nestjs-patterns/SKILL.md +230 -0
- package/src/skills/plan-orchestrate/SKILL.md +220 -0
- package/src/skills/prisma-patterns/SKILL.md +371 -0
- package/src/skills/production-audit/SKILL.md +206 -0
- package/src/skills/security-bounty-hunter/SKILL.md +99 -0
- package/src/skills/security-scan/references/agentshield-policy-exception/candidate-playbook.md +49 -0
- package/src/skills/security-scan/references/agentshield-policy-exception/report.json +35 -0
- package/src/skills/security-scan/references/agentshield-policy-exception/scenario.json +62 -0
- package/src/skills/security-scan/references/agentshield-policy-exception/trace.json +45 -0
- package/src/skills/security-scan/references/agentshield-policy-exception/verifier-result.json +35 -0
- package/src/skills/swift-actor-persistence/SKILL.md +143 -0
- package/src/skills/swift-protocol-di-testing/SKILL.md +190 -0
- package/src/skills/swiftui-patterns/SKILL.md +259 -0
- package/src/skills/terminal-ops/SKILL.md +109 -0
- package/src/skills/ui-demo/SKILL.md +465 -0
- package/src/skills/vite-patterns/SKILL.md +449 -0
- package/src/skills/windows-desktop-e2e/SKILL.md +887 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-introspection-debugging
|
|
3
|
+
description: Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Agent Introspection Debugging
|
|
8
|
+
|
|
9
|
+
Use this skill when an agent run is failing repeatedly, consuming tokens without progress, looping on the same tools, or drifting away from the intended task.
|
|
10
|
+
|
|
11
|
+
This is a workflow skill, not a hidden runtime. It teaches the agent to debug itself systematically before escalating to a human.
|
|
12
|
+
|
|
13
|
+
## When to Activate
|
|
14
|
+
|
|
15
|
+
- Maximum tool call / loop-limit failures
|
|
16
|
+
- Repeated retries with no forward progress
|
|
17
|
+
- Context growth or prompt drift that starts degrading output quality
|
|
18
|
+
- File-system or environment state mismatch between expectation and reality
|
|
19
|
+
- Tool failures that are likely recoverable with diagnosis and a smaller corrective action
|
|
20
|
+
|
|
21
|
+
## Scope Boundaries
|
|
22
|
+
|
|
23
|
+
Activate this skill for:
|
|
24
|
+
- capturing failure state before retrying blindly
|
|
25
|
+
- diagnosing common agent-specific failure patterns
|
|
26
|
+
- applying contained recovery actions
|
|
27
|
+
- producing a structured human-readable debug report
|
|
28
|
+
|
|
29
|
+
Do not use this skill as the primary source for:
|
|
30
|
+
- feature verification after code changes; use `verification-loop`
|
|
31
|
+
- framework-specific debugging when a narrower ECC skill already exists
|
|
32
|
+
- runtime promises the current harness cannot enforce automatically
|
|
33
|
+
|
|
34
|
+
## Four-Phase Loop
|
|
35
|
+
|
|
36
|
+
### Phase 1: Failure Capture
|
|
37
|
+
|
|
38
|
+
Before trying to recover, record the failure precisely.
|
|
39
|
+
|
|
40
|
+
Capture:
|
|
41
|
+
- error type, message, and stack trace when available
|
|
42
|
+
- last meaningful tool call sequence
|
|
43
|
+
- what the agent was trying to do
|
|
44
|
+
- current context pressure: repeated prompts, oversized pasted logs, duplicated plans, or runaway notes
|
|
45
|
+
- current environment assumptions: cwd, branch, relevant service state, expected files
|
|
46
|
+
|
|
47
|
+
Minimum capture template:
|
|
48
|
+
|
|
49
|
+
```markdown
|
|
50
|
+
## Failure Capture
|
|
51
|
+
- Session / task:
|
|
52
|
+
- Goal in progress:
|
|
53
|
+
- Error:
|
|
54
|
+
- Last successful step:
|
|
55
|
+
- Last failed tool / command:
|
|
56
|
+
- Repeated pattern seen:
|
|
57
|
+
- Environment assumptions to verify:
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Phase 2: Root-Cause Diagnosis
|
|
61
|
+
|
|
62
|
+
Match the failure to a known pattern before changing anything.
|
|
63
|
+
|
|
64
|
+
| Pattern | Likely Cause | Check |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| Maximum tool calls / repeated same command | loop or no-exit observer path | inspect the last N tool calls for repetition |
|
|
67
|
+
| Context overflow / degraded reasoning | unbounded notes, repeated plans, oversized logs | inspect recent context for duplication and low-signal bulk |
|
|
68
|
+
| `ECONNREFUSED` / timeout | service unavailable or wrong port | verify service health, URL, and port assumptions |
|
|
69
|
+
| `429` / quota exhaustion | retry storm or missing backoff | count repeated calls and inspect retry spacing |
|
|
70
|
+
| file missing after write / stale diff | race, wrong cwd, or branch drift | re-check path, cwd, git status, and actual file existence |
|
|
71
|
+
| tests still failing after “fix” | wrong hypothesis | isolate the exact failing test and re-derive the bug |
|
|
72
|
+
|
|
73
|
+
Diagnosis questions:
|
|
74
|
+
- is this a logic failure, state failure, environment failure, or policy failure?
|
|
75
|
+
- did the agent lose the real objective and start optimizing the wrong subtask?
|
|
76
|
+
- is the failure deterministic or transient?
|
|
77
|
+
- what is the smallest reversible action that would validate the diagnosis?
|
|
78
|
+
|
|
79
|
+
### Phase 3: Contained Recovery
|
|
80
|
+
|
|
81
|
+
Recover with the smallest action that changes the diagnosis surface.
|
|
82
|
+
|
|
83
|
+
Safe recovery actions:
|
|
84
|
+
- stop repeated retries and restate the hypothesis
|
|
85
|
+
- trim low-signal context and keep only the active goal, blockers, and evidence
|
|
86
|
+
- re-check the actual filesystem / branch / process state
|
|
87
|
+
- narrow the task to one failing command, one file, or one test
|
|
88
|
+
- switch from speculative reasoning to direct observation
|
|
89
|
+
- escalate to a human when the failure is high-risk or externally blocked
|
|
90
|
+
|
|
91
|
+
Do not claim unsupported auto-healing actions like “reset agent state” or “update harness config” unless you are actually doing them through real tools in the current environment.
|
|
92
|
+
|
|
93
|
+
Contained recovery checklist:
|
|
94
|
+
|
|
95
|
+
```markdown
|
|
96
|
+
## Recovery Action
|
|
97
|
+
- Diagnosis chosen:
|
|
98
|
+
- Smallest action taken:
|
|
99
|
+
- Why this is safe:
|
|
100
|
+
- What evidence would prove the fix worked:
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Phase 4: Introspection Report
|
|
104
|
+
|
|
105
|
+
End with a report that makes the recovery legible to the next agent or human.
|
|
106
|
+
|
|
107
|
+
```markdown
|
|
108
|
+
## Agent Self-Debug Report
|
|
109
|
+
- Session / task:
|
|
110
|
+
- Failure:
|
|
111
|
+
- Root cause:
|
|
112
|
+
- Recovery action:
|
|
113
|
+
- Result: success | partial | blocked
|
|
114
|
+
- Token / time burn risk:
|
|
115
|
+
- Follow-up needed:
|
|
116
|
+
- Preventive change to encode later:
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Recovery Heuristics
|
|
120
|
+
|
|
121
|
+
Prefer these interventions in order:
|
|
122
|
+
|
|
123
|
+
1. Restate the real objective in one sentence.
|
|
124
|
+
2. Verify the world state instead of trusting memory.
|
|
125
|
+
3. Shrink the failing scope.
|
|
126
|
+
4. Run one discriminating check.
|
|
127
|
+
5. Only then retry.
|
|
128
|
+
|
|
129
|
+
Bad pattern:
|
|
130
|
+
- retrying the same action three times with slightly different wording
|
|
131
|
+
|
|
132
|
+
Good pattern:
|
|
133
|
+
- capture failure
|
|
134
|
+
- classify the pattern
|
|
135
|
+
- run one direct check
|
|
136
|
+
- change the plan only if the check supports it
|
|
137
|
+
|
|
138
|
+
## Integration with ECC
|
|
139
|
+
|
|
140
|
+
- Use `verification-loop` after recovery if code was changed.
|
|
141
|
+
- Use `continuous-learning-v2` when the failure pattern is worth turning into an instinct or later skill.
|
|
142
|
+
- Use `council` when the issue is not technical failure but decision ambiguity.
|
|
143
|
+
- Use `workspace-surface-audit` if the failure came from conflicting local state or repo drift.
|
|
144
|
+
|
|
145
|
+
## Output Standard
|
|
146
|
+
|
|
147
|
+
When this skill is active, do not end with “I fixed it” alone.
|
|
148
|
+
|
|
149
|
+
Always provide:
|
|
150
|
+
- the failure pattern
|
|
151
|
+
- the root-cause hypothesis
|
|
152
|
+
- the recovery action
|
|
153
|
+
- the evidence that the situation is now better or still blocked
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android-clean-architecture
|
|
3
|
+
description: Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Android Clean Architecture
|
|
8
|
+
|
|
9
|
+
Clean Architecture patterns for Android and KMP projects. Covers module boundaries, dependency inversion, UseCase/Repository patterns, and data layer design with Room, SQLDelight, and Ktor.
|
|
10
|
+
|
|
11
|
+
## When to Activate
|
|
12
|
+
|
|
13
|
+
- Structuring Android or KMP project modules
|
|
14
|
+
- Implementing UseCases, Repositories, or DataSources
|
|
15
|
+
- Designing data flow between layers (domain, data, presentation)
|
|
16
|
+
- Setting up dependency injection with Koin or Hilt
|
|
17
|
+
- Working with Room, SQLDelight, or Ktor in a layered architecture
|
|
18
|
+
|
|
19
|
+
## Module Structure
|
|
20
|
+
|
|
21
|
+
### Recommended Layout
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
project/
|
|
25
|
+
├── app/ # Android entry point, DI wiring, Application class
|
|
26
|
+
├── core/ # Shared utilities, base classes, error types
|
|
27
|
+
├── domain/ # UseCases, domain models, repository interfaces (pure Kotlin)
|
|
28
|
+
├── data/ # Repository implementations, DataSources, DB, network
|
|
29
|
+
├── presentation/ # Screens, ViewModels, UI models, navigation
|
|
30
|
+
├── design-system/ # Reusable Compose components, theme, typography
|
|
31
|
+
└── feature/ # Feature modules (optional, for larger projects)
|
|
32
|
+
├── auth/
|
|
33
|
+
├── settings/
|
|
34
|
+
└── profile/
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Dependency Rules
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
app → presentation, domain, data, core
|
|
41
|
+
presentation → domain, design-system, core
|
|
42
|
+
data → domain, core
|
|
43
|
+
domain → core (or no dependencies)
|
|
44
|
+
core → (nothing)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Critical**: `domain` must NEVER depend on `data`, `presentation`, or any framework. It contains pure Kotlin only.
|
|
48
|
+
|
|
49
|
+
## Domain Layer
|
|
50
|
+
|
|
51
|
+
### UseCase Pattern
|
|
52
|
+
|
|
53
|
+
Each UseCase represents one business operation. Use `operator fun invoke` for clean call sites:
|
|
54
|
+
|
|
55
|
+
```kotlin
|
|
56
|
+
class GetItemsByCategoryUseCase(
|
|
57
|
+
private val repository: ItemRepository
|
|
58
|
+
) {
|
|
59
|
+
suspend operator fun invoke(category: String): Result<List<Item>> {
|
|
60
|
+
return repository.getItemsByCategory(category)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Flow-based UseCase for reactive streams
|
|
65
|
+
class ObserveUserProgressUseCase(
|
|
66
|
+
private val repository: UserRepository
|
|
67
|
+
) {
|
|
68
|
+
operator fun invoke(userId: String): Flow<UserProgress> {
|
|
69
|
+
return repository.observeProgress(userId)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Domain Models
|
|
75
|
+
|
|
76
|
+
Domain models are plain Kotlin data classes — no framework annotations:
|
|
77
|
+
|
|
78
|
+
```kotlin
|
|
79
|
+
data class Item(
|
|
80
|
+
val id: String,
|
|
81
|
+
val title: String,
|
|
82
|
+
val description: String,
|
|
83
|
+
val tags: List<String>,
|
|
84
|
+
val status: Status,
|
|
85
|
+
val category: String
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
enum class Status { DRAFT, ACTIVE, ARCHIVED }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Repository Interfaces
|
|
92
|
+
|
|
93
|
+
Defined in domain, implemented in data:
|
|
94
|
+
|
|
95
|
+
```kotlin
|
|
96
|
+
interface ItemRepository {
|
|
97
|
+
suspend fun getItemsByCategory(category: String): Result<List<Item>>
|
|
98
|
+
suspend fun saveItem(item: Item): Result<Unit>
|
|
99
|
+
fun observeItems(): Flow<List<Item>>
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Data Layer
|
|
104
|
+
|
|
105
|
+
### Repository Implementation
|
|
106
|
+
|
|
107
|
+
Coordinates between local and remote data sources:
|
|
108
|
+
|
|
109
|
+
```kotlin
|
|
110
|
+
class ItemRepositoryImpl(
|
|
111
|
+
private val localDataSource: ItemLocalDataSource,
|
|
112
|
+
private val remoteDataSource: ItemRemoteDataSource
|
|
113
|
+
) : ItemRepository {
|
|
114
|
+
|
|
115
|
+
override suspend fun getItemsByCategory(category: String): Result<List<Item>> {
|
|
116
|
+
return runCatching {
|
|
117
|
+
val remote = remoteDataSource.fetchItems(category)
|
|
118
|
+
localDataSource.insertItems(remote.map { it.toEntity() })
|
|
119
|
+
localDataSource.getItemsByCategory(category).map { it.toDomain() }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override suspend fun saveItem(item: Item): Result<Unit> {
|
|
124
|
+
return runCatching {
|
|
125
|
+
localDataSource.insertItems(listOf(item.toEntity()))
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
override fun observeItems(): Flow<List<Item>> {
|
|
130
|
+
return localDataSource.observeAll().map { entities ->
|
|
131
|
+
entities.map { it.toDomain() }
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Mapper Pattern
|
|
138
|
+
|
|
139
|
+
Keep mappers as extension functions near the data models:
|
|
140
|
+
|
|
141
|
+
```kotlin
|
|
142
|
+
// In data layer
|
|
143
|
+
fun ItemEntity.toDomain() = Item(
|
|
144
|
+
id = id,
|
|
145
|
+
title = title,
|
|
146
|
+
description = description,
|
|
147
|
+
tags = tags.split("|"),
|
|
148
|
+
status = Status.valueOf(status),
|
|
149
|
+
category = category
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
fun ItemDto.toEntity() = ItemEntity(
|
|
153
|
+
id = id,
|
|
154
|
+
title = title,
|
|
155
|
+
description = description,
|
|
156
|
+
tags = tags.joinToString("|"),
|
|
157
|
+
status = status,
|
|
158
|
+
category = category
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Room Database (Android)
|
|
163
|
+
|
|
164
|
+
```kotlin
|
|
165
|
+
@Entity(tableName = "items")
|
|
166
|
+
data class ItemEntity(
|
|
167
|
+
@PrimaryKey val id: String,
|
|
168
|
+
val title: String,
|
|
169
|
+
val description: String,
|
|
170
|
+
val tags: String,
|
|
171
|
+
val status: String,
|
|
172
|
+
val category: String
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
@Dao
|
|
176
|
+
interface ItemDao {
|
|
177
|
+
@Query("SELECT * FROM items WHERE category = :category")
|
|
178
|
+
suspend fun getByCategory(category: String): List<ItemEntity>
|
|
179
|
+
|
|
180
|
+
@Upsert
|
|
181
|
+
suspend fun upsert(items: List<ItemEntity>)
|
|
182
|
+
|
|
183
|
+
@Query("SELECT * FROM items")
|
|
184
|
+
fun observeAll(): Flow<List<ItemEntity>>
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### SQLDelight (KMP)
|
|
189
|
+
|
|
190
|
+
```sql
|
|
191
|
+
-- Item.sq
|
|
192
|
+
CREATE TABLE ItemEntity (
|
|
193
|
+
id TEXT NOT NULL PRIMARY KEY,
|
|
194
|
+
title TEXT NOT NULL,
|
|
195
|
+
description TEXT NOT NULL,
|
|
196
|
+
tags TEXT NOT NULL,
|
|
197
|
+
status TEXT NOT NULL,
|
|
198
|
+
category TEXT NOT NULL
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
getByCategory:
|
|
202
|
+
SELECT * FROM ItemEntity WHERE category = ?;
|
|
203
|
+
|
|
204
|
+
upsert:
|
|
205
|
+
INSERT OR REPLACE INTO ItemEntity (id, title, description, tags, status, category)
|
|
206
|
+
VALUES (?, ?, ?, ?, ?, ?);
|
|
207
|
+
|
|
208
|
+
observeAll:
|
|
209
|
+
SELECT * FROM ItemEntity;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Ktor Network Client (KMP)
|
|
213
|
+
|
|
214
|
+
```kotlin
|
|
215
|
+
class ItemRemoteDataSource(private val client: HttpClient) {
|
|
216
|
+
|
|
217
|
+
suspend fun fetchItems(category: String): List<ItemDto> {
|
|
218
|
+
return client.get("api/items") {
|
|
219
|
+
parameter("category", category)
|
|
220
|
+
}.body()
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// HttpClient setup with content negotiation
|
|
225
|
+
val httpClient = HttpClient {
|
|
226
|
+
install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
|
|
227
|
+
install(Logging) { level = LogLevel.HEADERS }
|
|
228
|
+
defaultRequest { url("https://api.example.com/") }
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Dependency Injection
|
|
233
|
+
|
|
234
|
+
### Koin (KMP-friendly)
|
|
235
|
+
|
|
236
|
+
```kotlin
|
|
237
|
+
// Domain module
|
|
238
|
+
val domainModule = module {
|
|
239
|
+
factory { GetItemsByCategoryUseCase(get()) }
|
|
240
|
+
factory { ObserveUserProgressUseCase(get()) }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Data module
|
|
244
|
+
val dataModule = module {
|
|
245
|
+
single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
|
|
246
|
+
single { ItemLocalDataSource(get()) }
|
|
247
|
+
single { ItemRemoteDataSource(get()) }
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Presentation module
|
|
251
|
+
val presentationModule = module {
|
|
252
|
+
viewModelOf(::ItemListViewModel)
|
|
253
|
+
viewModelOf(::DashboardViewModel)
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Hilt (Android-only)
|
|
258
|
+
|
|
259
|
+
```kotlin
|
|
260
|
+
@Module
|
|
261
|
+
@InstallIn(SingletonComponent::class)
|
|
262
|
+
abstract class RepositoryModule {
|
|
263
|
+
@Binds
|
|
264
|
+
abstract fun bindItemRepository(impl: ItemRepositoryImpl): ItemRepository
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@HiltViewModel
|
|
268
|
+
class ItemListViewModel @Inject constructor(
|
|
269
|
+
private val getItems: GetItemsByCategoryUseCase
|
|
270
|
+
) : ViewModel()
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Error Handling
|
|
274
|
+
|
|
275
|
+
### Result/Try Pattern
|
|
276
|
+
|
|
277
|
+
Use `Result<T>` or a custom sealed type for error propagation:
|
|
278
|
+
|
|
279
|
+
```kotlin
|
|
280
|
+
sealed interface Try<out T> {
|
|
281
|
+
data class Success<T>(val value: T) : Try<T>
|
|
282
|
+
data class Failure(val error: AppError) : Try<Nothing>
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
sealed interface AppError {
|
|
286
|
+
data class Network(val message: String) : AppError
|
|
287
|
+
data class Database(val message: String) : AppError
|
|
288
|
+
data object Unauthorized : AppError
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// In ViewModel — map to UI state
|
|
292
|
+
viewModelScope.launch {
|
|
293
|
+
when (val result = getItems(category)) {
|
|
294
|
+
is Try.Success -> _state.update { it.copy(items = result.value, isLoading = false) }
|
|
295
|
+
is Try.Failure -> _state.update { it.copy(error = result.error.toMessage(), isLoading = false) }
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Convention Plugins (Gradle)
|
|
301
|
+
|
|
302
|
+
For KMP projects, use convention plugins to reduce build file duplication:
|
|
303
|
+
|
|
304
|
+
```kotlin
|
|
305
|
+
// build-logic/src/main/kotlin/kmp-library.gradle.kts
|
|
306
|
+
plugins {
|
|
307
|
+
id("org.jetbrains.kotlin.multiplatform")
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
kotlin {
|
|
311
|
+
androidTarget()
|
|
312
|
+
iosX64(); iosArm64(); iosSimulatorArm64()
|
|
313
|
+
sourceSets {
|
|
314
|
+
commonMain.dependencies { /* shared deps */ }
|
|
315
|
+
commonTest.dependencies { implementation(kotlin("test")) }
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Apply in modules:
|
|
321
|
+
|
|
322
|
+
```kotlin
|
|
323
|
+
// domain/build.gradle.kts
|
|
324
|
+
plugins { id("kmp-library") }
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Anti-Patterns to Avoid
|
|
328
|
+
|
|
329
|
+
- Importing Android framework classes in `domain` — keep it pure Kotlin
|
|
330
|
+
- Exposing database entities or DTOs to the UI layer — always map to domain models
|
|
331
|
+
- Putting business logic in ViewModels — extract to UseCases
|
|
332
|
+
- Using `GlobalScope` or unstructured coroutines — use `viewModelScope` or structured concurrency
|
|
333
|
+
- Fat repository implementations — split into focused DataSources
|
|
334
|
+
- Circular module dependencies — if A depends on B, B must not depend on A
|
|
335
|
+
|
|
336
|
+
## References
|
|
337
|
+
|
|
338
|
+
See skill: `compose-multiplatform-patterns` for UI patterns.
|
|
339
|
+
See skill: `kotlin-coroutines-flows` for async patterns.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: angular-developer
|
|
3
|
+
description: Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.
|
|
4
|
+
origin: ECC
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Angular Developer Guidelines
|
|
8
|
+
|
|
9
|
+
## When to Activate
|
|
10
|
+
|
|
11
|
+
- Working in any Angular project or codebase
|
|
12
|
+
- Creating or scaffolding a new Angular project, application, or library
|
|
13
|
+
- Generating components, services, directives, pipes, guards, or resolvers
|
|
14
|
+
- Implementing reactivity with Angular Signals, `linkedSignal`, or `resource`
|
|
15
|
+
- Working with Angular forms (signal forms, reactive forms, or template-driven)
|
|
16
|
+
- Setting up dependency injection, routing, lazy loading, or route guards
|
|
17
|
+
- Adding accessibility (ARIA), animations, or component styling
|
|
18
|
+
- Writing or debugging Angular-specific tests (unit, component harness, E2E)
|
|
19
|
+
- Configuring Angular CLI tooling or the Angular MCP server
|
|
20
|
+
|
|
21
|
+
1. Always analyze the project's Angular version before providing guidance, as best practices and available features can vary significantly between versions. If creating a new project with Angular CLI, do not specify a version unless prompted by the user.
|
|
22
|
+
|
|
23
|
+
2. When generating code, follow Angular's style guide and best practices for maintainability and performance. Use the Angular CLI for scaffolding components, services, directives, pipes, and routes to ensure consistency.
|
|
24
|
+
|
|
25
|
+
3. Once you finish generating code, run `ng build` to ensure there are no build errors. If there are errors, analyze the error messages and fix them before proceeding. Do not skip this step, as it is critical for ensuring the generated code is correct and functional.
|
|
26
|
+
|
|
27
|
+
## Creating New Projects
|
|
28
|
+
|
|
29
|
+
If no guidelines are provided by the user, use these defaults when creating a new Angular project:
|
|
30
|
+
|
|
31
|
+
1. Use the latest stable version of Angular unless the user specifies otherwise.
|
|
32
|
+
2. Prefer Signal Forms for new projects only when the target Angular version supports them. [Find out more](references/signal-forms.md).
|
|
33
|
+
|
|
34
|
+
**Execution Rules for `ng new`:**
|
|
35
|
+
When asked to create a new Angular project, you must determine the correct execution command by following these strict steps:
|
|
36
|
+
|
|
37
|
+
**Step 1: Check for an explicit user version.**
|
|
38
|
+
|
|
39
|
+
- **IF** the user requests a specific version (e.g., Angular 15), bypass local installations and strictly use `npx`.
|
|
40
|
+
- **Command:** `npx @angular/cli@<requested_version> new <project-name>`
|
|
41
|
+
|
|
42
|
+
**Step 2: Check for an existing Angular installation.**
|
|
43
|
+
|
|
44
|
+
- **IF** no specific version is requested, run `ng version` in the terminal to check if the Angular CLI is already installed on the system.
|
|
45
|
+
- **IF** the command succeeds and returns an installed version, use the local/global installation directly.
|
|
46
|
+
- **Command:** `ng new <project-name>`
|
|
47
|
+
|
|
48
|
+
**Step 3: Fallback to Latest.**
|
|
49
|
+
|
|
50
|
+
- **IF** no specific version is requested AND the `ng version` command fails (indicating no Angular installation exists), you must use `npx` to fetch the latest version.
|
|
51
|
+
- **Command:** `npx @angular/cli@latest new <project-name>`
|
|
52
|
+
|
|
53
|
+
## Components
|
|
54
|
+
|
|
55
|
+
When working with Angular components, consult the following references based on the task:
|
|
56
|
+
|
|
57
|
+
- **Fundamentals**: Anatomy, metadata, core concepts, and template control flow (@if, @for, @switch). Read [components.md](references/components.md)
|
|
58
|
+
- **Inputs**: Signal-based inputs, transforms, and model inputs. Read [inputs.md](references/inputs.md)
|
|
59
|
+
- **Outputs**: Signal-based outputs and custom event best practices. Read [outputs.md](references/outputs.md)
|
|
60
|
+
- **Host Elements**: Host bindings and attribute injection. Read [host-elements.md](references/host-elements.md)
|
|
61
|
+
|
|
62
|
+
If you require deeper documentation not found in the references above, read the documentation at `https://angular.dev/guide/components`.
|
|
63
|
+
|
|
64
|
+
## Reactivity and Data Management
|
|
65
|
+
|
|
66
|
+
When managing state and data reactivity, use Angular Signals and consult the following references:
|
|
67
|
+
|
|
68
|
+
- **Signals Overview**: Core signal concepts (`signal`, `computed`), reactive contexts, and `untracked`. Read [signals-overview.md](references/signals-overview.md)
|
|
69
|
+
- **Dependent State (`linkedSignal`)**: Creating writable state linked to source signals. Read [linked-signal.md](references/linked-signal.md)
|
|
70
|
+
- **Async Reactivity (`resource`)**: Fetching asynchronous data directly into signal state. Read [resource.md](references/resource.md)
|
|
71
|
+
- **Side Effects (`effect`)**: Logging, third-party DOM manipulation (`afterRenderEffect`), and when NOT to use effects. Read [effects.md](references/effects.md)
|
|
72
|
+
|
|
73
|
+
## Forms
|
|
74
|
+
|
|
75
|
+
In most cases for new apps, **prefer signal forms**. When making a forms decision, analyze the project and consider the following guidelines:
|
|
76
|
+
|
|
77
|
+
- If the application version supports Signal Forms and this is a new form, **prefer signal forms**.
|
|
78
|
+
- For older applications or existing forms, match the application's current form strategy.
|
|
79
|
+
|
|
80
|
+
- **Signal Forms**: Use signals for form state management. Read [signal-forms.md](references/signal-forms.md)
|
|
81
|
+
- **Template-driven forms**: Use for simple forms. Read [template-driven-forms.md](references/template-driven-forms.md)
|
|
82
|
+
- **Reactive forms**: Use for complex forms. Read [reactive-forms.md](references/reactive-forms.md)
|
|
83
|
+
|
|
84
|
+
## Dependency Injection
|
|
85
|
+
|
|
86
|
+
When implementing dependency injection in Angular, follow these guidelines:
|
|
87
|
+
|
|
88
|
+
- **Fundamentals**: Overview of Dependency Injection, services, and the `inject()` function. Read [di-fundamentals.md](references/di-fundamentals.md)
|
|
89
|
+
- **Creating and Using Services**: Creating services, the `providedIn: 'root'` option, and injecting into components or other services. Read [creating-services.md](references/creating-services.md)
|
|
90
|
+
- **Defining Dependency Providers**: Automatic vs manual provision, `InjectionToken`, `useClass`, `useValue`, `useFactory`, and scopes. Read [defining-providers.md](references/defining-providers.md)
|
|
91
|
+
- **Injection Context**: Where `inject()` is allowed, `runInInjectionContext`, and `assertInInjectionContext`. Read [injection-context.md](references/injection-context.md)
|
|
92
|
+
- **Hierarchical Injectors**: The `EnvironmentInjector` vs `ElementInjector`, resolution rules, modifiers (`optional`, `skipSelf`), and `providers` vs `viewProviders`. Read [hierarchical-injectors.md](references/hierarchical-injectors.md)
|
|
93
|
+
|
|
94
|
+
## Angular Aria
|
|
95
|
+
|
|
96
|
+
When building accessible custom components for any of the following patterns: Accordion, Listbox, Combobox, Menu, Tabs, Toolbar, Tree, Grid, consult the following reference:
|
|
97
|
+
|
|
98
|
+
- **Angular Aria Components**: Building headless, accessible components (Accordion, Listbox, Combobox, Menu, Tabs, Toolbar, Tree, Grid) and styling ARIA attributes. Read [angular-aria.md](references/angular-aria.md)
|
|
99
|
+
|
|
100
|
+
## Routing
|
|
101
|
+
|
|
102
|
+
When implementing navigation in Angular, consult the following references:
|
|
103
|
+
|
|
104
|
+
- **Define Routes**: URL paths, static vs dynamic segments, wildcards, and redirects. Read [define-routes.md](references/define-routes.md)
|
|
105
|
+
- **Route Loading Strategies**: Eager vs lazy loading, and context-aware loading. Read [loading-strategies.md](references/loading-strategies.md)
|
|
106
|
+
- **Show Routes with Outlets**: Using `<router-outlet>`, nested outlets, and named outlets. Read [show-routes-with-outlets.md](references/show-routes-with-outlets.md)
|
|
107
|
+
- **Navigate to Routes**: Declarative navigation with `RouterLink` and programmatic navigation with `Router`. Read [navigate-to-routes.md](references/navigate-to-routes.md)
|
|
108
|
+
- **Control Route Access with Guards**: Implementing `CanActivate`, `CanMatch`, and other guards for security. Read [route-guards.md](references/route-guards.md)
|
|
109
|
+
- **Data Resolvers**: Pre-fetching data before route activation with `ResolveFn`. Read [data-resolvers.md](references/data-resolvers.md)
|
|
110
|
+
- **Router Lifecycle and Events**: Chronological order of navigation events and debugging. Read [router-lifecycle.md](references/router-lifecycle.md)
|
|
111
|
+
- **Rendering Strategies**: CSR, SSG (Prerendering), and SSR with hydration. Read [rendering-strategies.md](references/rendering-strategies.md)
|
|
112
|
+
- **Route Transition Animations**: Enabling and customizing the View Transitions API. Read [route-animations.md](references/route-animations.md)
|
|
113
|
+
|
|
114
|
+
If you require deeper documentation or more context, visit the [official Angular Routing guide](https://angular.dev/guide/routing).
|
|
115
|
+
|
|
116
|
+
## Styling and Animations
|
|
117
|
+
|
|
118
|
+
When implementing styling and animations in Angular, consult the following references:
|
|
119
|
+
|
|
120
|
+
- **Using Tailwind CSS with Angular**: Integrating Tailwind CSS into Angular projects. Read [tailwind-css.md](references/tailwind-css.md)
|
|
121
|
+
- **Angular Animations**: Using native CSS (recommended) or the legacy DSL for dynamic effects. Read [angular-animations.md](references/angular-animations.md)
|
|
122
|
+
- **Styling components**: Best practices for component styles and encapsulation. Read [component-styling.md](references/component-styling.md)
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
When writing or updating tests, consult the following references based on the task:
|
|
127
|
+
|
|
128
|
+
- **Fundamentals**: Best practices for unit testing, async patterns, and `TestBed`. Read [testing-fundamentals.md](references/testing-fundamentals.md)
|
|
129
|
+
- **Component Harnesses**: Standard patterns for robust component interaction. Read [component-harnesses.md](references/component-harnesses.md)
|
|
130
|
+
- **Router Testing**: Using `RouterTestingHarness` for reliable navigation tests. Read [router-testing.md](references/router-testing.md)
|
|
131
|
+
- **End-to-End (E2E) Testing**: Best practices for E2E tests with Cypress or Playwright. Read [e2e-testing.md](references/e2e-testing.md)
|
|
132
|
+
|
|
133
|
+
## Tooling
|
|
134
|
+
|
|
135
|
+
When working with Angular tooling, consult the following references:
|
|
136
|
+
|
|
137
|
+
- **Angular CLI**: Creating applications, generating code (components, routes, services), serving, and building. Read [cli.md](references/cli.md)
|
|
138
|
+
- **Angular MCP Server**: Available tools, configuration, and experimental features. Read [mcp.md](references/mcp.md)
|
|
139
|
+
|
|
140
|
+
## Anti-Patterns
|
|
141
|
+
|
|
142
|
+
- Using `null` or `undefined` as initial signal form field values — use `''`, `0`, or `[]` instead
|
|
143
|
+
- Accessing form field state flags without calling the field first: `form.field.valid()` — use `form.field().valid()`
|
|
144
|
+
- Starting new forms with older form APIs when the target Angular version supports Signal Forms
|
|
145
|
+
- Setting `min`, `max`, `value`, `disabled`, or `readonly` HTML attributes on `[formField]` inputs — define these as schema rules instead
|
|
146
|
+
- Calling `inject()` outside an injection context — use `runInInjectionContext` when needed
|
|
147
|
+
- Using `effect()` for derived state that should use `computed()`
|
|
148
|
+
- Referencing `$parent.$index` in nested `@for` loops — Angular does not support `$parent`; use `let outerIdx = $index` instead
|
|
149
|
+
|
|
150
|
+
## Related Skills
|
|
151
|
+
|
|
152
|
+
- `tdd-workflow` — test-driven development workflow applicable to Angular components and services
|
|
153
|
+
- `security-review` — security checklist for web applications including Angular-specific concerns
|
|
154
|
+
- `frontend-patterns` — general frontend patterns for context on React/Next.js approaches
|