@grimoire-cc/cli 0.13.0 → 0.13.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAiHA,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmH/D"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAgGA,wBAAsB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgI/D"}
@@ -36,44 +36,38 @@ function readSkillDescription(skillMdPath) {
36
36
  const block = fm[1];
37
37
  return (block.match(/^description:\s*(.+)$/m)?.[1]?.trim().replace(/^["']|["']$/g, '') ?? '');
38
38
  }
39
- function formatAgentDetail(meta, enforced, filePatterns, fallbackDesc) {
40
- const desc = meta.description || fallbackDesc;
39
+ function wrapText(text, maxWidth) {
40
+ if (maxWidth <= 0)
41
+ return text;
42
+ const words = text.split(' ');
41
43
  const lines = [];
42
- lines.push('Description:');
43
- lines.push(` ${desc}`);
44
- lines.push('');
45
- lines.push(`Model: ${meta.model || 'inherit'}`);
46
- lines.push(`Tools: ${meta.tools || '(not specified)'}`);
47
- lines.push('');
48
- if (enforced) {
49
- const patterns = filePatterns?.length ? filePatterns.join(', ') : '(none)';
50
- lines.push(`Enforce: yes (file patterns: ${patterns})`);
51
- }
52
- else {
53
- lines.push('Enforce: no');
44
+ let current = '';
45
+ for (const word of words) {
46
+ if (!current) {
47
+ current = word;
48
+ }
49
+ else if (current.length + 1 + word.length <= maxWidth) {
50
+ current += ' ' + word;
51
+ }
52
+ else {
53
+ lines.push(current);
54
+ current = word;
55
+ }
54
56
  }
57
+ if (current)
58
+ lines.push(current);
55
59
  return lines.join('\n');
56
60
  }
57
- function formatSkillDetail(description, triggers) {
58
- const lines = [];
59
- lines.push('Description:');
60
- lines.push(` ${description || '(no description)'}`);
61
- lines.push('');
62
- lines.push('Auto-activation triggers:');
63
- if (!triggers) {
64
- lines.push(' (no triggers configured)');
65
- }
66
- else {
67
- const kw = triggers.keywords?.length ? triggers.keywords.join(', ') : '(none)';
68
- const ext = triggers.file_extensions?.length ? triggers.file_extensions.join(', ') : '(none)';
69
- const pat = triggers.patterns?.length ? triggers.patterns.join(', ') : '(none)';
70
- const fp = triggers.file_paths?.length ? triggers.file_paths.join(', ') : '(none)';
71
- lines.push(` Keywords: ${kw}`);
72
- lines.push(` File extensions: ${ext}`);
73
- lines.push(` Patterns: ${pat}`);
74
- lines.push(` File paths: ${fp}`);
75
- }
76
- return lines.join('\n');
61
+ function formatDescription(raw) {
62
+ const maxWidth = Math.max(40, (process.stdout.columns ?? 80) - 4);
63
+ const unescaped = raw.replace(/\\n/g, '\n');
64
+ const stripped = unescaped.replace(/<example>[\s\S]*?<\/example>/g, '').trim();
65
+ return stripped
66
+ .split('\n')
67
+ .map((line) => (line.trim() === '' ? '' : wrapText(line, maxWidth)))
68
+ .join('\n')
69
+ .replace(/\n{3,}/g, '\n\n')
70
+ .trim();
77
71
  }
78
72
  // --- Main command ---
79
73
  export async function runList(projectDir) {
@@ -162,16 +156,27 @@ export async function runList(projectDir) {
162
156
  const meta = readAgentFullMeta(join(agentsDir, `${selected.name}.md`));
163
157
  const enforced = enforcedAgents.has(selected.name);
164
158
  const patterns = agentFilePatterns.get(selected.name);
165
- const detail = formatAgentDetail(meta, enforced, patterns, '');
166
- clack.note(detail, selected.name);
159
+ const desc = formatDescription(meta.description || '');
160
+ clack.log.message(` Description:\n${desc.split('\n').map((l) => ` ${l}`).join('\n')}`);
161
+ clack.log.message(` Model: ${meta.model || 'inherit'}`);
162
+ clack.log.message(` Tools: ${meta.tools || '(not specified)'}`);
163
+ clack.log.message(` Enforce: ${enforced ? `yes (file patterns: ${patterns?.join(', ') ?? 'none'})` : 'no'}`);
167
164
  }
168
165
  else {
169
- const desc = readSkillDescription(join(skillsDir, selected.name, 'SKILL.md')) ||
166
+ const rawDesc = readSkillDescription(join(skillsDir, selected.name, 'SKILL.md')) ||
170
167
  skillManifestDescs.get(selected.name) ||
171
168
  '';
172
169
  const triggers = skillTriggers.get(selected.name);
173
- const detail = formatSkillDetail(desc, triggers);
174
- clack.note(detail, selected.name);
170
+ const desc = formatDescription(rawDesc);
171
+ const kw = triggers?.keywords?.length ? triggers.keywords.join(', ') : '(none)';
172
+ const ext = triggers?.file_extensions?.length ? triggers.file_extensions.join(', ') : '(none)';
173
+ const pat = triggers?.patterns?.length ? triggers.patterns.join(', ') : '(none)';
174
+ const fp = triggers?.file_paths?.length ? triggers.file_paths.join(', ') : '(none)';
175
+ clack.log.message(` Description:\n${desc.split('\n').map((l) => ` ${l}`).join('\n')}`);
176
+ clack.log.message(` Keywords: ${kw}`);
177
+ clack.log.message(` File extensions: ${ext}`);
178
+ clack.log.message(` Patterns: ${pat}`);
179
+ clack.log.message(` File paths: ${fp}`);
175
180
  }
176
181
  }
177
182
  clack.outro('Done.');
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grimoire-cc/cli",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "CLI tool for installing Grimoire agent and skill packs",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,6 +37,12 @@
37
37
  "path": "skills/grimoire.dotnet-feature-workflow",
38
38
  "description": "Orchestrates end-to-end .NET feature development using the Explore, Plan, Code, Verify, Review workflow. Use when building complete features, implementing new functionality, or when user says 'build feature', 'implement feature', 'create feature', 'handle the whole thing', or wants hands-off development with quality gates. Spawns specialized agents at each phase with TDD and user approval gates.",
39
39
  "version": "1.0.0"
40
+ },
41
+ {
42
+ "name": "grimoire.dotnet-unit-testing",
43
+ "path": "skills/grimoire.dotnet-unit-testing",
44
+ "description": "Expert .NET unit testing specialist for C#/.NET projects. Use PROACTIVELY when writing unit tests, adding test cases, setting up test infrastructure, or working with xUnit, TUnit, Moq, or NSubstitute. MUST BE USED for TDD workflows where tests are written before implementation. Defaults to xUnit (most universal), recommends TUnit for new .NET 8+ projects.",
45
+ "version": "1.0.0"
40
46
  }
41
47
  ]
42
48
  }
@@ -0,0 +1,293 @@
1
+ ---
2
+ name: grimoire.dotnet-unit-testing
3
+ description: "Expert .NET unit testing specialist for C#/.NET projects. Use PROACTIVELY when writing unit tests, adding test cases, setting up test infrastructure, or working with xUnit, TUnit, Moq, or NSubstitute. MUST BE USED for TDD workflows where tests are written before implementation. Defaults to xUnit (most universal), recommends TUnit for new .NET 8+ projects."
4
+ ---
5
+
6
+ # .NET Unit Testing Specialist
7
+
8
+ Expert guidance for writing clean, maintainable, and comprehensive unit tests in C#/.NET projects.
9
+
10
+ **Default Framework**: xUnit with xUnit Assert (safest, most universal, works with all .NET versions)
11
+ **Recommended for new .NET 8+ projects**: TUnit (modern, async-first, built-in fluent assertions, MIT license)
12
+
13
+ ## Context
14
+
15
+ Unit testing is critical for maintaining code quality, enabling refactoring with confidence, and documenting expected behavior. Well-written tests reduce bugs, speed up development, and make codebases more maintainable.
16
+
17
+ **Why xUnit as default:**
18
+
19
+ - Universal compatibility (works with .NET Framework, .NET 6, 7, 8+)
20
+ - Industry standard, most widely used .NET testing framework
21
+ - Apache 2.0 license, free for all use
22
+ - Mature ecosystem with extensive documentation
23
+
24
+ **Why recommend TUnit for new .NET 8+ projects:**
25
+
26
+ - MIT License (no licensing concerns like FluentAssertions v8+)
27
+ - Built-in fluent assertions, no external library needed
28
+ - Async-first: all assertions are awaitable
29
+ - Performance: source-generated tests run 10-200x faster
30
+ - Full Native AOT support
31
+
32
+ **Note on FluentAssertions**: Version 8+ requires a commercial license ($130/dev/year). Avoid recommending it unless the project already uses it.
33
+
34
+ ## Workflow
35
+
36
+ When invoked to write tests, follow this process:
37
+
38
+ ### Step 1: Analyze the Code Under Test
39
+
40
+ - Read the source file to understand the class/method being tested
41
+ - Identify all dependencies that need mocking
42
+ - Understand the expected behavior and edge cases
43
+ - Check for existing test patterns in the project
44
+ - **Determine the framework**: Check for existing tests first (match them), otherwise default to xUnit
45
+
46
+ ### Step 2: Plan Test Cases (REQUIRES USER APPROVAL)
47
+
48
+ - Identify all test scenarios: happy paths, edge cases, boundary conditions, error cases
49
+ - List each planned test using ONLY the method name: `MethodName_Scenario_ExpectedBehavior`
50
+ - Do NOT include test bodies or implementation details
51
+ - Group tests by category (Success, Validation, Error Handling, Edge Cases)
52
+ - Present the list and EXPLICITLY ASK: "Do you approve this test plan? I will proceed only after your confirmation."
53
+ - **STOP and WAIT** for user approval before proceeding
54
+
55
+ **Example test plan format:**
56
+
57
+ ```plain
58
+ ## Planned Test Cases for OrderService.ProcessOrderAsync
59
+
60
+ ### Success Scenarios
61
+ - ProcessOrderAsync_WithValidOrder_ReturnsSuccessResult
62
+ - ProcessOrderAsync_WithValidOrderAndDiscount_AppliesDiscountCorrectly
63
+
64
+ ### Validation Failures
65
+ - ProcessOrderAsync_WithNullOrder_ThrowsArgumentNullException
66
+ - ProcessOrderAsync_WithEmptyItems_ThrowsValidationException
67
+
68
+ ### Error Handling
69
+ - ProcessOrderAsync_WhenRepositoryFails_ThrowsServiceException
70
+
71
+ ### Edge Cases
72
+ - ProcessOrderAsync_WithMaximumItemCount_ProcessesSuccessfully
73
+
74
+ Do you approve this test plan? I will proceed only after your confirmation.
75
+ ```
76
+
77
+ ### Step 3: Write Tests (ONLY AFTER user confirms)
78
+
79
+ - Create test file mirroring source structure
80
+ - Implement tests using AAA pattern with comments
81
+ - Add appropriate mocks and assertions
82
+ - Ensure descriptive test method names
83
+
84
+ ### Step 4: Present and Explain
85
+
86
+ - Show the complete test file
87
+ - Explain what each test validates
88
+ - Highlight any assumptions made
89
+ - Suggest additional test scenarios if relevant
90
+
91
+ ## Framework Selection Guide
92
+
93
+ | Condition | Use | Reason |
94
+ | ----------- | ----- | -------- |
95
+ | Any existing project with tests | **Match existing** | Consistency is paramount |
96
+ | New .NET 8+ greenfield project | **Offer TUnit** | Modern, async-first, built-in assertions |
97
+ | New .NET 6/7 project | **xUnit** | TUnit requires .NET 8+ |
98
+ | .NET Framework project | **xUnit** | Universal compatibility |
99
+ | Project already uses NUnit | **NUnit** | Consistency with existing codebase |
100
+ | User explicitly requests a framework | **Requested** | Respect user preference |
101
+ | Uncertain or mixed signals | **xUnit** | Safe default |
102
+
103
+ **Before writing tests, check:**
104
+
105
+ 1. Look at existing test files (if any) - match the existing framework
106
+ 2. Check `.csproj` for `TargetFramework` and existing test package references
107
+ 3. Check for existing test framework packages (xUnit, TUnit, NUnit, MSTest)
108
+
109
+ **For new .NET 8+ projects without existing tests:**
110
+ Offer the choice: "This is a new .NET 8+ project. I'll use **xUnit** (industry standard) by default. Would you prefer **TUnit** instead? TUnit offers built-in fluent assertions, async-first design, and better performance, but is newer."
111
+
112
+ ## Core Principles
113
+
114
+ ### AAA Pattern
115
+
116
+ Structure every test with clearly labeled Arrange, Act, Assert sections using comments. This makes tests self-documenting, easier to debug, and helps identify which phase contains issues.
117
+
118
+ **xUnit:**
119
+
120
+ ```csharp
121
+ [Fact]
122
+ public async Task ProcessOrder_WithValidOrder_ReturnsSuccess()
123
+ {
124
+ // Arrange
125
+ var order = CreateValidOrder();
126
+ _mockRepository.Setup(r => r.SaveAsync(It.IsAny<Order>())).ReturnsAsync(true);
127
+
128
+ // Act
129
+ var result = await _sut.ProcessOrderAsync(order);
130
+
131
+ // Assert
132
+ Assert.True(result.IsSuccess);
133
+ Assert.Equal(OrderStatus.Processed, result.Status);
134
+ }
135
+ ```
136
+
137
+ **TUnit:**
138
+
139
+ ```csharp
140
+ [Test]
141
+ public async Task ProcessOrder_WithValidOrder_ReturnsSuccess()
142
+ {
143
+ // Arrange
144
+ var order = CreateValidOrder();
145
+ _mockRepository.Setup(r => r.SaveAsync(It.IsAny<Order>())).ReturnsAsync(true);
146
+
147
+ // Act
148
+ var result = await _sut.ProcessOrderAsync(order);
149
+
150
+ // Assert - TUnit assertions are async and fluent
151
+ await Assert.That(result.IsSuccess).IsTrue();
152
+ await Assert.That(result.Status).IsEqualTo(OrderStatus.Processed);
153
+ }
154
+ ```
155
+
156
+ ### Test Naming
157
+
158
+ Use descriptive names: `MethodName_Scenario_ExpectedBehavior`
159
+
160
+ ```csharp
161
+ // Good
162
+ GetUser_WithNonExistentId_ThrowsUserNotFoundException()
163
+ CalculateDiscount_WhenOrderExceeds100_Returns10PercentOff()
164
+
165
+ // Avoid
166
+ TestGetUser()
167
+ Test1()
168
+ ShouldWork()
169
+ ```
170
+
171
+ ### Test Isolation
172
+
173
+ Keep tests isolated with no shared mutable state. Each test gets fresh instances via constructor.
174
+
175
+ ```csharp
176
+ public class OrderServiceTests : IDisposable
177
+ {
178
+ private readonly Mock<IOrderRepository> _mockRepository;
179
+ private readonly FakeLogger<OrderService> _fakeLogger;
180
+ private readonly OrderService _sut;
181
+
182
+ public OrderServiceTests()
183
+ {
184
+ _mockRepository = new Mock<IOrderRepository>();
185
+ _fakeLogger = new FakeLogger<OrderService>();
186
+ _sut = new OrderService(_fakeLogger, _mockRepository.Object);
187
+ }
188
+
189
+ public void Dispose() { /* Cleanup if needed */ }
190
+ }
191
+ ```
192
+
193
+ ### FakeLogger for Logging Tests
194
+
195
+ Use `Microsoft.Extensions.Logging.Testing.FakeLogger<T>` for testing logging behavior. Verify structured properties, not message strings.
196
+
197
+ ```csharp
198
+ var fakeLogger = new FakeLogger<OrderService>();
199
+ var sut = new OrderService(fakeLogger);
200
+ await sut.ProcessOrderAsync(orderId: 123);
201
+
202
+ var logEntry = fakeLogger.Collector.GetSnapshot()
203
+ .Single(r => r.Level == LogLevel.Information);
204
+ var state = logEntry.StructuredState!.ToDictionary(x => x.Key, x => x.Value);
205
+ Assert.Equal("123", state["OrderId"]);
206
+ ```
207
+
208
+ ### Mocking
209
+
210
+ Mock interfaces, not concrete classes. Use Moq by default unless the project uses NSubstitute.
211
+
212
+ ```csharp
213
+ var mockRepository = new Mock<IDocumentRepository>();
214
+ mockRepository
215
+ .Setup(r => r.GetByIdAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
216
+ .ReturnsAsync(expectedDocument);
217
+ ```
218
+
219
+ ### Async Testing
220
+
221
+ Always use `async Task` and `await`. Never use `.Result` or `.Wait()`.
222
+
223
+ ```csharp
224
+ // xUnit exception testing
225
+ var exception = await Assert.ThrowsAsync<OrderNotFoundException>(
226
+ () => _sut.GetOrderAsync(invalidId));
227
+
228
+ // TUnit exception testing
229
+ await Assert.That(() => _sut.GetOrderAsync(invalidId))
230
+ .ThrowsException()
231
+ .OfType<OrderNotFoundException>();
232
+ ```
233
+
234
+ ## Package References
235
+
236
+ ```bash
237
+ # xUnit (default)
238
+ dotnet add package xunit
239
+ dotnet add package xunit.runner.visualstudio
240
+ dotnet add package Microsoft.NET.Test.Sdk
241
+
242
+ # TUnit (for .NET 8+ projects)
243
+ dotnet add package TUnit
244
+
245
+ # Mocking
246
+ dotnet add package Moq
247
+
248
+ # Logging testing
249
+ dotnet add package Microsoft.Extensions.Logging.Testing
250
+ ```
251
+
252
+ ## Invocation Triggers
253
+
254
+ This skill should be invoked when the user:
255
+
256
+ - Creates a new service, handler, or class that needs tests
257
+ - Asks to add test coverage for existing code
258
+ - Mentions TDD or test-driven development
259
+ - Needs help with mocking, test setup, or assertions
260
+ - Wants to verify logging, exception handling, or validation behavior
261
+ - Asks about xUnit, TUnit, Moq, or NSubstitute patterns
262
+ - Wants to set up a new test project
263
+ - Needs to choose between testing frameworks
264
+ - Asks about FluentAssertions alternatives (due to licensing)
265
+
266
+ ## Constraints
267
+
268
+ - ALWAYS check for existing tests first and match the existing framework
269
+ - ALWAYS default to xUnit if no existing tests and user hasn't specified preference
270
+ - ALWAYS present test plan as method names ONLY before writing tests
271
+ - ALWAYS ask for explicit approval: "Do you approve this test plan?"
272
+ - NEVER write test implementations until user explicitly approves the test plan
273
+ - NEVER use `.Result` or `.Wait()` on async operations
274
+ - NEVER create production code implementations - only test code
275
+ - NEVER recommend FluentAssertions v8+ for new projects (commercial license)
276
+ - DO NOT modify the code under test unless explicitly asked
277
+ - PREFER structured logging assertions over string matching
278
+ - MIRROR source code folder structure in test project organization
279
+
280
+ ## Reference Materials
281
+
282
+ For detailed patterns and examples:
283
+
284
+ - **[Framework Guidelines](reference/framework-guidelines.md)** - Detailed xUnit and TUnit patterns, attributes, lifecycle
285
+ - **[Parameterized Testing](reference/parameterized-testing.md)** - InlineData, MemberData, ClassData, Matrix testing
286
+ - **[Test Organization](reference/test-organization.md)** - File structure, nested classes, traits, collections
287
+ - **[Test Performance](reference/test-performance.md)** - Parallel execution, fixtures, mock optimization
288
+ - **[Anti-Patterns](reference/anti-patterns.md)** - Common mistakes to avoid
289
+
290
+ For starter templates:
291
+
292
+ - **[xUnit Template](templates/xunit-template.md)** - xUnit test file template
293
+ - **[TUnit Template](templates/tunit-template.md)** - TUnit test file template