Skip to content

Commit d3635e1

Browse files
authored
Add Claude AI skills for project conventions and development standards (#1931)
## Description Added Claude AI skills configuration to establish coding standards and best practices for the project. These skills provide comprehensive guidelines for React development, TypeScript usage, E2E testing with Playwright, UI primitives, code review processes, and project conventions. ## Related Issue and Pull requests <!-- Link to any related issues using the format #<issue-number> --> ## Type of Change - [ ] Bug fix - [ ] New feature - [ ] Improvement - [ ] Cleanup/Refactor - [ ] Breaking change - [x] Documentation update ## Checklist - [x] I have tested this does not break current pipelines / runs functionality - [x] I have tested the changes on staging ## Screenshots (if applicable) <!-- Include any screenshots that might help explain the changes or provide visual context --> ## Test Instructions 1. Verify the Claude skills are properly structured in `.claude/skills/` directory 2. Check that each skill file contains valid YAML frontmatter and markdown content 3. Confirm the skills cover the main areas: e2e-testing, project-conventions, react-patterns, review, typescript-standards, ui-primitives, and validate ## Additional Comments These skills will help maintain consistent code quality and development practices across the project. The configuration includes specific guidance for: - Playwright E2E testing patterns and anti-patterns - React Compiler compatibility rules - TypeScript safety standards - UI primitive usage over raw HTML - Code review processes and validation commands - Project-specific conventions for imports, file structure, and error handling
1 parent 9868241 commit d3635e1

16 files changed

Lines changed: 1788 additions & 0 deletions

File tree

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
name: accessibility
3+
description: Accessibility patterns and requirements for this project. Use when creating interactive components, forms, dialogs, or any user-facing UI.
4+
---
5+
6+
# Accessibility Patterns
7+
8+
This project builds on **shadcn/ui** primitives which provide strong built-in a11y. Follow these patterns to maintain that standard.
9+
10+
## ARIA Labels
11+
12+
All interactive elements without visible text must have an `aria-label`:
13+
14+
```typescript
15+
// Icon buttons
16+
<Button variant="ghost" aria-label="Home">
17+
<Icon name="Home" />
18+
</Button>
19+
20+
// Folder toggles
21+
<div role="button" aria-expanded={isOpen} aria-label={`Folder: ${folder.name}`}>
22+
```
23+
24+
## Form Accessibility
25+
26+
Link inputs to labels and error messages:
27+
28+
```typescript
29+
<Input
30+
id={id}
31+
aria-invalid={!!error}
32+
aria-describedby={`${id}-hint`}
33+
/>
34+
{!!error && <Text tone="critical">{error.join("\n")}</Text>}
35+
<div id={`${id}-hint`}>{hint}</div>
36+
```
37+
38+
Use the shadcn/ui `Label` component for proper form associations.
39+
40+
## Keyboard Navigation
41+
42+
### Required keyboard support for custom interactive elements:
43+
44+
- **Enter/Space**: Activate buttons and toggles
45+
- **Escape**: Close dialogs, cancel editing, deselect
46+
- **Tab**: Move focus between interactive elements
47+
48+
```typescript
49+
// The Input component has built-in onEnter and onEscape props
50+
<Input onEnter={save} onEscape={cancel} />
51+
52+
// For non-Input elements, handle manually
53+
onKeyDown={(e) => {
54+
if (e.key === "Enter" && !e.shiftKey) {
55+
e.preventDefault();
56+
save();
57+
} else if (e.key === "Escape") {
58+
e.preventDefault();
59+
cancel();
60+
}
61+
}
62+
```
63+
64+
### Non-button clickable elements need `role="button"` and `tabIndex={0}`:
65+
66+
```typescript
67+
<div role="button" tabIndex={0} title="Click to edit">
68+
{content}
69+
</div>
70+
```
71+
72+
### Dialogs must prevent keyboard shortcuts from leaking to the canvas:
73+
74+
The dialog component already handles this — use `preventKeyboardPropagation` prop when needed. This stops Ctrl+A, Ctrl+C, Ctrl+V, Tab, Enter, and Escape from reaching React Flow.
75+
76+
## Screen Reader Support
77+
78+
Use `sr-only` class for visually hidden but screen-reader-accessible text:
79+
80+
```typescript
81+
// Close buttons with only an icon
82+
<DialogClose>
83+
<Cross2Icon />
84+
<span className="sr-only">Close</span>
85+
</DialogClose>
86+
87+
// Command palette title
88+
<DialogHeader className="sr-only">
89+
<DialogTitle>{title}</DialogTitle>
90+
<DialogDescription>{description}</DialogDescription>
91+
</DialogHeader>
92+
```
93+
94+
## Semantic HTML
95+
96+
Use proper semantic elements and ARIA roles:
97+
98+
```typescript
99+
// Navigation
100+
<nav aria-label="breadcrumb">
101+
102+
// Current page in breadcrumb
103+
<span role="link" aria-disabled="true" aria-current="page">{children}</span>
104+
105+
// Decorative separators
106+
<li role="presentation" aria-hidden="true">
107+
108+
// Alerts
109+
<div role="alert">
110+
```
111+
112+
## Focus Styling
113+
114+
All focusable elements must use the project's focus-visible ring pattern:
115+
116+
```
117+
focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:border-ring
118+
```
119+
120+
Do not remove `outline-none` without replacing it with a visible focus indicator.
121+
122+
## UI Primitives A11y
123+
124+
The project's primitives already accept `AriaAttributes`:
125+
126+
- `BlockStack` and `InlineStack` accept all ARIA props
127+
- `Text` accepts `role` and ARIA props
128+
- `Button` has built-in focus-visible and disabled states
129+
- `Input` supports `aria-invalid`, `onEnter`, `onEscape`
130+
- All shadcn/ui components (Dialog, Select, Checkbox, Switch, Tabs) handle focus trapping and keyboard navigation automatically
131+
132+
## React Flow Considerations
133+
134+
The pipeline editor has specific a11y needs:
135+
136+
- **Handles**: Support click selection and Escape to deselect
137+
- **Task nodes**: Labels are interactive with visual feedback
138+
- **Folders in sidebar**: Use `role="button"` with `aria-expanded`
139+
- **Canvas keyboard shortcuts**: Must not interfere with dialog/modal focus
140+
141+
When adding new interactive elements to the flow canvas, ensure they:
142+
143+
1. Are keyboard accessible
144+
2. Have appropriate ARIA labels
145+
3. Don't capture keyboard events that should reach parent containers
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
name: address-pr-comments
3+
description: Find the PR for the current branch, read review comments, and address them — either by fixing the code or pushing back with a reply. Use when the user wants to handle PR feedback.
4+
disable-model-invocation: true
5+
allowed-tools: Bash(gh *), Bash(git *), Bash(gt *), Read, Edit, Write, Grep, Glob, Agent
6+
---
7+
8+
# Address PR Comments
9+
10+
Check the current branch for an open PR, read all unresolved review comments, and let the user pick which ones to address.
11+
12+
## Step 1: Find the PR
13+
14+
```bash
15+
gh pr view --json number,title,url,state --jq '{number, title, url, state}'
16+
```
17+
18+
If no PR exists for the current branch, tell the user and stop.
19+
20+
Also determine the current GitHub user:
21+
22+
```bash
23+
gh api user --jq '.login'
24+
```
25+
26+
## Step 2: Fetch review comments
27+
28+
Get all review comments (not general PR comments):
29+
30+
```bash
31+
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments --paginate --jq '.[] | {id, path, line, body, user: .user.login, created_at, in_reply_to_id, diff_hunk}'
32+
```
33+
34+
## Step 3: Filter to actionable comments
35+
36+
Build a thread map by grouping comments using `in_reply_to_id`. For each top-level comment thread:
37+
38+
**Skip the thread if ANY of these are true:**
39+
40+
- The thread is already resolved
41+
- The top-level comment was made by the current user
42+
- The top-level comment was made by a bot (dependabot, github-actions, etc.)
43+
- The comment is a pure approval with no actionable feedback
44+
- **The current user (or PR author) has already replied** in the thread — this means it was already addressed in a previous run or manually. Check if any reply in the thread was authored by the current GitHub user.
45+
46+
This ensures running the command again won't double-reply to already-addressed comments.
47+
48+
## Step 4: Analyze comments and present for selection
49+
50+
Before presenting comments to the user, **read the relevant code and think critically about each comment**. Determine whether the suggestion is correct, already addressed, or a bad idea. Form a proposed action for each.
51+
52+
Use the AskUserQuestion tool to show a **multi-select list** of all remaining unresolved, unaddressed comments. Each option should show:
53+
54+
- The reviewer's username
55+
- The file path and line number
56+
- A truncated preview of the comment (first ~80 characters)
57+
- **Your proposed action** — what you plan to do (e.g., "Will fix: change X to Y", "Will push back: current approach is better because...", "Will answer: explain how X works")
58+
59+
Example options:
60+
61+
- `[reviewer] file.ts:42 — "Fix this typo..." → Will fix: rename varName to variableName`
62+
- `[reviewer] other.ts:10 — "This should use..." → Will push back: current pattern is more performant here`
63+
- `[reviewer] types.ts:5 — "Why not use...?" → Will answer: explain the tradeoff`
64+
65+
The user picks which comments they want to address. Only proceed with the selected ones.
66+
67+
If there are no actionable comments, tell the user everything has been addressed and stop.
68+
69+
## Step 5: Address each selected comment
70+
71+
**Do not blindly agree with every comment.** Critically evaluate each suggestion against the codebase, existing patterns, and correctness. If a suggestion would make the code worse, introduce inconsistency, or is factually wrong — push back respectfully. The reviewer is a collaborator, not an authority to obey unconditionally.
72+
73+
For each selected comment, read the relevant file and surrounding context, then decide:
74+
75+
### If the suggestion is correct and actionable:
76+
77+
1. Make the code change
78+
2. Reply to the comment confirming the fix:
79+
80+
```markdown
81+
Fixed — <brief description of what was changed>.
82+
```
83+
84+
### If the suggestion is already addressed:
85+
86+
Reply explaining that it's already handled:
87+
88+
```markdown
89+
This is already handled — <explanation with file path/line reference>.
90+
```
91+
92+
### If the suggestion is incorrect or not applicable:
93+
94+
Reply respectfully pushing back:
95+
96+
```markdown
97+
I think the current approach is better here because <reasoning>. <Optional: offer an alternative compromise>.
98+
```
99+
100+
### If the comment is a question (not a change request):
101+
102+
Reply with the answer:
103+
104+
```markdown
105+
<Answer the question with relevant context/file references>.
106+
```
107+
108+
## Step 6: Post replies
109+
110+
For each comment, post the reply:
111+
112+
```bash
113+
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies -f body="<reply>"
114+
```
115+
116+
## Step 7: Stage and commit fixes
117+
118+
If any code changes were made:
119+
120+
1. Stage only the files that were modified to address comments
121+
2. Create a commit with a message like: `address pr feedback`
122+
3. Do NOT push — tell the user the changes are committed and ready to push
123+
124+
## Step 8: Show summary
125+
126+
After all comments are addressed, show a summary table with columns:
127+
128+
| # | File | Comment | Action |
129+
| --- | ---- | ------- | ------ |
130+
131+
Where **Action** clearly states what was done: "Fixed — ...", "Pushed back — ...", "Answered — ...", or "Already handled — ...".
132+
133+
## Important
134+
135+
- Always read the full file context before deciding how to address a comment
136+
- **Think critically** — do not default to agreeing. Push back when the suggestion is wrong, harmful, or inconsistent with the codebase
137+
- Never dismiss feedback rudely — be respectful even when pushing back
138+
- If a comment requires a large refactor or is out of scope, say so and suggest a follow-up issue
139+
- Group related comments that touch the same code — address them together
140+
- If unsure about a comment's intent, ask the user before responding
141+
- Show the user what you plan to reply before posting, so they can adjust

0 commit comments

Comments
 (0)