Skip to content

Commit 783cd2a

Browse files
committed
chore(claude): add project skills and generalize dev-conventions rules
Add five Claude Code skills distilled from recurring che-dashboard development workflows: - fix-cve-dep: upgrade a vulnerable npm dep, check ClearlyDefined, pin in resolutions, regenerate .deps files, commit and push - rebase-to-main: rebase a branch onto main, resolve .deps conflicts (take-theirs + regenerate), run license check, force-push - fix-pr-feedback: fetch and triage GitHub PR review comments, fix open items, commit and push - check-coverage: run coverage for changed packages, find uncovered code, write missing tests; enforces thresholds (common 99/100, frontend 92/88/85, backend 86/80/86) before PR is opened - pr-description: generate a PR description from branch context and save to openspec/docs/ following project template (check-coverage must pass first) Update CLAUDE.md to reference the new rules file and list all skills. Update AGENTS.md to reference .claude/rules/ and document all skills. Simplify .claude/rules/che-dashboard-dev.mdc (292 → 173 lines): - Remove §2 pre-push trailer cleanup (Cursor IDE defense) - Remove §7 building local images (human how-to, not an AI rule) - Remove §8 PR descriptions (superseded by pr-description skill) - Fix §3: split pre-commit (fast) vs pre-push (full suite) - Fix §4 dep format example to match actual .deps/prod.md format - Remove duplicate --updateSnapshot and tooltip CSS sub-section Remove personal identity data from all rules and skill files: - Signed-off-by uses {AUTHOR_NAME} <{AUTHOR_EMAIL}> placeholder - quay.io/oorel/ replaced with quay.io/{YOUR_QUAY_USERNAME}/ Assisted-by: Claude Sonnet 4.6 Signed-off-by: Oleksii Orel <oorel@redhat.com>
1 parent c5a69aa commit 783cd2a

12 files changed

Lines changed: 1466 additions & 8 deletions

File tree

.claude/CLAUDE.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@ See @../AGENTS.md for project guidelines.
44

55
See @../redhat-compliance-and-responsible-ai.md for Red Hat compliance and responsible AI rules.
66

7+
See @rules/che-dashboard-dev.mdc for development conventions — commits, CSS, deps, git patterns, accessibility.
8+
9+
## Available Skills
10+
11+
Project-specific skills live in `.claude/skills/`. Invoke with `/skill-name`:
12+
13+
| Skill | When to use |
14+
|---|---|
15+
| `commit-message` | Write a human-style commit message following project conventions |
16+
| `manage-resolutions` | Audit and clean up the `resolutions` field in `package.json` |
17+
| `fix-cve-dep` | Upgrade a vulnerable npm dependency (CVE/Jira ticket) |
18+
| `rebase-to-main` | Rebase a branch onto latest main, resolve `.deps/` conflicts, force-push |
19+
| `fix-pr-feedback` | Fetch PR review comments, triage fixed vs open, apply outstanding fixes |
20+
| `check-coverage` | Verify test coverage meets thresholds before opening a PR |
21+
| `pr-test-section` | Write the "Is it tested? How?" section of a PR description |
22+
| `pr-description` | Generate a PR description and save to `openspec/docs/` (run `check-coverage` first) |
23+
724
## Hard Rules
825

926
- **No `any` type**: NEVER use `any` or cast to `any` in TypeScript code. Use proper types, type guards, `unknown`, or specific interfaces instead.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
description: Unified development conventions for che-dashboard — commits, CI, CSS, deps, images, snapshots
3+
alwaysApply: true
4+
---
5+
6+
# che-dashboard Development Conventions
7+
8+
---
9+
10+
## 1. Commit Trailers
11+
12+
Only these trailers are permitted:
13+
14+
```
15+
Assisted-by: {AGENT_NAME}
16+
Signed-off-by: {AUTHOR_NAME} <{AUTHOR_EMAIL}>
17+
```
18+
19+
`{AGENT_NAME}` — specific agent name, e.g. `Claude Sonnet 4.6`.
20+
`{AUTHOR_NAME}` / `{AUTHOR_EMAIL}` — from `git config user.name` / `git config user.email`.
21+
22+
**Do NOT add:** `Made-with`, `Co-authored-by`, or duplicate trailers.
23+
**Do NOT add** AI explanation comments inside source code.
24+
**On amend:** always pass the full message with `-m "..."` so trailers are not stacked.
25+
26+
### Commit message format
27+
28+
- Subject line ≤ 50 chars, conventional commits: `type(scope): short description`
29+
- Common types: `fix`, `feat`, `chore`, `refactor`, `test`, `docs`
30+
31+
### Example
32+
33+
```
34+
fix(ui): prevent error message from overflowing the ErrorReporter widget
35+
36+
Assisted-by: Claude Sonnet 4.6
37+
Signed-off-by: Jane Developer <jane@example.com>
38+
```
39+
40+
---
41+
42+
## 2. Pre-commit Checks
43+
44+
**Before each commit** (fast — run every time):
45+
46+
```bash
47+
yarn lint:fix
48+
yarn format:fix
49+
yarn workspace @eclipse-che/dashboard-frontend test --testPathPatterns="ComponentName" --no-cache
50+
```
51+
52+
**Before pushing / opening a PR** (full suite):
53+
54+
```bash
55+
yarn build
56+
yarn test
57+
```
58+
59+
Follow the Surgical Change Workflow in `AGENTS.md` — targeted test runs before commit, full suite before push.
60+
61+
### Updating snapshots
62+
63+
When rendering changes break existing snapshots:
64+
65+
```bash
66+
yarn workspace @eclipse-che/dashboard-frontend test --testPathPatterns="ComponentName" --updateSnapshot
67+
```
68+
69+
Always verify the snapshot diff makes sense before committing.
70+
71+
---
72+
73+
## 3. Dependency Changes — License Regeneration
74+
75+
When `package.json` or `yarn.lock` changes:
76+
77+
```bash
78+
yarn license:generate
79+
```
80+
81+
If it exits with **"UNRESOLVED dependencies"**, add the missing package to `.deps/EXCLUDED/dev.md` (dev dep) or `.deps/EXCLUDED/prod.md` (runtime dep):
82+
83+
```markdown
84+
| `package-name@X.Y.Z` | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/package-name/X.Y.Z) |
85+
```
86+
87+
Then re-run `yarn license:generate`. Remove entries for packages no longer in `yarn.lock`.
88+
89+
---
90+
91+
## 4. CSS Property Ordering
92+
93+
This project uses `stylelint-config-clean-order`. Follow these group conventions:
94+
95+
| Group | Properties |
96+
|-------|-----------|
97+
| Layout | `position`, `z-index`, `overflow`, `overflow-x`, `overflow-y`, `display`, `flex-*`, `grid-*` |
98+
| Box/Size | `box-sizing`, `width`, `min-width`, `max-width`, `height`, `margin`, `padding` |
99+
| Typography | `font-*`, `color`, `text-*`, `word-break`, `white-space`, `line-height` |
100+
| Visual | `background`, `background-color`, `border*`, `border-radius`, `box-shadow` |
101+
| Animation | `transition`, `animation` |
102+
103+
- Empty lines **between groups** when rule has ≥ 5 properties
104+
- **No empty lines within a group**
105+
106+
---
107+
108+
## 5. Error Handling
109+
110+
Use typed error classes with status codes instead of string matching:
111+
112+
```typescript
113+
export class GitClientError extends Error {
114+
constructor(public readonly statusCode: number, message: string) {
115+
super(message);
116+
this.name = 'GitClientError';
117+
}
118+
}
119+
120+
// In route handler:
121+
const statusCode = e instanceof GitClientError ? e.statusCode : 500;
122+
reply.status(statusCode).send(helpers.errors.getMessage(e));
123+
```
124+
125+
---
126+
127+
## 6. Git Workflow Patterns
128+
129+
### Squash all branch commits into one
130+
131+
```bash
132+
git reset $(git merge-base origin/main HEAD)
133+
git add -A
134+
git commit -m "feat: ..."
135+
```
136+
137+
### Strip forbidden trailers from a range
138+
139+
```bash
140+
# upstream exists:
141+
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --msg-filter \
142+
'sed "/^Made-with:/d; /^Co-authored-by:/d"' \
143+
-- origin/BRANCH..HEAD
144+
145+
# no upstream yet:
146+
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --msg-filter \
147+
'sed "/^Made-with:/d; /^Co-authored-by:/d"' \
148+
-- HEAD~1..HEAD
149+
150+
git update-ref -d refs/original/refs/heads/$(git branch --show-current)
151+
```
152+
153+
Note: `--msg-filter` only rewrites commit messages — no stash needed.
154+
155+
### Resolve .deps merge conflicts
156+
157+
```bash
158+
git checkout --theirs .deps/EXCLUDED/dev.md .deps/EXCLUDED/prod.md
159+
git add .deps/EXCLUDED/dev.md .deps/EXCLUDED/prod.md
160+
```
161+
162+
Then re-run `yarn license:generate` after the rebase continues.
163+
164+
---
165+
166+
## 7. Accessibility and UI Conventions
167+
168+
- Icon hover color: `var(--pf-t--global--icon--color--subtle)` default, `var(--pf-t--global--text--color--link--default)` on hover
169+
- Tooltip `<a>` link colors: inverse background — use dark tokens in light theme, light tokens in dark theme (see the tooltip CSS module)
170+
- Keyboard toggle for `Switch`: wrap in `<div onKeyDown>` and handle `Enter`
171+
- Keyboard selection in `Select`/`SelectOption` with `hasCheckbox`: add explicit `onKeyDown` on each `SelectOption`
172+
- `ErrorReporter` overlay: `position: fixed; inset: 0; z-index: 9999`
173+
- Error `<pre>` blocks: `max-width: 100%; overflow-x: auto`
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
name: check-coverage
3+
description: Use when about to create a PR description, after adding new code, or when a PR received coverage-related review feedback. Checks that test coverage meets project thresholds and identifies uncovered code before the PR is opened.
4+
---
5+
6+
# Check Test Coverage
7+
8+
Verify that all changed or added code has sufficient test coverage before opening a PR. This prevents coverage-drop failures in CI and reviewer feedback about untested code.
9+
10+
## Coverage thresholds (enforced by CI)
11+
12+
| Package | Statements | Branches | Functions | Lines |
13+
|---|---|---|---|---|
14+
| `common` | 99% | 99% | **100%** | 99% |
15+
| `dashboard-frontend` | 92% | 88% | 85% | 92% |
16+
| `dashboard-backend` | 86% | 80% | 86% | 86% |
17+
18+
## Workflow
19+
20+
### 1. Identify changed packages
21+
22+
```bash
23+
git diff origin/main..HEAD --name-only | grep "^packages/" | cut -d/ -f2 | sort -u
24+
```
25+
26+
Only run coverage for packages with changed files — running all three is slow.
27+
28+
### 2. Run coverage for each changed package
29+
30+
```bash
31+
yarn workspace @eclipse-che/common test --coverage --no-cache
32+
yarn workspace @eclipse-che/dashboard-frontend test --coverage --no-cache
33+
yarn workspace @eclipse-che/dashboard-backend test --coverage --no-cache
34+
```
35+
36+
Look for the `Coverage summary` block at the end:
37+
38+
```
39+
Statements : 91.5% ( 1001/1094 ) ← must be ≥ threshold
40+
Branches : 87.2% ( 106/122 )
41+
Functions : 84.6% ( 22/26 )
42+
Lines : 91.5% ( 1001/1094 )
43+
Jest: "global" coverage threshold for statements (92%) not met: 91.5%
44+
```
45+
46+
If all lines end with the threshold met — **go to step 5**.
47+
48+
### 3. Find what is uncovered
49+
50+
Run with text reporter to see which files are below threshold:
51+
52+
```bash
53+
yarn workspace @eclipse-che/<package> test --coverage --no-cache \
54+
--coverageReporters=text 2>&1 | grep -v "^$" | grep "| " | \
55+
awk -F'|' '{if ($3+0 < 90 || $4+0 < 85 || $5+0 < 85) print}' | head -20
56+
```
57+
58+
Or check the specific files from the diff:
59+
60+
```bash
61+
# Get changed source files (not tests)
62+
CHANGED=$(git diff origin/main..HEAD --name-only | grep "^packages/<pkg>/src" | grep -v "__tests__\|spec\|mock")
63+
echo "$CHANGED"
64+
```
65+
66+
For each changed file, check if there is a corresponding test file:
67+
68+
```bash
69+
# For a file at src/services/myService.ts, expect:
70+
# src/services/__tests__/myService.spec.ts
71+
```
72+
73+
### 4. Write missing tests
74+
75+
For each uncovered file or function:
76+
77+
1. Read the source file to understand what it does.
78+
2. Create or update the corresponding `__tests__/<name>.spec.ts`.
79+
3. Cover:
80+
- **Happy path** — the function works with valid input
81+
- **Error path** — thrown errors, rejected promises, invalid input
82+
- **Edge cases** — empty arrays, undefined props, boundary values
83+
- **Each branch** — both sides of every `if`/ternary/`||`
84+
85+
Run with `--testPathPatterns` to iterate quickly:
86+
87+
```bash
88+
yarn workspace @eclipse-che/<package> test \
89+
--testPathPatterns "<FileName>" --coverage --no-cache
90+
```
91+
92+
### 5. Verify all thresholds pass
93+
94+
```bash
95+
yarn workspace @eclipse-che/<package> test --coverage --no-cache 2>&1 | tail -10
96+
```
97+
98+
Must see:
99+
```
100+
All coverage thresholds met.
101+
```
102+
or no `"coverage threshold … not met"` lines.
103+
104+
**Do not proceed to PR description until every changed package passes.**
105+
106+
### 6. Proceed to PR description
107+
108+
Once coverage passes, invoke the `pr-description` skill.
109+
110+
## Common patterns for untested code
111+
112+
### New utility function
113+
```typescript
114+
// Always test: return value, thrown error, edge input
115+
it('returns X for valid input', () => { ... });
116+
it('throws for invalid input', () => { ... });
117+
it('handles empty array', () => { ... });
118+
```
119+
120+
### New React component
121+
```typescript
122+
// Always test: renders without error, key props change output, user interaction
123+
it('renders without crashing', () => { renderComponent(); });
124+
it('shows error state when prop is true', () => { ... });
125+
it('calls callback on button click', () => { ... });
126+
```
127+
128+
### New async action / Redux thunk
129+
```typescript
130+
// Always test: success dispatch, error dispatch, API call arguments
131+
it('dispatches success on 200', async () => { ... });
132+
it('dispatches error on network failure', async () => { ... });
133+
```
134+
135+
### New API route (backend)
136+
```typescript
137+
// Always test: 200 response shape, 4xx error cases, auth guard
138+
it('returns 200 with correct body', async () => { ... });
139+
it('returns 403 when not authorized', async () => { ... });
140+
```
141+
142+
## What NOT to test (already excluded from coverage)
143+
144+
- `src/**/__tests__/**` — test files themselves
145+
- `src/**/*.d.ts` — type declaration files
146+
- `src/**/*.config.ts` — config files
147+
- `src/index.tsx`, `src/App.tsx`, `src/Routes.tsx` — entry points (frontend)
148+
- `src/localRun/**`, `src/utils/**`, `src/server.ts` — backend exclusions
149+
150+
## Snapshot tests do NOT count
151+
152+
Updated snapshots (`--updateSnapshot`) do not improve branch/function coverage. Always add behavioral tests alongside snapshot updates when coverage is at risk.

0 commit comments

Comments
 (0)