forked from Cloud-Pipelines/pipeline-editor
-
Notifications
You must be signed in to change notification settings - Fork 5
Add Claude AI skills for project conventions and development standards #1931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| --- | ||
| name: accessibility | ||
| description: Accessibility patterns and requirements for this project. Use when creating interactive components, forms, dialogs, or any user-facing UI. | ||
| --- | ||
|
|
||
| # Accessibility Patterns | ||
|
|
||
| This project builds on **shadcn/ui** primitives which provide strong built-in a11y. Follow these patterns to maintain that standard. | ||
|
|
||
| ## ARIA Labels | ||
|
|
||
| All interactive elements without visible text must have an `aria-label`: | ||
|
|
||
| ```typescript | ||
| // Icon buttons | ||
| <Button variant="ghost" aria-label="Home"> | ||
| <Icon name="Home" /> | ||
| </Button> | ||
|
|
||
| // Folder toggles | ||
| <div role="button" aria-expanded={isOpen} aria-label={`Folder: ${folder.name}`}> | ||
| ``` | ||
|
|
||
| ## Form Accessibility | ||
|
|
||
| Link inputs to labels and error messages: | ||
|
|
||
| ```typescript | ||
| <Input | ||
| id={id} | ||
| aria-invalid={!!error} | ||
| aria-describedby={`${id}-hint`} | ||
| /> | ||
| {!!error && <Text tone="critical">{error.join("\n")}</Text>} | ||
| <div id={`${id}-hint`}>{hint}</div> | ||
| ``` | ||
|
|
||
| Use the shadcn/ui `Label` component for proper form associations. | ||
|
|
||
| ## Keyboard Navigation | ||
|
|
||
| ### Required keyboard support for custom interactive elements: | ||
|
|
||
| - **Enter/Space**: Activate buttons and toggles | ||
| - **Escape**: Close dialogs, cancel editing, deselect | ||
| - **Tab**: Move focus between interactive elements | ||
|
|
||
| ```typescript | ||
| // The Input component has built-in onEnter and onEscape props | ||
| <Input onEnter={save} onEscape={cancel} /> | ||
|
|
||
| // For non-Input elements, handle manually | ||
| onKeyDown={(e) => { | ||
| if (e.key === "Enter" && !e.shiftKey) { | ||
| e.preventDefault(); | ||
| save(); | ||
| } else if (e.key === "Escape") { | ||
| e.preventDefault(); | ||
| cancel(); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Non-button clickable elements need `role="button"` and `tabIndex={0}`: | ||
|
|
||
| ```typescript | ||
| <div role="button" tabIndex={0} title="Click to edit"> | ||
| {content} | ||
| </div> | ||
| ``` | ||
|
|
||
| ### Dialogs must prevent keyboard shortcuts from leaking to the canvas: | ||
|
|
||
| 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. | ||
|
|
||
| ## Screen Reader Support | ||
|
|
||
| Use `sr-only` class for visually hidden but screen-reader-accessible text: | ||
|
|
||
| ```typescript | ||
| // Close buttons with only an icon | ||
| <DialogClose> | ||
| <Cross2Icon /> | ||
| <span className="sr-only">Close</span> | ||
| </DialogClose> | ||
|
|
||
| // Command palette title | ||
| <DialogHeader className="sr-only"> | ||
| <DialogTitle>{title}</DialogTitle> | ||
| <DialogDescription>{description}</DialogDescription> | ||
| </DialogHeader> | ||
| ``` | ||
|
|
||
| ## Semantic HTML | ||
|
|
||
| Use proper semantic elements and ARIA roles: | ||
|
|
||
| ```typescript | ||
| // Navigation | ||
| <nav aria-label="breadcrumb"> | ||
|
|
||
| // Current page in breadcrumb | ||
| <span role="link" aria-disabled="true" aria-current="page">{children}</span> | ||
|
|
||
| // Decorative separators | ||
| <li role="presentation" aria-hidden="true"> | ||
|
|
||
| // Alerts | ||
| <div role="alert"> | ||
| ``` | ||
|
|
||
| ## Focus Styling | ||
|
|
||
| All focusable elements must use the project's focus-visible ring pattern: | ||
|
|
||
| ``` | ||
| focus-visible:ring-ring/50 focus-visible:ring-[3px] focus-visible:border-ring | ||
| ``` | ||
|
|
||
| Do not remove `outline-none` without replacing it with a visible focus indicator. | ||
|
|
||
| ## UI Primitives A11y | ||
|
|
||
| The project's primitives already accept `AriaAttributes`: | ||
|
|
||
| - `BlockStack` and `InlineStack` accept all ARIA props | ||
| - `Text` accepts `role` and ARIA props | ||
| - `Button` has built-in focus-visible and disabled states | ||
| - `Input` supports `aria-invalid`, `onEnter`, `onEscape` | ||
| - All shadcn/ui components (Dialog, Select, Checkbox, Switch, Tabs) handle focus trapping and keyboard navigation automatically | ||
|
|
||
| ## React Flow Considerations | ||
|
|
||
| The pipeline editor has specific a11y needs: | ||
|
|
||
| - **Handles**: Support click selection and Escape to deselect | ||
| - **Task nodes**: Labels are interactive with visual feedback | ||
| - **Folders in sidebar**: Use `role="button"` with `aria-expanded` | ||
| - **Canvas keyboard shortcuts**: Must not interfere with dialog/modal focus | ||
|
|
||
| When adding new interactive elements to the flow canvas, ensure they: | ||
|
|
||
| 1. Are keyboard accessible | ||
| 2. Have appropriate ARIA labels | ||
| 3. Don't capture keyboard events that should reach parent containers | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| --- | ||
| name: address-pr-comments | ||
| 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. | ||
| disable-model-invocation: true | ||
| allowed-tools: Bash(gh *), Bash(git *), Bash(gt *), Read, Edit, Write, Grep, Glob, Agent | ||
| --- | ||
|
|
||
| # Address PR Comments | ||
|
|
||
| Check the current branch for an open PR, read all unresolved review comments, and let the user pick which ones to address. | ||
|
|
||
| ## Step 1: Find the PR | ||
|
|
||
| ```bash | ||
| gh pr view --json number,title,url,state --jq '{number, title, url, state}' | ||
| ``` | ||
|
|
||
| If no PR exists for the current branch, tell the user and stop. | ||
|
|
||
| Also determine the current GitHub user: | ||
|
|
||
| ```bash | ||
| gh api user --jq '.login' | ||
| ``` | ||
|
|
||
| ## Step 2: Fetch review comments | ||
|
|
||
| Get all review comments (not general PR comments): | ||
|
|
||
| ```bash | ||
| 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}' | ||
| ``` | ||
|
|
||
| ## Step 3: Filter to actionable comments | ||
|
|
||
| Build a thread map by grouping comments using `in_reply_to_id`. For each top-level comment thread: | ||
|
|
||
| **Skip the thread if ANY of these are true:** | ||
|
|
||
| - The thread is already resolved | ||
| - The top-level comment was made by the current user | ||
| - The top-level comment was made by a bot (dependabot, github-actions, etc.) | ||
| - The comment is a pure approval with no actionable feedback | ||
| - **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. | ||
|
|
||
| This ensures running the command again won't double-reply to already-addressed comments. | ||
|
|
||
| ## Step 4: Analyze comments and present for selection | ||
|
|
||
| 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. | ||
|
|
||
| Use the AskUserQuestion tool to show a **multi-select list** of all remaining unresolved, unaddressed comments. Each option should show: | ||
|
|
||
| - The reviewer's username | ||
| - The file path and line number | ||
| - A truncated preview of the comment (first ~80 characters) | ||
| - **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") | ||
|
|
||
| Example options: | ||
|
|
||
| - `[reviewer] file.ts:42 — "Fix this typo..." → Will fix: rename varName to variableName` | ||
| - `[reviewer] other.ts:10 — "This should use..." → Will push back: current pattern is more performant here` | ||
| - `[reviewer] types.ts:5 — "Why not use...?" → Will answer: explain the tradeoff` | ||
|
|
||
| The user picks which comments they want to address. Only proceed with the selected ones. | ||
|
|
||
| If there are no actionable comments, tell the user everything has been addressed and stop. | ||
|
|
||
| ## Step 5: Address each selected comment | ||
|
|
||
| **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. | ||
|
|
||
| For each selected comment, read the relevant file and surrounding context, then decide: | ||
|
|
||
| ### If the suggestion is correct and actionable: | ||
|
|
||
| 1. Make the code change | ||
| 2. Reply to the comment confirming the fix: | ||
|
|
||
| ```markdown | ||
| Fixed — <brief description of what was changed>. | ||
| ``` | ||
|
|
||
| ### If the suggestion is already addressed: | ||
|
|
||
| Reply explaining that it's already handled: | ||
|
|
||
| ```markdown | ||
| This is already handled — <explanation with file path/line reference>. | ||
| ``` | ||
|
|
||
| ### If the suggestion is incorrect or not applicable: | ||
|
|
||
| Reply respectfully pushing back: | ||
|
|
||
| ```markdown | ||
| I think the current approach is better here because <reasoning>. <Optional: offer an alternative compromise>. | ||
| ``` | ||
|
|
||
| ### If the comment is a question (not a change request): | ||
|
|
||
| Reply with the answer: | ||
|
|
||
| ```markdown | ||
| <Answer the question with relevant context/file references>. | ||
| ``` | ||
|
|
||
| ## Step 6: Post replies | ||
|
|
||
| For each comment, post the reply: | ||
|
|
||
| ```bash | ||
| gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies -f body="<reply>" | ||
| ``` | ||
|
|
||
| ## Step 7: Stage and commit fixes | ||
|
|
||
| If any code changes were made: | ||
|
|
||
| 1. Stage only the files that were modified to address comments | ||
| 2. Create a commit with a message like: `address pr feedback` | ||
| 3. Do NOT push — tell the user the changes are committed and ready to push | ||
|
|
||
| ## Step 8: Show summary | ||
|
|
||
| After all comments are addressed, show a summary table with columns: | ||
|
|
||
| | # | File | Comment | Action | | ||
| | --- | ---- | ------- | ------ | | ||
|
|
||
| Where **Action** clearly states what was done: "Fixed — ...", "Pushed back — ...", "Answered — ...", or "Already handled — ...". | ||
|
|
||
| ## Important | ||
|
|
||
| - Always read the full file context before deciding how to address a comment | ||
| - **Think critically** — do not default to agreeing. Push back when the suggestion is wrong, harmful, or inconsistent with the codebase | ||
| - Never dismiss feedback rudely — be respectful even when pushing back | ||
| - If a comment requires a large refactor or is out of scope, say so and suggest a follow-up issue | ||
| - Group related comments that touch the same code — address them together | ||
| - If unsure about a comment's intent, ask the user before responding | ||
| - Show the user what you plan to reply before posting, so they can adjust |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.