@codihaus/claude-skills 1.6.28 → 1.7.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/package.json +1 -1
- package/skills/_registry.md +7 -9
- package/skills/debrief/SKILL.md +14 -5
- package/skills/debrief/references/workflow.md +8 -2
- package/skills/dev-arch/SKILL.md +10 -183
- package/skills/dev-arch/references/decision-categories.md +73 -0
- package/skills/dev-arch/references/examples.md +125 -0
- package/skills/dev-changelog/SKILL.md +43 -20
- package/skills/dev-coding/SKILL.md +16 -3
- package/skills/dev-review/SKILL.md +46 -237
- package/skills/dev-review/references/review-examples.md +160 -0
- package/skills/dev-review/references/stack-checks.md +45 -0
- package/skills/dev-scout/SKILL.md +2 -2
- package/skills/dev-specs/SKILL.md +2 -16
- package/skills/dev-test/SKILL.md +6 -127
- package/skills/dev-test/references/test-patterns.md +119 -0
- package/src/commands/init.js +113 -3
- package/src/commands/update.js +15 -1
package/skills/dev-test/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dev-test
|
|
3
|
-
description: Automated testing
|
|
4
|
-
version: 1.
|
|
3
|
+
description: Automated UI testing using Playwright browser tools. Use when: (1) After completing feature implementation, (2) After fixing bugs, (3) Before code review, (4) Verifying acceptance criteria from specs
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# /dev-test - Implementation Testing
|
|
@@ -113,134 +113,13 @@ Test report showing whether implementation works correctly.
|
|
|
113
113
|
|
|
114
114
|
## Test Patterns
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
- Form submission
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
- Error state testing
|
|
116
|
+
See `references/test-patterns.md` for code examples:
|
|
117
|
+
- Form submission, navigation flow, API response validation, error state testing
|
|
118
|
+
- Test data conventions
|
|
119
|
+
- Common issues and solutions (page not loading, element not found, intermittent failures)
|
|
121
120
|
|
|
122
121
|
Use Playwright MCP tools to interact with browser.
|
|
123
122
|
|
|
124
|
-
## Test Patterns
|
|
125
|
-
|
|
126
|
-
### Form Submission
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
// 1. Fill form
|
|
130
|
-
await browser_fill_form({
|
|
131
|
-
fields: [
|
|
132
|
-
{ name: 'Email', type: 'textbox', ref: 'input-email', value: 'test@test.com' },
|
|
133
|
-
{ name: 'Password', type: 'textbox', ref: 'input-password', value: 'password123' }
|
|
134
|
-
]
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// 2. Submit and wait
|
|
138
|
-
await browser_click({ element: 'Submit button', ref: 'btn-submit' });
|
|
139
|
-
await browser_wait_for({ text: 'Success' });
|
|
140
|
-
|
|
141
|
-
// 3. Check for errors
|
|
142
|
-
const errors = await browser_console_messages({ level: 'error' });
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Navigation Flow
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// 1. Start at page A
|
|
149
|
-
await browser_navigate({ url: '/dashboard' });
|
|
150
|
-
|
|
151
|
-
// 2. Click to page B
|
|
152
|
-
await browser_click({ element: 'Settings link', ref: 'nav-settings' });
|
|
153
|
-
await browser_wait_for({ text: 'Settings' });
|
|
154
|
-
|
|
155
|
-
// 3. Verify correct page
|
|
156
|
-
const snapshot = await browser_snapshot({});
|
|
157
|
-
// Check snapshot contains expected elements
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### API Response Validation
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
// 1. Trigger API call (via form submit or button)
|
|
164
|
-
await browser_click({ element: 'Load data', ref: 'btn-load' });
|
|
165
|
-
await browser_wait_for({ time: 2 });
|
|
166
|
-
|
|
167
|
-
// 2. Check network requests
|
|
168
|
-
const requests = await browser_network_requests({});
|
|
169
|
-
|
|
170
|
-
// 3. Find the API call
|
|
171
|
-
const apiCall = requests.find(r => r.url.includes('/api/data'));
|
|
172
|
-
|
|
173
|
-
// 4. Validate
|
|
174
|
-
if (apiCall.status >= 400) {
|
|
175
|
-
// Report error
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Error State Testing
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
// Test error handling by submitting invalid data
|
|
183
|
-
await browser_type({
|
|
184
|
-
element: 'email',
|
|
185
|
-
ref: 'input-email',
|
|
186
|
-
text: 'invalid-email' // No @ symbol
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
await browser_click({ element: 'Submit', ref: 'btn-submit' });
|
|
190
|
-
|
|
191
|
-
// Verify error message appears
|
|
192
|
-
const snapshot = await browser_snapshot({});
|
|
193
|
-
// Check for validation error in snapshot
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
## Test Data
|
|
197
|
-
|
|
198
|
-
Use predictable test data:
|
|
199
|
-
|
|
200
|
-
```typescript
|
|
201
|
-
const TEST_DATA = {
|
|
202
|
-
validEmail: 'test@example.com',
|
|
203
|
-
validPassword: 'Test123!@#',
|
|
204
|
-
invalidEmail: 'not-an-email',
|
|
205
|
-
shortPassword: '123',
|
|
206
|
-
};
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
For existing data, check spec or use API to fetch valid IDs.
|
|
210
|
-
|
|
211
|
-
## Common Issues & Solutions
|
|
212
|
-
|
|
213
|
-
### Issue: Page Not Loading
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
Symptom: Navigation fails or times out
|
|
217
|
-
Check:
|
|
218
|
-
1. Is dev server running? (npm run dev)
|
|
219
|
-
2. Correct port? (3000, 3001, etc.)
|
|
220
|
-
3. Any build errors?
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Issue: Element Not Found
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
Symptom: Click/type fails with "element not found"
|
|
227
|
-
Check:
|
|
228
|
-
1. Take snapshot to see current state
|
|
229
|
-
2. Is element conditionally rendered?
|
|
230
|
-
3. Has ref changed since snapshot?
|
|
231
|
-
4. Is page still loading?
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
### Issue: Intermittent Failures
|
|
235
|
-
|
|
236
|
-
```
|
|
237
|
-
Symptom: Test passes sometimes, fails sometimes
|
|
238
|
-
Check:
|
|
239
|
-
1. Add wait_for before interactions
|
|
240
|
-
2. Check for race conditions
|
|
241
|
-
3. Increase timeout for slow APIs
|
|
242
|
-
```
|
|
243
|
-
|
|
244
123
|
## Integration with /dev-coding
|
|
245
124
|
|
|
246
125
|
When `/dev-coding` completes:
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Test Patterns & Common Issues
|
|
2
|
+
|
|
3
|
+
## Form Submission
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// 1. Fill form
|
|
7
|
+
await browser_fill_form({
|
|
8
|
+
fields: [
|
|
9
|
+
{ name: 'Email', type: 'textbox', ref: 'input-email', value: 'test@test.com' },
|
|
10
|
+
{ name: 'Password', type: 'textbox', ref: 'input-password', value: 'password123' }
|
|
11
|
+
]
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// 2. Submit and wait
|
|
15
|
+
await browser_click({ element: 'Submit button', ref: 'btn-submit' });
|
|
16
|
+
await browser_wait_for({ text: 'Success' });
|
|
17
|
+
|
|
18
|
+
// 3. Check for errors
|
|
19
|
+
const errors = await browser_console_messages({ level: 'error' });
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Navigation Flow
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// 1. Start at page A
|
|
26
|
+
await browser_navigate({ url: '/dashboard' });
|
|
27
|
+
|
|
28
|
+
// 2. Click to page B
|
|
29
|
+
await browser_click({ element: 'Settings link', ref: 'nav-settings' });
|
|
30
|
+
await browser_wait_for({ text: 'Settings' });
|
|
31
|
+
|
|
32
|
+
// 3. Verify correct page
|
|
33
|
+
const snapshot = await browser_snapshot({});
|
|
34
|
+
// Check snapshot contains expected elements
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API Response Validation
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// 1. Trigger API call (via form submit or button)
|
|
41
|
+
await browser_click({ element: 'Load data', ref: 'btn-load' });
|
|
42
|
+
await browser_wait_for({ time: 2 });
|
|
43
|
+
|
|
44
|
+
// 2. Check network requests
|
|
45
|
+
const requests = await browser_network_requests({});
|
|
46
|
+
|
|
47
|
+
// 3. Find the API call
|
|
48
|
+
const apiCall = requests.find(r => r.url.includes('/api/data'));
|
|
49
|
+
|
|
50
|
+
// 4. Validate
|
|
51
|
+
if (apiCall.status >= 400) {
|
|
52
|
+
// Report error
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Error State Testing
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Test error handling by submitting invalid data
|
|
60
|
+
await browser_type({
|
|
61
|
+
element: 'email',
|
|
62
|
+
ref: 'input-email',
|
|
63
|
+
text: 'invalid-email' // No @ symbol
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await browser_click({ element: 'Submit', ref: 'btn-submit' });
|
|
67
|
+
|
|
68
|
+
// Verify error message appears
|
|
69
|
+
const snapshot = await browser_snapshot({});
|
|
70
|
+
// Check for validation error in snapshot
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Test Data
|
|
74
|
+
|
|
75
|
+
Use predictable test data:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const TEST_DATA = {
|
|
79
|
+
validEmail: 'test@example.com',
|
|
80
|
+
validPassword: 'Test123!@#',
|
|
81
|
+
invalidEmail: 'not-an-email',
|
|
82
|
+
shortPassword: '123',
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For existing data, check spec or use API to fetch valid IDs.
|
|
87
|
+
|
|
88
|
+
## Common Issues & Solutions
|
|
89
|
+
|
|
90
|
+
### Page Not Loading
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Symptom: Navigation fails or times out
|
|
94
|
+
Check:
|
|
95
|
+
1. Is dev server running? (npm run dev)
|
|
96
|
+
2. Correct port? (3000, 3001, etc.)
|
|
97
|
+
3. Any build errors?
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Element Not Found
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
Symptom: Click/type fails with "element not found"
|
|
104
|
+
Check:
|
|
105
|
+
1. Take snapshot to see current state
|
|
106
|
+
2. Is element conditionally rendered?
|
|
107
|
+
3. Has ref changed since snapshot?
|
|
108
|
+
4. Is page still loading?
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Intermittent Failures
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
Symptom: Test passes sometimes, fails sometimes
|
|
115
|
+
Check:
|
|
116
|
+
1. Add wait_for before interactions
|
|
117
|
+
2. Check for race conditions
|
|
118
|
+
3. Increase timeout for slow APIs
|
|
119
|
+
```
|
package/src/commands/init.js
CHANGED
|
@@ -9,6 +9,7 @@ import ora from 'ora';
|
|
|
9
9
|
import inquirer from 'inquirer';
|
|
10
10
|
import path from 'path';
|
|
11
11
|
import fs from 'fs-extra';
|
|
12
|
+
import { execSync } from 'child_process';
|
|
12
13
|
|
|
13
14
|
import {
|
|
14
15
|
checkGlobalDeps,
|
|
@@ -24,7 +25,9 @@ import {
|
|
|
24
25
|
getInstalledSkills,
|
|
25
26
|
copySkillsToProject,
|
|
26
27
|
copyKnowledgeToProject,
|
|
27
|
-
copyScriptsToProject
|
|
28
|
+
copyScriptsToProject,
|
|
29
|
+
checkForUpdates,
|
|
30
|
+
cleanupOldSkills
|
|
28
31
|
} from '../utils/skills.js';
|
|
29
32
|
import {
|
|
30
33
|
setupSettings,
|
|
@@ -124,8 +127,88 @@ export async function init(options) {
|
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
if (action === 'update') {
|
|
127
|
-
|
|
128
|
-
|
|
130
|
+
console.log('');
|
|
131
|
+
|
|
132
|
+
// Check for CLI package updates first
|
|
133
|
+
const packageSpinner = ora('Checking npm for latest CLI version...').start();
|
|
134
|
+
try {
|
|
135
|
+
const currentVersion = await getCurrentPackageVersion();
|
|
136
|
+
const latestVersion = await getLatestNpmVersion();
|
|
137
|
+
|
|
138
|
+
if (currentVersion !== latestVersion) {
|
|
139
|
+
packageSpinner.info(`CLI update available: ${currentVersion} → ${latestVersion}`);
|
|
140
|
+
|
|
141
|
+
// Auto-update the CLI package
|
|
142
|
+
const updateSpinner = ora('Updating CLI package...').start();
|
|
143
|
+
try {
|
|
144
|
+
execSync('npm install -g @codihaus/claude-skills@latest', {
|
|
145
|
+
encoding: 'utf8',
|
|
146
|
+
stdio: 'pipe'
|
|
147
|
+
});
|
|
148
|
+
updateSpinner.succeed(`CLI package updated to ${latestVersion}`);
|
|
149
|
+
console.log(chalk.green(`\n✅ Please re-run init to update skills with the new CLI version.\n`));
|
|
150
|
+
process.exit(0);
|
|
151
|
+
} catch (updateErr) {
|
|
152
|
+
updateSpinner.fail('Failed to update CLI package');
|
|
153
|
+
console.log(chalk.yellow(`\nTo update manually, run:\n npm install -g @codihaus/claude-skills@latest\n`));
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
packageSpinner.succeed(`CLI package is up to date (${currentVersion})`);
|
|
157
|
+
}
|
|
158
|
+
} catch (e) {
|
|
159
|
+
packageSpinner.warn('Could not check for CLI updates');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log('');
|
|
163
|
+
|
|
164
|
+
// Check for skill updates
|
|
165
|
+
const skillSpinner = ora('Checking for skill updates...').start();
|
|
166
|
+
const updates = await checkForUpdates(projectPath);
|
|
167
|
+
skillSpinner.stop();
|
|
168
|
+
|
|
169
|
+
if (updates.length === 0) {
|
|
170
|
+
console.log(chalk.green('✅ All skills are up to date!\n'));
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
console.log(chalk.cyan(`Found ${updates.length} skill update(s) available:\n`));
|
|
175
|
+
|
|
176
|
+
for (const update of updates) {
|
|
177
|
+
console.log(` ${update.name}`);
|
|
178
|
+
console.log(chalk.gray(` ${update.current} → ${update.available}`));
|
|
179
|
+
console.log('');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Apply skill updates
|
|
183
|
+
const updateSkillsSpinner = ora('Updating skills...').start();
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const skillNames = updates.map(u => u.name);
|
|
187
|
+
|
|
188
|
+
// Clean up old files first
|
|
189
|
+
updateSkillsSpinner.text = 'Cleaning up old skill files...';
|
|
190
|
+
await cleanupOldSkills(projectPath, skillNames);
|
|
191
|
+
|
|
192
|
+
// Copy new versions
|
|
193
|
+
updateSkillsSpinner.text = 'Installing updated skills...';
|
|
194
|
+
const { copied, errors } = await copySkillsToProject(projectPath, skillNames);
|
|
195
|
+
|
|
196
|
+
if (errors.length > 0) {
|
|
197
|
+
updateSkillsSpinner.warn(`Updated ${copied.length} skills with ${errors.length} errors`);
|
|
198
|
+
for (const err of errors) {
|
|
199
|
+
console.log(chalk.red(` ✗ ${err.name}: ${err.error}`));
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
updateSkillsSpinner.succeed(`Updated ${copied.length} skills`);
|
|
203
|
+
}
|
|
204
|
+
} catch (e) {
|
|
205
|
+
updateSkillsSpinner.fail('Update failed');
|
|
206
|
+
console.error(chalk.red(e.message));
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
console.log(chalk.green('\n✅ Update complete!\n'));
|
|
211
|
+
process.exit(0);
|
|
129
212
|
}
|
|
130
213
|
}
|
|
131
214
|
|
|
@@ -409,3 +492,30 @@ export async function init(options) {
|
|
|
409
492
|
console.log('');
|
|
410
493
|
}
|
|
411
494
|
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Get current package version
|
|
498
|
+
*/
|
|
499
|
+
async function getCurrentPackageVersion() {
|
|
500
|
+
try {
|
|
501
|
+
const packageJson = await fs.readJson(path.join(import.meta.dirname, '../../package.json'));
|
|
502
|
+
return packageJson.version;
|
|
503
|
+
} catch (e) {
|
|
504
|
+
return 'unknown';
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Get latest version from npm
|
|
510
|
+
*/
|
|
511
|
+
async function getLatestNpmVersion() {
|
|
512
|
+
try {
|
|
513
|
+
const result = execSync('npm view @codihaus/claude-skills version', {
|
|
514
|
+
encoding: 'utf8',
|
|
515
|
+
stdio: ['pipe', 'pipe', 'ignore']
|
|
516
|
+
});
|
|
517
|
+
return result.trim();
|
|
518
|
+
} catch (e) {
|
|
519
|
+
throw new Error('Could not fetch latest version from npm');
|
|
520
|
+
}
|
|
521
|
+
}
|
package/src/commands/update.js
CHANGED
|
@@ -25,7 +25,21 @@ export async function update(options) {
|
|
|
25
25
|
|
|
26
26
|
if (currentVersion !== latestVersion) {
|
|
27
27
|
packageSpinner.info(`Package update available: ${currentVersion} → ${latestVersion}`);
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
// Auto-update the CLI package
|
|
30
|
+
const updateSpinner = ora('Updating CLI package...').start();
|
|
31
|
+
try {
|
|
32
|
+
execSync('npm install -g @codihaus/claude-skills@latest', {
|
|
33
|
+
encoding: 'utf8',
|
|
34
|
+
stdio: 'pipe'
|
|
35
|
+
});
|
|
36
|
+
updateSpinner.succeed(`CLI package updated to ${latestVersion}`);
|
|
37
|
+
console.log(chalk.green(`\n✅ Please re-run this command to update skills with the new CLI version.\n`));
|
|
38
|
+
process.exit(0);
|
|
39
|
+
} catch (updateErr) {
|
|
40
|
+
updateSpinner.fail('Failed to update CLI package');
|
|
41
|
+
console.log(chalk.yellow(`\nTo update manually, run:\n npm install -g @codihaus/claude-skills@latest\n`));
|
|
42
|
+
}
|
|
29
43
|
} else {
|
|
30
44
|
packageSpinner.succeed(`CLI package is up to date (${currentVersion})`);
|
|
31
45
|
}
|