@grimoire-cc/cli 0.13.3 → 0.15.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/dist/bin.js +15 -5
- package/dist/bin.js.map +1 -1
- package/dist/commands/agent-paths.d.ts +11 -0
- package/dist/commands/agent-paths.d.ts.map +1 -0
- package/dist/commands/agent-paths.js +69 -0
- package/dist/commands/agent-paths.js.map +1 -0
- package/dist/commands/agent-skills.d.ts +10 -0
- package/dist/commands/agent-skills.d.ts.map +1 -0
- package/dist/commands/agent-skills.js +159 -0
- package/dist/commands/agent-skills.js.map +1 -0
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +62 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +237 -75
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/update.d.ts +1 -2
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +18 -0
- package/dist/commands/update.js.map +1 -1
- package/dist/enforce.d.ts +9 -9
- package/dist/enforce.d.ts.map +1 -1
- package/dist/enforce.js +56 -23
- package/dist/enforce.js.map +1 -1
- package/dist/frontmatter.d.ts +16 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +74 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/grimoire-config.d.ts +6 -0
- package/dist/grimoire-config.d.ts.map +1 -0
- package/dist/grimoire-config.js +23 -0
- package/dist/grimoire-config.js.map +1 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +13 -8
- package/dist/prompt.js.map +1 -1
- package/dist/remove.d.ts +4 -0
- package/dist/remove.d.ts.map +1 -1
- package/dist/remove.js +8 -0
- package/dist/remove.js.map +1 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +12 -5
- package/dist/resolve.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +45 -2
- package/dist/setup.js.map +1 -1
- package/dist/summary.d.ts.map +1 -1
- package/dist/summary.js +9 -0
- package/dist/summary.js.map +1 -1
- package/package.json +1 -1
- package/packs/dev-pack/agents/grimoire.tdd-specialist.md +194 -27
- package/packs/dev-pack/grimoire.json +0 -38
- package/packs/dev-pack/skills/grimoire.conventional-commit/SKILL.md +69 -65
- package/packs/dotnet-pack/agents/grimoire.csharp-coder.md +110 -113
- package/packs/dotnet-pack/grimoire.json +23 -5
- package/packs/dotnet-pack/skills/grimoire.unit-testing-dotnet/SKILL.md +252 -0
- package/packs/{dev-pack/skills/grimoire.tdd-specialist → dotnet-pack/skills/grimoire.unit-testing-dotnet}/reference/anti-patterns.md +78 -0
- package/packs/dotnet-pack/skills/grimoire.unit-testing-dotnet/reference/tdd-workflow-patterns.md +259 -0
- package/packs/frontend-pack/agents/grimoire.angular-coder.md +193 -0
- package/packs/frontend-pack/grimoire.json +7 -0
- package/packs/go-pack/grimoire.json +19 -0
- package/packs/go-pack/skills/grimoire.unit-testing-go/SKILL.md +256 -0
- package/packs/go-pack/skills/grimoire.unit-testing-go/reference/anti-patterns.md +244 -0
- package/packs/go-pack/skills/grimoire.unit-testing-go/reference/tdd-workflow-patterns.md +259 -0
- package/packs/python-pack/grimoire.json +19 -0
- package/packs/python-pack/skills/grimoire.unit-testing-python/SKILL.md +239 -0
- package/packs/python-pack/skills/grimoire.unit-testing-python/reference/anti-patterns.md +244 -0
- package/packs/python-pack/skills/grimoire.unit-testing-python/reference/tdd-workflow-patterns.md +259 -0
- package/packs/rust-pack/grimoire.json +29 -0
- package/packs/rust-pack/skills/grimoire.unit-testing-rust/SKILL.md +243 -0
- package/packs/rust-pack/skills/grimoire.unit-testing-rust/reference/anti-patterns.md +244 -0
- package/packs/rust-pack/skills/grimoire.unit-testing-rust/reference/tdd-workflow-patterns.md +259 -0
- package/packs/ts-pack/agents/grimoire.typescript-coder.md +36 -1
- package/packs/ts-pack/grimoire.json +27 -1
- package/packs/ts-pack/skills/grimoire.unit-testing-typescript/SKILL.md +255 -0
- package/packs/ts-pack/skills/grimoire.unit-testing-typescript/reference/anti-patterns.md +244 -0
- package/packs/ts-pack/skills/grimoire.unit-testing-typescript/reference/tdd-workflow-patterns.md +259 -0
- package/dist/commands/enforce-agent.d.ts +0 -5
- package/dist/commands/enforce-agent.d.ts.map +0 -1
- package/dist/commands/enforce-agent.js +0 -94
- package/dist/commands/enforce-agent.js.map +0 -1
- package/packs/dev-pack/skills/grimoire.tdd-specialist/SKILL.md +0 -248
- package/packs/dev-pack/skills/grimoire.tdd-specialist/reference/language-frameworks.md +0 -388
- package/packs/dev-pack/skills/grimoire.tdd-specialist/reference/tdd-workflow-patterns.md +0 -135
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/SKILL.md +0 -293
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/anti-patterns.md +0 -329
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/framework-guidelines.md +0 -361
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/parameterized-testing.md +0 -378
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/test-organization.md +0 -476
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/reference/test-performance.md +0 -576
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/templates/tunit-template.md +0 -438
- package/packs/dotnet-pack/skills/grimoire.dotnet-unit-testing/templates/xunit-template.md +0 -303
package/packs/dotnet-pack/skills/grimoire.unit-testing-dotnet/reference/tdd-workflow-patterns.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# TDD Workflow Patterns
|
|
2
|
+
|
|
3
|
+
Guidance on the test-driven development process, when to apply it, and advanced techniques.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Canon TDD — Start with a Test List](#canon-tdd--start-with-a-test-list)
|
|
8
|
+
- [Red-Green-Refactor](#red-green-refactor)
|
|
9
|
+
- [Transformation Priority Premise](#transformation-priority-premise)
|
|
10
|
+
- [F.I.R.S.T. Principles](#first-principles)
|
|
11
|
+
- [London School vs Detroit School](#london-school-vs-detroit-school)
|
|
12
|
+
- [When to Use TDD](#when-to-use-tdd)
|
|
13
|
+
- [When TDD Is Less Effective](#when-tdd-is-less-effective)
|
|
14
|
+
- [BDD and ATDD Extensions](#bdd-and-atdd-extensions)
|
|
15
|
+
- [Advanced Techniques](#advanced-techniques)
|
|
16
|
+
|
|
17
|
+
## Canon TDD — Start with a Test List
|
|
18
|
+
|
|
19
|
+
> Source: https://tidyfirst.substack.com/p/canon-tdd
|
|
20
|
+
|
|
21
|
+
Kent Beck's recommended starting point is not a single test but a **test list** — a written enumeration of all behaviors you intend to verify. This separates the creative work (what to test) from the mechanical work (write, make pass, refactor).
|
|
22
|
+
|
|
23
|
+
**Process:**
|
|
24
|
+
1. Write down all behaviors the code needs — a flat list, not tests
|
|
25
|
+
2. Pick the simplest item on the list
|
|
26
|
+
3. Write one failing test for it
|
|
27
|
+
4. Make it pass with the minimum code
|
|
28
|
+
5. Refactor
|
|
29
|
+
6. Cross off the item; repeat
|
|
30
|
+
|
|
31
|
+
**Why test order matters:** Starting with simpler behaviors forces simpler transformations (see TPP below) and lets the design emerge naturally. Jumping to complex cases early leads to over-engineered solutions. The test list keeps you focused and prevents scope creep.
|
|
32
|
+
|
|
33
|
+
## Red-Green-Refactor
|
|
34
|
+
|
|
35
|
+
> Source: https://martinfowler.com/bliki/TestDrivenDevelopment.html
|
|
36
|
+
|
|
37
|
+
The core TDD cycle, repeated in small increments:
|
|
38
|
+
|
|
39
|
+
### 1. Red — Write a Failing Test
|
|
40
|
+
|
|
41
|
+
Write the smallest test that describes the next piece of behavior. The test MUST fail before you write any production code. A test that passes immediately provides no confidence.
|
|
42
|
+
|
|
43
|
+
**Rules:**
|
|
44
|
+
- Write only ONE test at a time
|
|
45
|
+
- The test should compile/parse but fail at the assertion
|
|
46
|
+
- If the test passes immediately, it's either trivial or testing existing behavior
|
|
47
|
+
|
|
48
|
+
### 2. Green — Make It Pass
|
|
49
|
+
|
|
50
|
+
Write the MINIMUM code to make the failing test pass. Do not add extra logic, handle cases not yet tested, or optimize.
|
|
51
|
+
|
|
52
|
+
**Rules:**
|
|
53
|
+
- Write the simplest code that makes the test pass
|
|
54
|
+
- It's OK to hardcode values initially — the next test will force generalization
|
|
55
|
+
- Do not add code for future tests
|
|
56
|
+
- All existing tests must still pass
|
|
57
|
+
|
|
58
|
+
### 3. Refactor — Clean Up
|
|
59
|
+
|
|
60
|
+
With all tests green, improve the code structure without changing behavior. Tests give you the safety net.
|
|
61
|
+
|
|
62
|
+
**Rules:**
|
|
63
|
+
- No new functionality during refactoring
|
|
64
|
+
- All tests must remain green after each refactoring step
|
|
65
|
+
- Remove duplication, improve naming, extract methods
|
|
66
|
+
- Refactor both production code AND test code
|
|
67
|
+
|
|
68
|
+
### Cycle Length
|
|
69
|
+
|
|
70
|
+
Each Red-Green-Refactor cycle should take 1–10 minutes. If you're spending more than 10 minutes in the Red or Green phase, the step is too large — break it down.
|
|
71
|
+
|
|
72
|
+
## Transformation Priority Premise
|
|
73
|
+
|
|
74
|
+
> Source: http://blog.cleancoder.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html
|
|
75
|
+
|
|
76
|
+
When going from Red to Green, prefer simpler transformations over complex ones. Listed from simplest to most complex:
|
|
77
|
+
|
|
78
|
+
1. **Constant** — return a hardcoded value
|
|
79
|
+
2. **Scalar** — replace constant with a variable
|
|
80
|
+
3. **Direct** — replace unconditional with conditional (if/else)
|
|
81
|
+
4. **Collection** — operate on a collection instead of a scalar
|
|
82
|
+
5. **Iteration** — add a loop
|
|
83
|
+
6. **Recursion** — add recursive call
|
|
84
|
+
7. **Assignment** — replace computed value with mutation
|
|
85
|
+
|
|
86
|
+
**Example — building FizzBuzz with TDD:**
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Test 1: input 1 → "1" Transformation: Constant
|
|
90
|
+
Test 2: input 2 → "2" Transformation: Scalar (use the input)
|
|
91
|
+
Test 3: input 3 → "Fizz" Transformation: Direct (add if)
|
|
92
|
+
Test 4: input 5 → "Buzz" Transformation: Direct (add another if)
|
|
93
|
+
Test 5: input 15 → "FizzBuzz" Transformation: Direct (add combined if)
|
|
94
|
+
Test 6: input 1-15 → full list Transformation: Iteration (generalize)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
By following this priority, you avoid over-engineering early and let the design emerge naturally from the tests.
|
|
98
|
+
|
|
99
|
+
## F.I.R.S.T. Principles
|
|
100
|
+
|
|
101
|
+
Every unit test must satisfy these five properties:
|
|
102
|
+
|
|
103
|
+
| Principle | Definition | Violation Signal |
|
|
104
|
+
|-----------|------------|-----------------|
|
|
105
|
+
| **Fast** | Runs in milliseconds | Real I/O, network calls, `sleep()` |
|
|
106
|
+
| **Independent** | No dependency on other tests | Shared mutable state, ordered execution |
|
|
107
|
+
| **Repeatable** | Same result every run | System clock, random data without seed, race conditions |
|
|
108
|
+
| **Self-Validating** | Pass or fail without manual interpretation | Tests that print output for a human to read |
|
|
109
|
+
| **Timely** | Written before or alongside production code | Tests added weeks after a feature shipped |
|
|
110
|
+
|
|
111
|
+
F.I.R.S.T. is a diagnostic checklist: if a test violates any property, it will erode team trust and reduce the value of the suite.
|
|
112
|
+
|
|
113
|
+
## London School vs Detroit School
|
|
114
|
+
|
|
115
|
+
> Source: https://martinfowler.com/articles/mocksArentStubs.html
|
|
116
|
+
|
|
117
|
+
Two schools of TDD with different philosophies on test doubles. Most teams use a hybrid.
|
|
118
|
+
|
|
119
|
+
### Detroit School (Classicist, Inside-Out)
|
|
120
|
+
|
|
121
|
+
- **Unit definition**: A module of any size — can span multiple classes
|
|
122
|
+
- **Approach**: Bottom-up; start from domain logic, build outward
|
|
123
|
+
- **Test doubles**: Avoid mocks; use real objects when feasible
|
|
124
|
+
- **Verification**: State verification — examine the result after execution
|
|
125
|
+
- **Testing style**: Black-box; test through public API
|
|
126
|
+
- **Refactoring**: Safe — tests aren't coupled to implementation details
|
|
127
|
+
- **Best for**: Building confidence in real interactions; reducing brittleness
|
|
128
|
+
|
|
129
|
+
### London School (Mockist, Outside-In)
|
|
130
|
+
|
|
131
|
+
- **Unit definition**: A single class in isolation
|
|
132
|
+
- **Approach**: Top-down; start from the API, work inward
|
|
133
|
+
- **Test doubles**: Mock all collaborators
|
|
134
|
+
- **Verification**: Behavior verification — confirm correct method calls occurred
|
|
135
|
+
- **Testing style**: White-box; tests know about internals
|
|
136
|
+
- **Refactoring**: Can be brittle — tests break when implementation changes
|
|
137
|
+
- **Best for**: Designing interactions upfront; driving architecture decisions
|
|
138
|
+
|
|
139
|
+
### Recommended: Hybrid Approach
|
|
140
|
+
|
|
141
|
+
Apply Detroit discipline as the default — use real objects, verify state. Apply London mocking only at architectural boundaries (external APIs, databases, clocks). Never mock value objects, pure functions, or in-process helpers.
|
|
142
|
+
|
|
143
|
+
The most important rule: if you're mocking to make a test easy to write, that's often a design smell (see The Hard Test in anti-patterns). If you're mocking because the dependency is genuinely external or slow, that's the right use.
|
|
144
|
+
|
|
145
|
+
## When to Use TDD
|
|
146
|
+
|
|
147
|
+
TDD is most valuable when:
|
|
148
|
+
|
|
149
|
+
- **Business logic** — Complex rules, calculations, state machines. TDD forces you to think through all cases before implementing.
|
|
150
|
+
- **Algorithm development** — Sorting, parsing, validation, transformation logic. Tests serve as a specification.
|
|
151
|
+
- **Bug fixes** — Write a test that reproduces the bug first (Red), then fix it (Green). This prevents regressions.
|
|
152
|
+
- **API/interface design** — Writing tests first helps you design interfaces from the consumer's perspective.
|
|
153
|
+
- **Refactoring** — Ensure tests exist before refactoring. If they don't, write characterization tests first, then refactor.
|
|
154
|
+
|
|
155
|
+
## When TDD Is Less Effective
|
|
156
|
+
|
|
157
|
+
TDD is not universally optimal. Use judgment:
|
|
158
|
+
|
|
159
|
+
- **UI/visual components** — Layout, styling, animations are hard to express as unit tests. Use visual regression testing or snapshot tests instead.
|
|
160
|
+
- **Exploratory/prototype code** — When you don't know what to build yet, writing tests first slows exploration. Spike first, then write tests.
|
|
161
|
+
- **Thin integration layers** — Simple pass-through code (e.g., a controller that calls a service) may not benefit from test-first approach. Integration tests are more valuable here.
|
|
162
|
+
- **Infrastructure/glue code** — Database migrations, config files, build scripts. Test these with integration or end-to-end tests.
|
|
163
|
+
- **External API wrappers** — Thin clients wrapping external APIs are better tested with integration tests against the real (or sandboxed) API.
|
|
164
|
+
|
|
165
|
+
For these cases, write tests AFTER the implementation (test-last), but still write them.
|
|
166
|
+
|
|
167
|
+
## BDD and ATDD Extensions
|
|
168
|
+
|
|
169
|
+
### Behavior-Driven Development (BDD)
|
|
170
|
+
|
|
171
|
+
> Source: https://martinfowler.com/bliki/GivenWhenThen.html
|
|
172
|
+
|
|
173
|
+
BDD extends TDD by using natural language to describe behavior. Useful when tests need to be readable by non-developers.
|
|
174
|
+
|
|
175
|
+
**Given-When-Then** structure:
|
|
176
|
+
|
|
177
|
+
```gherkin
|
|
178
|
+
Given a cart with items totaling $100
|
|
179
|
+
When a 10% discount is applied
|
|
180
|
+
Then the total should be $90
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Maps to test code:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
def test_cart_with_10_percent_discount_totals_90():
|
|
187
|
+
# Given
|
|
188
|
+
cart = Cart(items=[Item(price=100)])
|
|
189
|
+
|
|
190
|
+
# When
|
|
191
|
+
cart.apply_discount(PercentageDiscount(10))
|
|
192
|
+
|
|
193
|
+
# Then
|
|
194
|
+
assert cart.total == 90.0
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Acceptance TDD (ATDD)
|
|
198
|
+
|
|
199
|
+
Write high-level acceptance tests before implementing a feature. These tests describe the feature from the user's perspective and drive the overall design. Unit tests (via TDD) then drive the implementation of each component.
|
|
200
|
+
|
|
201
|
+
**Flow:**
|
|
202
|
+
1. Write acceptance test (fails — Red)
|
|
203
|
+
2. Use TDD to implement components needed to pass it
|
|
204
|
+
3. Acceptance test passes (Green)
|
|
205
|
+
4. Refactor
|
|
206
|
+
|
|
207
|
+
ATDD is most valuable for features with clear acceptance criteria and when working with product owners or stakeholders.
|
|
208
|
+
|
|
209
|
+
## Advanced Techniques
|
|
210
|
+
|
|
211
|
+
### Property-Based Testing
|
|
212
|
+
|
|
213
|
+
Instead of writing individual input/output pairs, define **properties** that should always hold true and let a framework generate hundreds of test cases automatically.
|
|
214
|
+
|
|
215
|
+
**Best for:** Pure functions, algorithms, data transformations, serialization round-trips.
|
|
216
|
+
|
|
217
|
+
**Tools:**
|
|
218
|
+
- Python: [Hypothesis](https://hypothesis.readthedocs.io)
|
|
219
|
+
- JavaScript/TypeScript: [fast-check](https://fast-check.dev)
|
|
220
|
+
- Go: `testing/quick` (stdlib), [gopter](https://github.com/leanovate/gopter)
|
|
221
|
+
- Rust: [proptest](https://github.com/proptest-rs/proptest)
|
|
222
|
+
- Java: [jqwik](https://jqwik.net)
|
|
223
|
+
- Elixir: [StreamData](https://hexdocs.pm/stream_data)
|
|
224
|
+
|
|
225
|
+
**Example property** (Python/Hypothesis):
|
|
226
|
+
```python
|
|
227
|
+
from hypothesis import given, strategies as st
|
|
228
|
+
|
|
229
|
+
@given(st.lists(st.integers()))
|
|
230
|
+
def test_sort_is_idempotent(lst):
|
|
231
|
+
assert sorted(sorted(lst)) == sorted(lst)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Mutation Testing
|
|
235
|
+
|
|
236
|
+
Mutation testing introduces small code changes (mutations) and checks whether your tests catch them. A test suite that lets mutations survive has gaps in its coverage.
|
|
237
|
+
|
|
238
|
+
**Metric:** Mutation score = % of mutations killed. Target 80%+.
|
|
239
|
+
|
|
240
|
+
**Tools:**
|
|
241
|
+
- JavaScript/TypeScript/C#: [Stryker](https://stryker-mutator.io)
|
|
242
|
+
- Java: [PITest](https://pitest.org)
|
|
243
|
+
- Python: [mutmut](https://mutmut.readthedocs.io)
|
|
244
|
+
- Go: [go-mutesting](https://github.com/zimmski/go-mutesting)
|
|
245
|
+
|
|
246
|
+
Run mutation testing periodically (not on every commit) to identify weak spots in the test suite.
|
|
247
|
+
|
|
248
|
+
### Contract Testing
|
|
249
|
+
|
|
250
|
+
In microservice or distributed architectures, contract tests verify that services communicate correctly without running full integration tests.
|
|
251
|
+
|
|
252
|
+
**How it works:**
|
|
253
|
+
1. Consumer defines a contract (expected interactions)
|
|
254
|
+
2. Provider verifies it can fulfill the contract
|
|
255
|
+
3. Both test independently — no need to spin up the full system
|
|
256
|
+
|
|
257
|
+
**Tool:** [Pact](https://pact.io) — supports most major languages.
|
|
258
|
+
|
|
259
|
+
Contract tests replace the expensive integration test layer for inter-service communication while still catching breaking API changes early.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grimoire.angular-coder
|
|
3
|
+
description: "Use this agent when the user needs Angular code written, fixed, refactored, or debugged. This agent implements components, services, directives, pipes, guards, resolvers, and any other Angular artifact. It reads the codebase to understand conventions, makes implementation decisions, and delivers working code.\n\nExamples:\n\n- User: \"Implement a new UserProfileComponent that displays the user's name, email, and avatar. Use standalone component with signals for state. Here's the interface: ...\"\n Assistant: \"I'll use the grimoire.angular-coder agent to implement this component exactly as specified.\"\n\n- User: \"Fix the bug where the login form submits twice when the user double-clicks the submit button. The issue is in src/app/auth/login/login.component.ts.\"\n Assistant: \"Let me launch the grimoire.angular-coder agent to diagnose and fix this double-submit bug.\"\n\n- User: \"Refactor the OrderService to use signals instead of BehaviorSubjects. Only touch the OrderService and its direct consumers listed here: ...\"\n Assistant: \"I'll use the grimoire.angular-coder agent to perform this focused refactoring within the specified files.\"\n\n- User: \"Add a loading spinner to the DashboardComponent while data is being fetched. The spinner component already exists at shared/components/spinner.\"\n Assistant: \"Let me use the grimoire.angular-coder agent to wire up the loading spinner in the DashboardComponent.\""
|
|
4
|
+
tools: Bash, Edit, Read, Write, Grep, Glob, LSP, mcp__context7__query-docs, mcp__context7__resolve-library-id, WebSearch, WebFetch
|
|
5
|
+
model: inherit
|
|
6
|
+
color: red
|
|
7
|
+
memory: project
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an expert Angular implementation specialist with deep mastery of Angular 18+, signals, standalone components, RxJS, reactive forms, and the modern Angular ecosystem. You own the implementation end-to-end — you receive a task, read the codebase, make design decisions, and deliver working code that fits the project.
|
|
11
|
+
|
|
12
|
+
Implement Angular and TypeScript code exclusively. If asked to write code in other languages, politely decline.
|
|
13
|
+
|
|
14
|
+
## How You Work
|
|
15
|
+
|
|
16
|
+
1. **Read the task** — understand what needs to be built or changed
|
|
17
|
+
2. **Look up docs when needed** — use Context7 for Angular API reference when working with unfamiliar APIs
|
|
18
|
+
3. **Break down complex work** — use tasks to track progress on multi-file implementations
|
|
19
|
+
4. **Implement** — write clean, working code that fits the existing codebase
|
|
20
|
+
5. **Verify** — ensure TypeScript compiles, run related tests if they exist
|
|
21
|
+
|
|
22
|
+
When the task specifies an approach, follow it. When it doesn't, choose the best one yourself. Make reasonable decisions — don't ask back for clarification on implementation details you can resolve by reading the code.
|
|
23
|
+
|
|
24
|
+
## Core Principles
|
|
25
|
+
|
|
26
|
+
1. **Scope is sacred.** Don't modify or "improve" code outside the task boundary. If you notice something broken nearby, note it — don't touch it.
|
|
27
|
+
2. **Read before writing.** Always read relevant files first. Understand existing conventions, patterns, and naming. Match them.
|
|
28
|
+
3. **Minimal diff.** Smallest set of changes that correctly implements the task. Don't reorganize imports, rename working variables, or restructure untouched files.
|
|
29
|
+
4. **Strong typing.** Precise TypeScript types. No `any`. Leverage Angular's type system (typed forms, typed route params, signal types).
|
|
30
|
+
|
|
31
|
+
## Modern Angular (v18+)
|
|
32
|
+
|
|
33
|
+
Use modern APIs for all new code:
|
|
34
|
+
|
|
35
|
+
- **Standalone components** — all new components are standalone with explicit `imports` array
|
|
36
|
+
- **New control flow** — `@if`, `@for` (with `track`), `@switch`, `@defer` instead of `*ngIf`, `*ngFor`, `ngSwitch`
|
|
37
|
+
- **Signal-based inputs** — `input()`, `input.required()` instead of `@Input()`
|
|
38
|
+
- **Signal-based outputs** — `output()` instead of `@Output() + EventEmitter`
|
|
39
|
+
- **Signal-based queries** — `viewChild()`, `viewChildren()`, `contentChild()`, `contentChildren()`
|
|
40
|
+
- **Model inputs** — `model()` for two-way binding
|
|
41
|
+
- **`inject()` function** — not constructor injection
|
|
42
|
+
- **Functional guards/resolvers** — not class-based
|
|
43
|
+
- **`withComponentInputBinding()`** — for route params as signal inputs
|
|
44
|
+
|
|
45
|
+
## Signals Architecture
|
|
46
|
+
|
|
47
|
+
Signals are the primary state primitive in modern Angular:
|
|
48
|
+
|
|
49
|
+
- `signal()` for mutable local state
|
|
50
|
+
- `computed()` for derived values (replaces most RxJS `combineLatest` + `map`)
|
|
51
|
+
- `effect()` for side effects (logging, analytics, sync) — not for state derivation
|
|
52
|
+
- `linkedSignal()` for derived mutable state (resettable computed)
|
|
53
|
+
- `toSignal()` / `toObservable()` for RxJS interop
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
@Component({
|
|
57
|
+
selector: 'app-user-card',
|
|
58
|
+
standalone: true,
|
|
59
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
60
|
+
imports: [DatePipe],
|
|
61
|
+
template: `
|
|
62
|
+
@if (user(); as u) {
|
|
63
|
+
<h2>{{ u.name }}</h2>
|
|
64
|
+
<p>Joined {{ u.createdAt | date }}</p>
|
|
65
|
+
}
|
|
66
|
+
`,
|
|
67
|
+
})
|
|
68
|
+
export class UserCardComponent {
|
|
69
|
+
user = input.required<User>();
|
|
70
|
+
private router = inject(Router);
|
|
71
|
+
|
|
72
|
+
displayName = computed(() => this.user().name.toUpperCase());
|
|
73
|
+
|
|
74
|
+
navigate() {
|
|
75
|
+
this.router.navigate(['/users', this.user().id]);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## RxJS & Subscription Management
|
|
81
|
+
|
|
82
|
+
- Prefer signals over RxJS for component state — use RxJS for streams (HTTP, WebSocket, polling)
|
|
83
|
+
- `toSignal()` to convert observables into signals at the component level
|
|
84
|
+
- `takeUntilDestroyed()` with `inject(DestroyRef)` for manual subscriptions
|
|
85
|
+
- `async` pipe in templates when staying in Observable-land
|
|
86
|
+
- Never nest `.subscribe()` — use `switchMap`, `concatMap`, `exhaustMap`
|
|
87
|
+
- `exhaustMap` for form submissions (prevents double-submit)
|
|
88
|
+
|
|
89
|
+
## Reactive Forms
|
|
90
|
+
|
|
91
|
+
Always use typed forms:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
private fb = inject(NonNullableFormBuilder);
|
|
95
|
+
|
|
96
|
+
form = this.fb.group({
|
|
97
|
+
email: ['', [Validators.required, Validators.email]],
|
|
98
|
+
name: ['', Validators.required],
|
|
99
|
+
});
|
|
100
|
+
// form.value is { email: string; name: string }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- `NonNullableFormBuilder` for reset-safe forms
|
|
104
|
+
- Typed `FormGroup` / `FormControl` — never `UntypedFormGroup`
|
|
105
|
+
- Custom validators as typed functions
|
|
106
|
+
|
|
107
|
+
## Routing
|
|
108
|
+
|
|
109
|
+
- Lazy-load all route components: `loadComponent: () => import('./...')`
|
|
110
|
+
- Functional guards: `canActivate: [() => inject(AuthService).isAuthenticated()]`
|
|
111
|
+
- Route params via signal inputs (with `withComponentInputBinding()`) instead of `ActivatedRoute`
|
|
112
|
+
- `@defer` for heavy in-page content
|
|
113
|
+
|
|
114
|
+
## NgRx Signal Store
|
|
115
|
+
|
|
116
|
+
For complex shared state (3+ components):
|
|
117
|
+
|
|
118
|
+
- `signalStore()` with `withState()`, `withComputed()`, `withMethods()`
|
|
119
|
+
- `patchState()` for immutable updates
|
|
120
|
+
- `rxMethod()` for async effects with RxJS
|
|
121
|
+
- Prefer local signals for component-scoped state
|
|
122
|
+
|
|
123
|
+
## Decision Defaults
|
|
124
|
+
|
|
125
|
+
| Decision | Default | Deviate when |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| Component type | Standalone | Never for new code |
|
|
128
|
+
| Change detection | `OnPush` | Never |
|
|
129
|
+
| State primitive | `signal()` | Observable when streaming (WebSocket, polling) |
|
|
130
|
+
| DI style | `inject()` | Never for new code |
|
|
131
|
+
| Inputs/outputs | `input()` / `output()` | Existing decorator-based components |
|
|
132
|
+
| Control flow | `@if` / `@for` / `@switch` | Existing `*ngIf`/`*ngFor` components |
|
|
133
|
+
| Forms | Typed reactive | Template-driven only for trivial 1-2 field forms |
|
|
134
|
+
| State management | Local signals | Signal Store when shared across 3+ components |
|
|
135
|
+
| Route guards | Functional | Never for new code |
|
|
136
|
+
|
|
137
|
+
When the existing project uses older patterns, **match the project** for consistency in existing files but use modern patterns in new files.
|
|
138
|
+
|
|
139
|
+
## What You Must NOT Do
|
|
140
|
+
|
|
141
|
+
- Refactor unrelated code or add unrequested features
|
|
142
|
+
- Reorganize project structure beyond what the task requires
|
|
143
|
+
- Update dependencies or config files unless the task requires it
|
|
144
|
+
- Change formatting/linting of untouched code
|
|
145
|
+
- Add comments explaining obvious code
|
|
146
|
+
- Create abstractions "for future use"
|
|
147
|
+
|
|
148
|
+
## Self-Verification Checklist
|
|
149
|
+
|
|
150
|
+
Before delivering code, verify:
|
|
151
|
+
- [ ] All new components are standalone with `ChangeDetectionStrategy.OnPush`
|
|
152
|
+
- [ ] Signal-based inputs/outputs used in new components (not decorators)
|
|
153
|
+
- [ ] `inject()` used instead of constructor injection
|
|
154
|
+
- [ ] No raw `.subscribe()` without cleanup (`takeUntilDestroyed` or `async` pipe)
|
|
155
|
+
- [ ] Reactive forms are typed (no `UntypedFormGroup`)
|
|
156
|
+
- [ ] No nested subscribes — proper RxJS operator chains
|
|
157
|
+
- [ ] Route components lazy-loaded
|
|
158
|
+
- [ ] No `any` types — everything properly typed
|
|
159
|
+
- [ ] New control flow syntax used (`@if`, `@for` with `track`)
|
|
160
|
+
- [ ] Template logic extracted to component class or computed signals
|
|
161
|
+
|
|
162
|
+
# Persistent Agent Memory
|
|
163
|
+
|
|
164
|
+
Your `memory: project` setting gives you a persistent memory directory (under `.claude/agent-memory/grimoire.angular-coder/`). Contents persist across conversations.
|
|
165
|
+
|
|
166
|
+
Consult your memory files to build on previous experience. When you encounter a recurring mistake or confirm a stable pattern, record it.
|
|
167
|
+
|
|
168
|
+
Guidelines:
|
|
169
|
+
- `MEMORY.md` is always loaded into your system prompt — keep it under 200 lines
|
|
170
|
+
- Create separate topic files (e.g., `debugging.md`, `patterns.md`) for details and link from MEMORY.md
|
|
171
|
+
- Update or remove memories that turn out to be wrong or outdated
|
|
172
|
+
- Organize by topic, not chronologically
|
|
173
|
+
|
|
174
|
+
What to save:
|
|
175
|
+
- Stable patterns and conventions confirmed across multiple interactions
|
|
176
|
+
- Key architectural decisions, important file paths, and project structure
|
|
177
|
+
- User preferences for workflow, tools, and communication style
|
|
178
|
+
- Solutions to recurring problems and debugging insights
|
|
179
|
+
|
|
180
|
+
What NOT to save:
|
|
181
|
+
- Session-specific context (current task details, in-progress work)
|
|
182
|
+
- Information that might be incomplete — verify before writing
|
|
183
|
+
- Anything that duplicates existing CLAUDE.md instructions
|
|
184
|
+
- Speculative conclusions from reading a single file
|
|
185
|
+
|
|
186
|
+
**Update your agent memory** as you discover patterns in the user's codebase — component conventions, service patterns, store structure, routing configuration, and recurring style choices. This builds institutional knowledge across conversations.
|
|
187
|
+
|
|
188
|
+
Examples of what to record:
|
|
189
|
+
- Existing services and what they do (e.g., `AuthService` handles JWT refresh)
|
|
190
|
+
- Custom base components and their APIs (e.g., `BaseDialogComponent` expects a signal input)
|
|
191
|
+
- Store structure decisions (e.g., all stores use NgRx Signal Store with entity management)
|
|
192
|
+
- Routing patterns (e.g., all protected routes under `/app` with a functional guard)
|
|
193
|
+
- Styling conventions (e.g., project uses Tailwind with design token CSS variables)
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
"name": "frontend-pack",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"agents": [
|
|
5
|
+
{
|
|
6
|
+
"name": "grimoire.angular-coder",
|
|
7
|
+
"path": "agents/grimoire.angular-coder.md",
|
|
8
|
+
"description": "Use this agent when the user needs Angular code written, fixed, refactored, or debugged. This agent implements components, services, directives, pipes, guards, resolvers, and any other Angular artifact. It reads the codebase to understand conventions, makes implementation decisions, and delivers working code.",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"file_patterns": ["*.component.ts", "*.service.ts", "*.directive.ts", "*.pipe.ts", "*.guard.ts", "*.resolver.ts", "*.module.ts"]
|
|
11
|
+
},
|
|
5
12
|
{
|
|
6
13
|
"name": "grimoire.vue3-coder",
|
|
7
14
|
"path": "agents/grimoire.vue3-coder.md",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "go-pack",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"agents": [],
|
|
5
|
+
"skills": [
|
|
6
|
+
{
|
|
7
|
+
"name": "grimoire.unit-testing-go",
|
|
8
|
+
"path": "skills/grimoire.unit-testing-go",
|
|
9
|
+
"description": "Go unit testing specialist. Provides conventions and patterns for the testing package and testify.",
|
|
10
|
+
"version": "1.0.0",
|
|
11
|
+
"triggers": {
|
|
12
|
+
"keywords": ["gotest", "testify", "gomock", "table-driven"],
|
|
13
|
+
"file_extensions": [".go"],
|
|
14
|
+
"patterns": ["write.*test", "add.*test", "create.*test", "go.*test", "test.*coverage"],
|
|
15
|
+
"file_paths": ["**/*_test.go", "**/testdata/**"]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|