Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .agents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# .agents/ - Codex Skill Entrypoints

> Codex loads project-local skills from this directory. These packages are the Codex-facing entrypoints for reusable workflows that need scripts, references, or progressive context loading.

## Directory Overview

| Directory | Responsibility | Notes |
|-----------|----------------|-------|
| [skills/](skills/) | Project-local Codex skills | Mirrors the reusable skill packages originally maintained under `.claude/skills/` |

## Boundary With .codex/

| Directory | Purpose |
|-----------|---------|
| `.agents/skills/` | Skills that Codex can discover and invoke from natural-language requests |
| `.codex/agents/` | Codex sub-agent configuration in TOML format |
| `.codex/hooks/` | Hook scripts and Codex hook configuration |
| `.claude/` | Legacy Claude Code prompts, rules, and historical source material |

## Maintenance

- Add a `SKILL.md` with frontmatter for every skill package.
- Keep each skill's scripts and references inside the same skill directory.
- Update [skills/README.md](skills/README.md) when adding, removing, or renaming a skill.
- Prefer `.agents/skills/<name>/...` paths in Codex-facing docs.
47 changes: 47 additions & 0 deletions .agents/skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# skills/ - Codex Skill Packages

> Project-local skills for Codex. Each package contains a `SKILL.md` entrypoint, plus optional `scripts/` and `references/` directories.

## File Manifest

| Skill | Purpose | Trigger Scenario |
|-------|---------|------------------|
| [prd-import/](prd-import/) | Convert non-Markdown requirement formats (`.docx`, `.xlsx`, `.pptx`) into markdown source material | Product or backend hands over Word, Excel, or PowerPoint requirements |
| [ext-dep-audit/](ext-dep-audit/) | Dependency security and health audit | Dependency inspection, vulnerability checks, outdated packages |
| [ext-perf-audit/](ext-perf-audit/) | Frontend performance audit | Page jank, bundle size, render performance, initial load optimization |
| [ext-a11y-check/](ext-a11y-check/) | Accessibility WCAG 2.1 AA compliance check | Screen reader, keyboard navigation, semantic HTML, antd accessibility review |
| [ext-changelog/](ext-changelog/) | Human-readable change impact report | Weekly reports, handoffs, retrospectives, recent-change summaries |

## Naming Conventions

- `ext-*` means optional analysis/audit skill, used on demand.
- Names without `ext-` are companion skills for the main workflow, such as `prd-import`.

## Directory Structure

```text
skills/<skill-name>/
|-- SKILL.md
|-- scripts/
| `-- helper.sh
`-- references/
`-- checklist.md
```

## Script Conventions

- Scripts should be invoked through paths under `.agents/skills/<skill-name>/scripts/`.
- Scripts collect deterministic data; Codex interprets the result.
- Scripts should print useful diagnostics and avoid destructive behavior.

## References

- Keep long checklists or format guides in `references/`.
- Link to references from `SKILL.md`; do not inline large reference material in the skill body.

## Adding A Skill

1. Create `.agents/skills/<new-skill>/SKILL.md`.
2. Add optional `scripts/` and `references/` folders.
3. Register the skill in this README.
4. Update any workflow docs if users need to invoke it directly.
53 changes: 53 additions & 0 deletions .agents/skills/ext-a11y-check/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
name: ext-a11y-check
description: Accessibility audit. Performs WCAG 2.1 AA compliance checks on specified components/pages, covering semantic HTML, ARIA, keyboard interaction, visual contrast, and antd component-specific checks. Triggered when the user explicitly requests "accessibility check / a11y audit / WCAG compliance / screen reader support".
---

# ext-a11y-check — Accessibility Compliance Check

You are now an Accessibility expert. Perform a WCAG 2.1 AA compliance check on the specified component or page.

## Execution Approach

A11y checks rely primarily on static analysis (reading JSX / CSS) — there are no definitive scripts. AI scans the source code item-by-item against [references/wcag-aa-checklist.md](references/wcag-aa-checklist.md) and cross-references [references/antd-a11y-notes.md](references/antd-a11y-notes.md) for antd-specific checks.

## Audit Flow

1. Read the file/directory specified by `$ARGUMENTS`
2. Check each item across the 5 dimensions in [references/wcag-aa-checklist.md](references/wcag-aa-checklist.md):
- Semantic HTML
- ARIA attributes
- Keyboard interaction
- Visual (contrast / alt text / text scaling)
- antd component-specific checks
3. Link each issue to the specific WCAG 2.1 criterion (e.g. `1.1.1 Non-text Content`)
4. Output violations + improvements + compliance rate

## Output Format

```
🔴 Violations (WCAG AA non-compliant):
- [file:line] Issue description
Standard: WCAG 2.1 criterion number (e.g. 1.1.1 Non-text Content)
Impact: Specific affected group (e.g. visually impaired users cannot determine the button's purpose)
Fix: Code example

🟡 Improvements (enhances experience but not required):
- [file:line] Issue description
Fix: Proposed solution

📊 Compliance rate: X/Y items passing, Rating: AA / Non-compliant
```

## Usage

```
/ext-a11y-check workspace/src/features/login/
/ext-a11y-check workspace/src/components/DataTable.tsx
```

## Design Principles

- Use native HTML semantics where they suffice; don't overuse ARIA
- Every 🔴 violation must cite the WCAG criterion number so users can look it up
- Never auto-modify code — output a list of issues and recommendations only; fixes are done manually by the user or via `/fix`
111 changes: 111 additions & 0 deletions .agents/skills/ext-a11y-check/references/antd-a11y-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# antd Component Accessibility Notes

> antd v5 has built-in a11y for most components. The following are easy-to-miss spots and pitfalls when customizing.

## Table

```tsx
// Recommended: add summary (screen readers will announce it)
<Table
dataSource={data}
columns={columns}
summary={() => <Table.Summary>Total: X items</Table.Summary>}
rowKey="id"
/>
```

- `rowKey` must be stable; never use index
- When customizing header render, ensure `th` semantics are preserved
- For complex headers, use the `title` prop on `Table.Column` — don't write raw JSX that breaks the `scope` attribute

## Modal

```tsx
<Modal
title="Confirm Delete" // required — screen readers need this
open={open}
onCancel={handleClose}
>
```

- `title` is required; don't pass `null` (unless you implement `aria-labelledby` yourself)
- `closable` defaults to true (keep the close button); don't disable it
- `keyboard` defaults to true (Esc to close); don't disable it
- Focus trapping is handled by antd

## Form

- `Form.Item`'s `label` is automatically associated by id — leave it as-is
- Error messages have `role="alert"` and will be announced by screen readers
- Custom components wired to `Form.Item` must implement `value` + `onChange`; don't rely solely on internal state

## Icon Buttons

```tsx
// ❌
<Button icon={<DeleteOutlined />} />
<Button icon={<SearchOutlined />} type="primary" />

// ✅
<Button icon={<DeleteOutlined />} aria-label="Delete" />

// ✅ or use Tooltip (title is linked via aria-describedby)
<Tooltip title="Delete">
<Button icon={<DeleteOutlined />} />
</Tooltip>
```

## Tooltip / Popover

- `title` is required
- Purely visual tooltips are fine, **but never put important information only in a Tooltip** — keyboard and touch users may not be able to access it
- Critical information like form errors and required-field indicators must be visible in the DOM

## Select / DatePicker / Cascader

- Built-in keyboard support: ↑↓ to navigate, Enter to select, Esc to close
- `placeholder` is not a substitute for `label`; screen readers do not read placeholder text
- Custom `dropdownRender` must preserve `role="option"` on options

## Menu

- Built-in `role="menu"` + `role="menuitem"`
- Keyboard: ← → for sibling menus, ↑ ↓ for items in the same level, Enter to activate
- Keep `key` stable on custom `<Menu.Item>` elements

## Tabs

- Built-in `role="tablist"` + `role="tab"` + `role="tabpanel"`
- Keyboard: ← → to switch tabs
- Don't use `forceRender={false}` and then depend on refs inside the tab — refs are null when the tab hasn't rendered

## Drawer

- Same as Modal: `title` is required; focus trapping is already handled

## Upload

- Drag-and-drop areas must have clear text labels — icon alone is not sufficient
- The `accept` attribute helps screen readers announce which file types are supported

## Icon

```tsx
// Purely decorative icon — add aria-hidden
<CheckCircleOutlined aria-hidden />
<span>Success</span>

// Icon that carries meaning on its own — add aria-label
<LoadingOutlined aria-label="Loading" />
```

## Quick Checklist

| Scenario | What to check |
|----------|--------------|
| Icon buttons | Does it have `aria-label` or a Tooltip? |
| Modal | Is `title` provided? |
| Table | Is `rowKey` stable? |
| Tooltip | If info is only accessible on hover, how do keyboard users get it? |
| Custom interactions | Are `tabIndex` + `onKeyDown` both implemented? |
| Images | Is `alt` provided? Decorative images should use `alt=""` — not omit it entirely |
Loading