codebyplan 1.5.1 → 1.9.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/dist/cli.js +4462 -748
- package/package.json +5 -1
- package/templates/.gitkeep +0 -0
- package/templates/README.md +20 -0
- package/templates/agents/cbp-cc-executor.md +213 -0
- package/templates/agents/cbp-database-agent.md +229 -0
- package/templates/agents/cbp-improve-claude.md +245 -0
- package/templates/agents/cbp-improve-round.md +284 -0
- package/templates/agents/cbp-mechanical-edits.md +111 -0
- package/templates/agents/cbp-research.md +282 -0
- package/templates/agents/cbp-round-executor.md +604 -0
- package/templates/agents/cbp-security-agent.md +134 -0
- package/templates/agents/cbp-task-check.md +213 -0
- package/templates/agents/cbp-task-planner.md +582 -0
- package/templates/agents/cbp-test-e2e-agent.md +363 -0
- package/templates/agents/cbp-testing-qa-agent.md +400 -0
- package/templates/context/mcp-docs.md +139 -0
- package/templates/hooks/README.md +236 -0
- package/templates/hooks/cbp-auto-test-hooks.sh +44 -0
- package/templates/hooks/cbp-lint-format-on-edit.sh +159 -0
- package/templates/hooks/cbp-maestro-yaml-validate.sh +100 -0
- package/templates/hooks/cbp-mcp-migration-guard.sh +32 -0
- package/templates/hooks/cbp-mcp-round-sync.sh +79 -0
- package/templates/hooks/cbp-mcp-worktree-inject.sh +76 -0
- package/templates/hooks/cbp-notify.sh +68 -0
- package/templates/hooks/cbp-plugin-dispatch.sh +29 -0
- package/templates/hooks/cbp-pre-commit-quality-gate.sh +204 -0
- package/templates/hooks/cbp-statusline.sh +347 -0
- package/templates/hooks/cbp-subagent-statusline.sh +182 -0
- package/templates/hooks/cbp-test-coverage-gate.sh +144 -0
- package/templates/hooks/cbp-test-hooks.sh +320 -0
- package/templates/hooks/hooks.json +85 -0
- package/templates/hooks/validate-context-usage.sh +59 -0
- package/templates/hooks/validate-git-commit.sh +78 -0
- package/templates/hooks/validate-git-stash-deny.sh +32 -0
- package/templates/hooks/validate-structure-lengths.sh +57 -0
- package/templates/hooks/validate-structure-lib.sh +104 -0
- package/templates/hooks/validate-structure-patterns.sh +54 -0
- package/templates/hooks/validate-structure-scope.sh +33 -0
- package/templates/hooks/validate-structure-smoke.sh +95 -0
- package/templates/hooks/validate-structure-templates.sh +34 -0
- package/templates/hooks/validate-structure.sh +69 -0
- package/templates/rules/.gitkeep +0 -0
- package/templates/rules/README.md +47 -0
- package/templates/rules/context-file-loading.md +52 -0
- package/templates/rules/scope-vocabulary.md +64 -0
- package/templates/rules/todo-backend.md +109 -0
- package/templates/settings.project.base.json +55 -0
- package/templates/settings.user.base.json +25 -0
- package/templates/skills/cbp-build-cc-agent/SKILL.md +139 -0
- package/templates/skills/cbp-build-cc-agent/examples/read-only-reviewer.md +32 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-hooks.md +41 -0
- package/templates/skills/cbp-build-cc-agent/examples/with-skills-preload.md +25 -0
- package/templates/skills/cbp-build-cc-agent/reference/cbp-quality.md +153 -0
- package/templates/skills/cbp-build-cc-agent/reference/frontmatter-fields.md +37 -0
- package/templates/skills/cbp-build-cc-agent/reference/permission-modes.md +18 -0
- package/templates/skills/cbp-build-cc-agent/scripts/validate-agent.sh +67 -0
- package/templates/skills/cbp-build-cc-agent/templates/agent.md +66 -0
- package/templates/skills/cbp-build-cc-claude-file/SKILL.md +178 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/minimal-project.md +33 -0
- package/templates/skills/cbp-build-cc-claude-file/examples/monorepo-with-imports.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/imports.md +72 -0
- package/templates/skills/cbp-build-cc-claude-file/reference/what-belongs.md +39 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/project-claude-md.md +48 -0
- package/templates/skills/cbp-build-cc-claude-file/templates/user-claude-md.md +22 -0
- package/templates/skills/cbp-build-cc-memory/SKILL.md +201 -0
- package/templates/skills/cbp-build-cc-memory/examples/feedback-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/project-memory.md +11 -0
- package/templates/skills/cbp-build-cc-memory/examples/reference-memory.md +13 -0
- package/templates/skills/cbp-build-cc-memory/examples/user-memory.md +14 -0
- package/templates/skills/cbp-build-cc-memory/reference/memory-types.md +59 -0
- package/templates/skills/cbp-build-cc-memory/reference/when-to-save.md +62 -0
- package/templates/skills/cbp-build-cc-memory/templates/MEMORY-index.md +4 -0
- package/templates/skills/cbp-build-cc-memory/templates/memory-entry.md +15 -0
- package/templates/skills/cbp-build-cc-mode/SKILL.md +99 -0
- package/templates/skills/cbp-build-cc-rule/SKILL.md +176 -0
- package/templates/skills/cbp-build-cc-rule/examples/global-rule.md +19 -0
- package/templates/skills/cbp-build-cc-rule/examples/scoped-rule.md +41 -0
- package/templates/skills/cbp-build-cc-rule/reference/paths-patterns.md +48 -0
- package/templates/skills/cbp-build-cc-rule/templates/rule.md +32 -0
- package/templates/skills/cbp-build-cc-settings/SKILL.md +220 -0
- package/templates/skills/cbp-build-cc-settings/examples/hooks-config.json +64 -0
- package/templates/skills/cbp-build-cc-settings/examples/permissions-config.json +34 -0
- package/templates/skills/cbp-build-cc-settings/examples/sandbox-config.json +42 -0
- package/templates/skills/cbp-build-cc-settings/reference/cbp-conventions.md +104 -0
- package/templates/skills/cbp-build-cc-settings/reference/permission-rules.md +61 -0
- package/templates/skills/cbp-build-cc-settings/reference/scope-precedence.md +73 -0
- package/templates/skills/cbp-build-cc-settings/reference/settings-fields.md +166 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.json +23 -0
- package/templates/skills/cbp-build-cc-settings/templates/settings.local.json +10 -0
- package/templates/skills/cbp-build-cc-skill/SKILL.md +154 -0
- package/templates/skills/cbp-build-cc-skill/examples/dynamic-context.md +31 -0
- package/templates/skills/cbp-build-cc-skill/examples/fork-skill.md +22 -0
- package/templates/skills/cbp-build-cc-skill/examples/knowledge-skill.md +25 -0
- package/templates/skills/cbp-build-cc-skill/examples/task-skill.md +29 -0
- package/templates/skills/cbp-build-cc-skill/reference/cbp-quality.md +157 -0
- package/templates/skills/cbp-build-cc-skill/reference/frontmatter-fields.md +35 -0
- package/templates/skills/cbp-build-cc-skill/reference/string-substitutions.md +60 -0
- package/templates/skills/cbp-build-cc-skill/scripts/validate-skill.sh +90 -0
- package/templates/skills/cbp-build-cc-skill/templates/skill.md +51 -0
- package/templates/skills/cbp-checkpoint-check/SKILL.md +156 -0
- package/templates/skills/cbp-checkpoint-complete/SKILL.md +109 -0
- package/templates/skills/cbp-checkpoint-create/SKILL.md +116 -0
- package/templates/skills/cbp-checkpoint-end/SKILL.md +241 -0
- package/templates/skills/cbp-checkpoint-plan/SKILL.md +137 -0
- package/templates/skills/cbp-checkpoint-plan/reference/alternative-comparison-template.md +54 -0
- package/templates/skills/cbp-checkpoint-plan/reference/dep-decision-rubric.md +50 -0
- package/templates/skills/cbp-checkpoint-plan/reference/e2e-discovery-probe.md +57 -0
- package/templates/skills/cbp-checkpoint-plan/reference/gap-analysis-playbook.md +47 -0
- package/templates/skills/cbp-checkpoint-start/SKILL.md +84 -0
- package/templates/skills/cbp-checkpoint-update/SKILL.md +115 -0
- package/templates/skills/cbp-frontend-a11y/SKILL.md +109 -0
- package/templates/skills/cbp-frontend-a11y/reference/aria-roles-states.md +130 -0
- package/templates/skills/cbp-frontend-a11y/reference/contrast-visual.md +122 -0
- package/templates/skills/cbp-frontend-a11y/reference/keyboard-patterns.md +154 -0
- package/templates/skills/cbp-frontend-a11y/reference/semantic-html.md +111 -0
- package/templates/skills/cbp-frontend-design/SKILL.md +145 -0
- package/templates/skills/cbp-frontend-design/reference/nextjs-scss.md +118 -0
- package/templates/skills/cbp-frontend-design/reference/rn-expo.md +101 -0
- package/templates/skills/cbp-frontend-design/reference/tauri-react.md +82 -0
- package/templates/skills/cbp-frontend-ui/SKILL.md +262 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-label-maps.md +42 -0
- package/templates/skills/cbp-frontend-ui/reference/ui-layout-patterns.md +105 -0
- package/templates/skills/cbp-frontend-ui/reference/variant-defaults.md +149 -0
- package/templates/skills/cbp-frontend-ux/SKILL.md +181 -0
- package/templates/skills/cbp-git-branch-feat-create/SKILL.md +115 -0
- package/templates/skills/cbp-git-commit/SKILL.md +278 -0
- package/templates/skills/cbp-git-worktree-create/SKILL.md +226 -0
- package/templates/skills/cbp-git-worktree-remove/SKILL.md +145 -0
- package/templates/skills/cbp-merge-main/SKILL.md +228 -0
- package/templates/skills/cbp-round-check/SKILL.md +104 -0
- package/templates/skills/cbp-round-end/SKILL.md +183 -0
- package/templates/skills/cbp-round-end/reference/findings-presentation.md +44 -0
- package/templates/skills/cbp-round-end/reference/inline-fallback.md +35 -0
- package/templates/skills/cbp-round-execute/SKILL.md +211 -0
- package/templates/skills/cbp-round-execute/reference/inline-fallback.md +59 -0
- package/templates/skills/cbp-round-input/SKILL.md +165 -0
- package/templates/skills/cbp-round-start/SKILL.md +222 -0
- package/templates/skills/cbp-round-update/SKILL.md +163 -0
- package/templates/skills/cbp-session-end/SKILL.md +187 -0
- package/templates/skills/cbp-session-start/SKILL.md +155 -0
- package/templates/skills/cbp-ship/SKILL.md +332 -0
- package/templates/skills/cbp-ship/reference/changesets-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/eas-cli-overview.md +60 -0
- package/templates/skills/cbp-ship/reference/gh-cli-overview.md +135 -0
- package/templates/skills/cbp-ship/reference/gh-cli-shipment-commands.md +283 -0
- package/templates/skills/cbp-ship/reference/npm-publish-monorepo.md +252 -0
- package/templates/skills/cbp-ship/reference/npm-publish-oidc-trusted.md +157 -0
- package/templates/skills/cbp-ship/reference/npm-publish-overview.md +171 -0
- package/templates/skills/cbp-ship/reference/preflight-checklist.md +88 -0
- package/templates/skills/cbp-ship/reference/railway-nestjs-deployment.md +169 -0
- package/templates/skills/cbp-ship/reference/railway-overview.md +120 -0
- package/templates/skills/cbp-ship/reference/railway-troubleshooting.md +168 -0
- package/templates/skills/cbp-ship/reference/release-please-overview.md +99 -0
- package/templates/skills/cbp-ship/reference/surface-expo-eas.md +155 -0
- package/templates/skills/cbp-ship/reference/surface-npm.md +180 -0
- package/templates/skills/cbp-ship/reference/surface-railway.md +152 -0
- package/templates/skills/cbp-ship/reference/surface-supabase.md +178 -0
- package/templates/skills/cbp-ship/reference/surface-tauri.md +138 -0
- package/templates/skills/cbp-ship/reference/surface-vercel.md +124 -0
- package/templates/skills/cbp-ship/reference/surface-vscode-ext.md +144 -0
- package/templates/skills/cbp-ship/reference/surfaces.md +60 -0
- package/templates/skills/cbp-ship/reference/testflight-automation.md +215 -0
- package/templates/skills/cbp-ship/reference/testflight-internal-vs-external.md +69 -0
- package/templates/skills/cbp-ship/reference/testflight-overview.md +98 -0
- package/templates/skills/cbp-ship/reference/versioning.md +116 -0
- package/templates/skills/cbp-ship/scripts/detect-surfaces.sh +217 -0
- package/templates/skills/cbp-ship/scripts/verify-expo-eas.sh +35 -0
- package/templates/skills/cbp-ship/scripts/verify-npm.sh +21 -0
- package/templates/skills/cbp-ship/scripts/verify-railway.sh +41 -0
- package/templates/skills/cbp-ship/scripts/verify-supabase.sh +19 -0
- package/templates/skills/cbp-ship/scripts/verify-tauri.sh +24 -0
- package/templates/skills/cbp-ship/scripts/verify-vercel.sh +32 -0
- package/templates/skills/cbp-ship/scripts/verify-vscode-ext.sh +25 -0
- package/templates/skills/cbp-ship/templates/eas.json +66 -0
- package/templates/skills/cbp-ship/templates/railway.toml +15 -0
- package/templates/skills/cbp-ship/templates/release-please-config.json +17 -0
- package/templates/skills/cbp-ship/templates/vercel.json +19 -0
- package/templates/skills/cbp-ship/templates/vscodeignore +21 -0
- package/templates/skills/cbp-ship/templates/workflow-changesets.yml +41 -0
- package/templates/skills/cbp-ship/templates/workflow-eas-submit.yml +53 -0
- package/templates/skills/cbp-ship/templates/workflow-npm-publish.yml +36 -0
- package/templates/skills/cbp-ship/templates/workflow-release-please.yml +21 -0
- package/templates/skills/cbp-ship/templates/workflow-tauri-release.yml +69 -0
- package/templates/skills/cbp-ship/templates/workflow-vsce-publish.yml +31 -0
- package/templates/skills/cbp-ship-configure/SKILL.md +296 -0
- package/templates/skills/cbp-ship-configure/reference/expo-mobile.md +204 -0
- package/templates/skills/cbp-ship-configure/reference/npm-package.md +165 -0
- package/templates/skills/cbp-ship-configure/reference/railway-backend.md +199 -0
- package/templates/skills/cbp-ship-configure/reference/supabase.md +200 -0
- package/templates/skills/cbp-ship-configure/reference/tauri-desktop.md +181 -0
- package/templates/skills/cbp-ship-configure/reference/vercel.md +117 -0
- package/templates/skills/cbp-ship-configure/reference/vscode-ext.md +155 -0
- package/templates/skills/cbp-ship-main/SKILL.md +65 -0
- package/templates/skills/cbp-supabase-branch-check/SKILL.md +337 -0
- package/templates/skills/cbp-supabase-branch-check/reference/dag-steps.md +29 -0
- package/templates/skills/cbp-supabase-migrate/SKILL.md +314 -0
- package/templates/skills/cbp-supabase-migrate/reference/advisor-triage.md +70 -0
- package/templates/skills/cbp-supabase-migrate/reference/cli-fallback.md +87 -0
- package/templates/skills/cbp-supabase-migrate/reference/preflight-dry-run.md +58 -0
- package/templates/skills/cbp-supabase-setup/SKILL.md +239 -0
- package/templates/skills/cbp-supabase-setup/reference/branching-setup.md +121 -0
- package/templates/skills/cbp-supabase-setup/reference/cli-fallback.md +109 -0
- package/templates/skills/cbp-task-check/SKILL.md +166 -0
- package/templates/skills/cbp-task-complete/SKILL.md +206 -0
- package/templates/skills/cbp-task-complete/reference/checkpoint-done-branching.md +48 -0
- package/templates/skills/cbp-task-complete/reference/next-step-heuristic.md +56 -0
- package/templates/skills/cbp-task-create/SKILL.md +167 -0
- package/templates/skills/cbp-task-start/SKILL.md +239 -0
- package/templates/skills/cbp-task-testing/SKILL.md +277 -0
- package/templates/skills/cbp-todo/SKILL.md +111 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Dependency Decision Rubric
|
|
6
|
+
|
|
7
|
+
Loaded by `/cbp-checkpoint-plan` Step 5. Use when an idea could be built by extending something already installed OR by pulling in a new dependency. The goal is a deliberate, recorded choice — never a silent `pnpm add`.
|
|
8
|
+
|
|
9
|
+
## Decision tree
|
|
10
|
+
|
|
11
|
+
1. **Does an installed dependency already cover this?**
|
|
12
|
+
- Check `package.json` (root + the relevant workspace) and `vendor/INDEX.md` for an existing library.
|
|
13
|
+
- Grep the codebase for prior art — the capability may already be wrapped in a util/hook/service.
|
|
14
|
+
- If yes and it fits → **extend the existing dependency**. Record a `locked` decision and stop.
|
|
15
|
+
|
|
16
|
+
2. **Can the existing dependency be extended at acceptable cost?**
|
|
17
|
+
- A thin wrapper / adapter over an installed lib almost always beats a new dependency.
|
|
18
|
+
- If extension means forking or fighting the library → a new dependency may be justified; continue.
|
|
19
|
+
|
|
20
|
+
3. **Is a new dependency warranted?** Weigh:
|
|
21
|
+
|
|
22
|
+
| Factor | Favors extending | Favors new dependency |
|
|
23
|
+
|--------|------------------|-----------------------|
|
|
24
|
+
| Capability gap | Existing covers ~all of it | Existing covers little / poorly |
|
|
25
|
+
| Bundle weight | Adds to an already-loaded dep | Heavy add to a lean surface (esp. mobile) |
|
|
26
|
+
| Maintenance | No new supply-chain surface | Well-maintained, widely used, typed |
|
|
27
|
+
| Vendor docs | — | A `vendor/{lib}/v{ver}/` mirror exists or can be scaffolded via `/cbp-build-vendor-doc` |
|
|
28
|
+
| Lock-in / migration | Reuses known patterns | One-way door; migration cost later |
|
|
29
|
+
|
|
30
|
+
4. **Consequential choice?** If adding a new dependency meaningfully changes bundle size, security surface, or architecture, surface it to the user via AskUserQuestion with the trade-off table above. Otherwise decide inline and record it.
|
|
31
|
+
|
|
32
|
+
## Record format
|
|
33
|
+
|
|
34
|
+
Write the outcome as a `context.decisions[]` entry (read-merge-write the full context per Step 10):
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"decision": "Extend the installed date-fns rather than add dayjs",
|
|
39
|
+
"rationale": "date-fns already bundled; needed formatter is a 3-line wrapper; avoids a second date lib",
|
|
40
|
+
"locked": true
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
When a new dependency IS chosen, also add a `context.dependencies[]` entry naming it and (if no vendor mirror exists) a plan step to scaffold one via `/cbp-build-vendor-doc`.
|
|
45
|
+
|
|
46
|
+
## Anti-patterns
|
|
47
|
+
|
|
48
|
+
- Adding a library for something the standard lib or an installed dep already does.
|
|
49
|
+
- Two libraries that solve the same problem (e.g. two date libs, two state managers) — consolidate instead.
|
|
50
|
+
- Deciding silently — every extend-vs-add fork must leave a recorded, locked decision so the executor and future planners can see the reasoning.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# E2E Discovery Probe
|
|
6
|
+
|
|
7
|
+
Loaded by `/cbp-checkpoint-plan` Step 4. The probe answers one question before you plan a fix: **is this area actually broken, and how?** It reuses `cbp-test-e2e-agent` (the sole owner of e2e execution) in `whole_checkpoint_mode` rather than introducing a second smoke-test path.
|
|
8
|
+
|
|
9
|
+
## When to offer the probe
|
|
10
|
+
|
|
11
|
+
Offer it only when BOTH hold:
|
|
12
|
+
|
|
13
|
+
- An idea touches a UI surface — its text or the affected files mention a page / screen / route / form / component.
|
|
14
|
+
- You have a concrete suspicion that an existing flow is already broken (not "let's test everything"). The probe targets a named area, not the whole app.
|
|
15
|
+
|
|
16
|
+
Skip silently for backend-only / infra / `claude_only` checkpoints, or when you have no breakage suspicion.
|
|
17
|
+
|
|
18
|
+
## Procedure
|
|
19
|
+
|
|
20
|
+
1. **State the suspicion** — name the area, the specific pages/screens, and why you think it is broken (a stale selector, a route that 404s, a recent refactor nearby).
|
|
21
|
+
2. **Confirm with the user** via AskUserQuestion — the probe needs a running dev server, so it is opt-in. Options: run the probe / skip and plan from assumption / let me name different pages.
|
|
22
|
+
3. **Resolve the dev-server port** from `.codebyplan/server.json` `port_allocations[]` (pick the entry whose `server_type` matches the app, e.g. `nextjs`). If nothing is running there, ask the user to start it or skip.
|
|
23
|
+
4. **Resolve `test_strategy`** — call MCP `get_repos()`, find the entry where `id === repo_id`, and read the affected app's platform + e2e framework from its `tech_stack` record. If the record has no e2e data, pass `null` for the unknown fields — the agent resolves them itself at its Step 1.5. Do NOT pass placeholder strings.
|
|
24
|
+
5. **Spawn** `cbp-test-e2e-agent` with the payload below.
|
|
25
|
+
6. **Interpret** the result: compare what actually failed against what you assumed. Record the delta in `context.discoveries[]` so the plan targets real defects, not imagined ones.
|
|
26
|
+
|
|
27
|
+
## Spawn payload (whole_checkpoint_mode)
|
|
28
|
+
|
|
29
|
+
`round_number: 0` is the documented sentinel for `whole_checkpoint_mode` in the agent's Input Contract — in that mode `files_changed` / `prior_round_files_changed` are ignored and the agent runs the `pages_affected` you give it.
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
input:
|
|
33
|
+
repo_id: <repo UUID from .codebyplan/repo.json>
|
|
34
|
+
round_number: 0 # sentinel — whole_checkpoint_mode
|
|
35
|
+
whole_checkpoint_mode: true
|
|
36
|
+
files_changed: [] # nothing changed yet — probing current state
|
|
37
|
+
prior_round_files_changed: [] # ignored under whole_checkpoint_mode; required for non-probe round_number >= 2 calls
|
|
38
|
+
|
|
39
|
+
test_strategy:
|
|
40
|
+
platform: <from tech_stack DB record>
|
|
41
|
+
e2e_framework: <playwright | maestro | webdriverio | xcuitest | vscode-test>
|
|
42
|
+
pages_affected: ["<route or screen you suspect>", ...]
|
|
43
|
+
has_auth: <true | false>
|
|
44
|
+
dev_server_port: <port from server.json, or null>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## What you get back
|
|
48
|
+
|
|
49
|
+
The agent returns `test_results` (passed / failed / skipped + per-failure `category` and `classification_reason`) and `preflight`. For planning purposes:
|
|
50
|
+
|
|
51
|
+
- `category: 'real'` failures → genuine defects; turn each into a plan step / task.
|
|
52
|
+
- `category: 'env' | 'auth' | 'access' | 'flake'` → not the feature's fault; note it but do not plan a code fix around it.
|
|
53
|
+
- A clean pass → your breakage suspicion was wrong; plan the actual requested change without a "fix" step you did not need.
|
|
54
|
+
|
|
55
|
+
## Why reuse the agent (not a new smoke probe)
|
|
56
|
+
|
|
57
|
+
`cbp-test-e2e-agent` is the declared sole owner of e2e: it auto-detects the platform, reconciles against the `tech_stack` DB record, configures the framework if missing, and classifies failures. A bespoke in-skill smoke check would duplicate that ownership and drift. The probe is a thin, opt-in caller of the existing agent.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Gap Analysis Playbook
|
|
6
|
+
|
|
7
|
+
Loaded by `/cbp-checkpoint-plan` Step 3. The job: find what the raw request misses, before any task is created. Most "half-ass" outcomes come from planning only what was literally asked and ignoring the foundations it depends on or the adjacent breakage it sits next to.
|
|
8
|
+
|
|
9
|
+
## Two passes
|
|
10
|
+
|
|
11
|
+
### Pass 1 — in-scope gaps
|
|
12
|
+
|
|
13
|
+
For each idea, compare the stated requirements against codebase reality (Glob/Grep/Read the affected area). Look for:
|
|
14
|
+
|
|
15
|
+
- **Missing foundations** — the request assumes a helper / table / route / type that does not exist yet.
|
|
16
|
+
- **Half-implemented patterns** — a similar feature exists but is incomplete (e.g. a hook with no test, a route with no error path, a component with no loading/empty state).
|
|
17
|
+
- **Implicit requirements** — auth, validation, RLS, migration, types regen, i18n, a11y that the request did not name but the feature needs to be production-ready.
|
|
18
|
+
- **Consistency debt** — the new work would diverge from an established convention unless explicitly aligned.
|
|
19
|
+
|
|
20
|
+
Record each as a `context.discoveries[]` entry: `{ topic, finding }`. These become plan steps in Step 8.
|
|
21
|
+
|
|
22
|
+
### Pass 2 — adjacent findings
|
|
23
|
+
|
|
24
|
+
While reading the area, you will notice problems just outside the literal request (a neighbouring bug, a stale comment referencing a removed symbol, a sibling file with the same latent defect). Classify each:
|
|
25
|
+
|
|
26
|
+
| Class | Meaning | Default action |
|
|
27
|
+
|-------|---------|----------------|
|
|
28
|
+
| `in_scope_gap` | Needed for the request to be production-ready | Add a plan step (Pass 1) |
|
|
29
|
+
| `adjacent_absorbed` | Same neighbourhood, cheap to fix while here, low risk | **Pull into this checkpoint** as a task (locked policy) |
|
|
30
|
+
| `adjacent_deferred` | Real but large/independent enough to warrant its own checkpoint | Record as discovery; confirm with user in Step 7 before dropping |
|
|
31
|
+
|
|
32
|
+
The locked CHK-138 policy is **scope absorption**: prefer `adjacent_absorbed` over `adjacent_deferred`. Only defer when the user explicitly scopes it out in Step 7, or when absorbing it would balloon the checkpoint beyond its deadline.
|
|
33
|
+
|
|
34
|
+
## What "production-ready" means here
|
|
35
|
+
|
|
36
|
+
A plan is complete when, for every idea, you can answer yes to:
|
|
37
|
+
|
|
38
|
+
- Does every requirement have a covering plan step?
|
|
39
|
+
- Are the implicit requirements (auth / validation / migration / types / tests) either covered or explicitly deemed N/A?
|
|
40
|
+
- Did Pass 2 findings get a disposition (absorbed or deferred-with-user-confirmation)?
|
|
41
|
+
- Would shipping this leave any half-implemented pattern in the touched files?
|
|
42
|
+
|
|
43
|
+
If any answer is no, the plan is not done — add the step or ask the question.
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
Everything from this playbook lands in `context.discoveries[]` and, after Step 8, in `plan.steps[]`. Do not create tasks here — task creation is Step 9, after dependency decisions and alternatives are settled.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-checkpoint-start
|
|
4
|
+
description: Activate a planned checkpoint and claim it for the current user/worktree, then route into task work. Runs after /cbp-checkpoint-plan (which produces tasks but never activates). Refuses to start an unplanned checkpoint.
|
|
5
|
+
argument-hint: [checkpoint-number]
|
|
6
|
+
effort: high
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Checkpoint Start Command
|
|
10
|
+
|
|
11
|
+
The activation + claim gate of the checkpoint pipeline. `/cbp-checkpoint-plan` produces tasks but deliberately leaves the checkpoint `pending` and possibly unclaimed so it can sit in a team queue. This skill flips it to `active`, claims it for the caller's worktree if still open, and routes into the first task.
|
|
12
|
+
|
|
13
|
+
## Pipeline
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
/cbp-checkpoint-create → /cbp-checkpoint-plan (tasks, no activation) → /cbp-checkpoint-start (activate + claim, here) → /cbp-task-start
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Instructions
|
|
20
|
+
|
|
21
|
+
### Step 0: Parse `$ARGUMENTS`
|
|
22
|
+
|
|
23
|
+
Source `repo_id` from `.codebyplan/repo.json`. Resolve caller worktree once for the whole skill: `CALLER_WT=$(npx codebyplan resolve-worktree 2>/dev/null)`.
|
|
24
|
+
|
|
25
|
+
| Shape | Resolves to |
|
|
26
|
+
|-------|-------------|
|
|
27
|
+
| `{chk}` (e.g. `138`) | CHK-{chk} via MCP `get_checkpoints` filtered by `number` |
|
|
28
|
+
| _(empty)_ | The next `pending` checkpoint that already has tasks (planned but not yet started); if several, the lowest-numbered |
|
|
29
|
+
|
|
30
|
+
Malformed (non-numeric, contains `-`): surface `checkpoint-start: invalid argument` and stop.
|
|
31
|
+
|
|
32
|
+
### Step 1: Load Checkpoint + Tasks
|
|
33
|
+
|
|
34
|
+
Load the checkpoint (`status`, `worktree_id`, `plan`) and its tasks via MCP `get_tasks(checkpoint_id)`.
|
|
35
|
+
|
|
36
|
+
### Step 2: Planned-Gate
|
|
37
|
+
|
|
38
|
+
A checkpoint must be planned before it can start.
|
|
39
|
+
|
|
40
|
+
- **No tasks AND empty `plan.steps[]`** → refuse: surface `CHK-NNN is not planned yet.` and auto-trigger `/cbp-checkpoint-plan {NNN}`. STOP. (An unplanned checkpoint is `worktree_id`-null, so there is nothing to own yet — always kick off planning, matching `/cbp-todo` Rule A.)
|
|
41
|
+
- **Already `active`** → no activation needed; skip to Step 3 for a claim-check only, then Step 5.
|
|
42
|
+
- **`pending` with tasks** → proceed.
|
|
43
|
+
|
|
44
|
+
### Step 3: Claim Logic
|
|
45
|
+
|
|
46
|
+
Compare the checkpoint's `worktree_id` against `CALLER_WT`:
|
|
47
|
+
|
|
48
|
+
| Checkpoint `worktree_id` | Action |
|
|
49
|
+
|--------------------------|--------|
|
|
50
|
+
| null (left open at create) | Claim it: in Step 4 pass `worktree_id: CALLER_WT`. If `CALLER_WT` is empty, warn the checkpoint will stay unclaimed and proceed without it. |
|
|
51
|
+
| equals `CALLER_WT` | Already yours — no-op. |
|
|
52
|
+
| a DIFFERENT worktree | STOP. Surface: `CHK-NNN is claimed by worktree {other}; current worktree is {CALLER_WT}. If {other} is dead, a maintainer can release it via the release_assignment MCP tool, then re-run /cbp-checkpoint-start.` Do not activate. |
|
|
53
|
+
|
|
54
|
+
This mirrors the CHK-104 hard-lock model — never wrest a checkpoint from a live worktree.
|
|
55
|
+
|
|
56
|
+
### Step 4: Activate
|
|
57
|
+
|
|
58
|
+
If the checkpoint is already `active` AND `worktree_id` already equals `CALLER_WT` (the Step 3 no-op row), skip this step entirely and proceed to Step 5 — nothing to write.
|
|
59
|
+
|
|
60
|
+
Otherwise set the checkpoint `active` via MCP `update_checkpoint(checkpoint_id, status: "active"`, plus `worktree_id: CALLER_WT` when claiming per Step 3, plus `caller_worktree_id: CALLER_WT` so the hard-lock pre-guard accepts the call (omit `caller_worktree_id` only when `CALLER_WT` is empty). If the checkpoint was already `active` but a claim is still needed, skip the status write and only write `worktree_id`.
|
|
61
|
+
|
|
62
|
+
### Step 5: Route
|
|
63
|
+
|
|
64
|
+
Follow the close-out routing convention — auto-trigger the next same-context step, never an A/B/C menu. `{first-pending-task}` is the lowest-numbered pending task from Step 1 (not necessarily TASK-1, since additive re-planning may have completed earlier ones):
|
|
65
|
+
|
|
66
|
+
- **Claimed by THIS session** (`CALLER_WT` now owns the checkpoint): auto-trigger `/cbp-task-start {chk}-{first-pending-task}` in the same context.
|
|
67
|
+
- **`CALLER_WT` empty / unresolved**: surface a single directive — `Next: /cbp-task-start {chk}-{first-pending-task}` — and let the user proceed.
|
|
68
|
+
|
|
69
|
+
Show a one-line confirmation before routing:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
## Checkpoint Started
|
|
73
|
+
|
|
74
|
+
**CHK-NNN**: [title] • **Status**: active • **Claimed by**: [worktree or "open"]
|
|
75
|
+
**Next task**: TASK-[N] — [title]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Integration
|
|
79
|
+
|
|
80
|
+
- **Reads**: MCP `get_checkpoints`, `get_tasks`; `npx codebyplan resolve-worktree`
|
|
81
|
+
- **Writes**: MCP `update_checkpoint` (status + worktree_id, with caller_worktree_id pre-guard)
|
|
82
|
+
- **Triggered by**: `/cbp-checkpoint-plan` (auto when claimed at create), `/cbp-todo` (planned-but-pending gate), or user directly
|
|
83
|
+
- **Triggers**: `/cbp-task-start` (auto when claimed), or `/cbp-checkpoint-plan` (when the checkpoint is unplanned)
|
|
84
|
+
- **Never**: plans or creates tasks — that is `/cbp-checkpoint-plan`
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-checkpoint-update
|
|
4
|
+
description: Update checkpoint state (activate, update context, etc.)
|
|
5
|
+
argument-hint: [checkpoint-number]
|
|
6
|
+
effort: high
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Checkpoint Update Command
|
|
10
|
+
|
|
11
|
+
Update checkpoint status, context, or other fields.
|
|
12
|
+
|
|
13
|
+
## Instructions
|
|
14
|
+
|
|
15
|
+
### Step 0.5: Parse `$ARGUMENTS`
|
|
16
|
+
|
|
17
|
+
Parse the argument:
|
|
18
|
+
|
|
19
|
+
| Shape | Regex | Resolves to |
|
|
20
|
+
|-------|-------|-------------|
|
|
21
|
+
| `{chk}` (e.g. `108`) | `^[0-9]+$` | Target CHK-{chk} |
|
|
22
|
+
| _(empty)_ | — | Use MCP `get_current_task` to find the active checkpoint |
|
|
23
|
+
|
|
24
|
+
Anything else is malformed — surface this error and stop:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
checkpoint-update: invalid argument `{value}`. Expected:
|
|
28
|
+
108 → CHK-108
|
|
29
|
+
(empty) → active checkpoint
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### Worked examples
|
|
33
|
+
|
|
34
|
+
- `checkpoint-update 108` → CHK-108
|
|
35
|
+
- `checkpoint-update` (no arg) → active checkpoint via `get_current_task`
|
|
36
|
+
- `checkpoint-update abc` → error: malformed
|
|
37
|
+
- `checkpoint-update 108-1` → error: malformed (that is task-start's shape)
|
|
38
|
+
|
|
39
|
+
### Step 1: Get Current Checkpoint
|
|
40
|
+
|
|
41
|
+
Given the parse from Step 0.5:
|
|
42
|
+
|
|
43
|
+
| Parse | Resolution path |
|
|
44
|
+
|-------|-----------------|
|
|
45
|
+
| `{chk}` | MCP `get_checkpoints(repo_id)` → filter `number === {chk}` (must exist). |
|
|
46
|
+
| _(empty)_ | MCP `get_current_task` with repo_id (and worktree_id resolved via `npx codebyplan resolve-worktree`) to find the active checkpoint. If no active checkpoint, use MCP `get_checkpoints` filtered by `pending` status to find pending ones. |
|
|
47
|
+
|
|
48
|
+
### Step 1.5: Detect Entry Context (from `/cbp-task-complete` expand path)
|
|
49
|
+
|
|
50
|
+
When invoked with a preamble naming `Triggered from /cbp-task-complete with intent: expand`, the user just completed the last task in the checkpoint and chose Option B "Expand checkpoint with more tasks" per `task-complete/reference/checkpoint-done-branching.md`.
|
|
51
|
+
|
|
52
|
+
In that case, lead with explicit guidance:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
You're expanding [CHK-NNN]: [title]
|
|
56
|
+
The checkpoint has no remaining tasks; you chose to add more before shipping.
|
|
57
|
+
|
|
58
|
+
Recommended sequence:
|
|
59
|
+
1. (here) update context — record any new decisions / discoveries / scope clarifications driving the expansion
|
|
60
|
+
2. (next) `/cbp-task-create` — add the specific tasks the expansion calls for
|
|
61
|
+
|
|
62
|
+
You can skip the context update (Steps 2–3) if the expansion is purely additive with no scope change. Run `/cbp-task-create` directly in that case.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
When invoked WITHOUT this preamble (direct user invocation), skip the guidance and proceed normally.
|
|
66
|
+
|
|
67
|
+
### Step 2: Determine Update
|
|
68
|
+
|
|
69
|
+
Ask user via AskUserQuestion what to update:
|
|
70
|
+
- **Activate**: Change pending → active (starts development)
|
|
71
|
+
- **Update context**: Add decisions, discoveries, constraints
|
|
72
|
+
- **Update goal**: Refine the checkpoint goal
|
|
73
|
+
- **Update deadline**: Change the deadline
|
|
74
|
+
|
|
75
|
+
When the entry context is "expand from task-complete", `Update context` is the recommended default.
|
|
76
|
+
|
|
77
|
+
### Step 3: Apply Update
|
|
78
|
+
|
|
79
|
+
Use MCP `update_checkpoint` with the appropriate fields.
|
|
80
|
+
|
|
81
|
+
**For activation:**
|
|
82
|
+
```
|
|
83
|
+
update_checkpoint(checkpoint_id, status: "active")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**For context updates:**
|
|
87
|
+
Read current checkpoint to get existing context, merge new data, then:
|
|
88
|
+
```
|
|
89
|
+
update_checkpoint(checkpoint_id, context: merged_context)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Step 4: Show Result and Route
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
## Checkpoint Updated
|
|
96
|
+
|
|
97
|
+
**CHK-[NNN]**: [Title]
|
|
98
|
+
**Status**: [new status]
|
|
99
|
+
**Updated**: [what changed]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
When the entry context was "expand from task-complete", append:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
**Next:**
|
|
106
|
+
Run `/cbp-task-create` to add the new task(s) under this checkpoint.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Otherwise, no follow-up directive — the user is back in control.
|
|
110
|
+
|
|
111
|
+
## Integration
|
|
112
|
+
|
|
113
|
+
- **Reads**: MCP `get_current_task`, `get_checkpoints`
|
|
114
|
+
- **Writes**: MCP `update_checkpoint`
|
|
115
|
+
- **Triggered by**: User directly, OR `/cbp-task-complete` Step 9c (expand path) — see `task-complete/reference/checkpoint-done-branching.md`
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
scope: org-shared
|
|
3
|
+
name: cbp-frontend-a11y
|
|
4
|
+
description: Pre-implementation accessibility playbook loaded BEFORE writing UI / styling code. Produces a per-component checklist of WCAG 2.1 AA obligations from semantic HTML, ARIA roles/states, keyboard patterns, and contrast requirements.
|
|
5
|
+
effort: xhigh
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Frontend Accessibility (Pre-Implementation Playbook)
|
|
9
|
+
|
|
10
|
+
Loaded by `round-executor` Step 2.6 BEFORE any UI or styling file is written, AFTER `frontend-design` has committed to an aesthetic direction. Produces a concrete pre-write checklist — not a post-implementation audit.
|
|
11
|
+
|
|
12
|
+
## When this skill fires
|
|
13
|
+
|
|
14
|
+
Invoked when the wave's `skill_preloads[]` contains `"frontend-a11y"` (set by planner Phase 5.6 when `wave.files[]` includes UI-bearing paths). See `rules/frontend-accessibility-invocation.md` for the trigger gate.
|
|
15
|
+
|
|
16
|
+
If none of the wave files are UI-bearing, skip — proceed to Step 3.
|
|
17
|
+
|
|
18
|
+
## Phase 1: Read tokens and sibling components
|
|
19
|
+
|
|
20
|
+
1. Identify design tokens from the plan's context or `frontend-design` output — colour tokens are needed for contrast checks.
|
|
21
|
+
2. Glob for sibling components in the same directory as files being authored. Read 1-2 examples to understand existing `aria-*` usage, `role` attributes, keyboard handlers, focus management patterns.
|
|
22
|
+
3. Note the established a11y posture: does the codebase already use `role="dialog"` patterns? Does it trap focus in modals? Are there custom keyboard handlers?
|
|
23
|
+
|
|
24
|
+
## Phase 2: Detect the stack
|
|
25
|
+
|
|
26
|
+
Read the planner's `test_strategy.platform` or grep for signal files:
|
|
27
|
+
|
|
28
|
+
| Signal | Stack |
|
|
29
|
+
|--------|-------|
|
|
30
|
+
| `next.config.ts` | Next.js (App Router) |
|
|
31
|
+
| `expo` in deps | React Native / Expo |
|
|
32
|
+
| `tauri.conf.json` | Tauri web view |
|
|
33
|
+
|
|
34
|
+
Load the matching reference doc from `reference/` (relative to this SKILL.md):
|
|
35
|
+
|
|
36
|
+
- Next.js / web: read `reference/semantic-html.md`, `reference/aria-roles-states.md`, `reference/keyboard-patterns.md`, `reference/contrast-visual.md`
|
|
37
|
+
- React Native: read `reference/aria-roles-states.md`, `reference/contrast-visual.md` (semantic HTML n/a for RN)
|
|
38
|
+
- Tauri web view: same as Next.js / web
|
|
39
|
+
|
|
40
|
+
## Phase 3: Load reference docs
|
|
41
|
+
|
|
42
|
+
For the detected stack, read EACH applicable reference doc in sequence. Do not skip — the pre-write checklist is derived from their combined content.
|
|
43
|
+
|
|
44
|
+
Reference docs (paths relative to this SKILL.md):
|
|
45
|
+
|
|
46
|
+
- `reference/semantic-html.md` — landmark roles, heading hierarchy, element semantics, anti-patterns
|
|
47
|
+
- `reference/aria-roles-states.md` — role table, aria-label vs aria-labelledby, live regions, expanded/pressed/hidden
|
|
48
|
+
- `reference/keyboard-patterns.md` — focus management, tab order, Esc, arrow keys, focus traps, type-ahead
|
|
49
|
+
- `reference/contrast-visual.md` — WCAG 2.1 AA ratios, focus-visible, colour-only state, reduced-motion, touch targets
|
|
50
|
+
|
|
51
|
+
## Phase 4: Commit to per-component obligations
|
|
52
|
+
|
|
53
|
+
For each component or element type in `wave.files[]`, derive explicit obligations from the reference docs. Group by component:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Component: <ComponentName> (<path>)
|
|
57
|
+
- Semantic: [e.g. "use <button> not <div onClick>"]
|
|
58
|
+
- ARIA: [e.g. "aria-expanded on disclosure trigger"]
|
|
59
|
+
- Keyboard: [e.g. "Esc closes; focus returns to trigger"]
|
|
60
|
+
- Contrast: [e.g. "border token needs 3:1 vs background — verify"]
|
|
61
|
+
- Touch: [e.g. "min 44x44px tap target on mobile"]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Unknown component types get the universal checklist from Phase 5.
|
|
65
|
+
|
|
66
|
+
## Phase 5: Universal guidelines (applied to every component)
|
|
67
|
+
|
|
68
|
+
Regardless of component type, every UI component must satisfy:
|
|
69
|
+
|
|
70
|
+
1. Every interactive element is keyboard-reachable and activatable (Enter/Space for buttons, Enter for links)
|
|
71
|
+
2. Focus-visible is never removed via `outline: none` without a custom indicator meeting 3:1 contrast
|
|
72
|
+
3. No state conveyed via colour alone — icon + text + colour
|
|
73
|
+
4. `prefers-reduced-motion` media query wraps any animation
|
|
74
|
+
5. Touch targets ≥ 44×44 CSS px
|
|
75
|
+
6. Images have `alt` text (decorative images use `alt=""`)
|
|
76
|
+
7. Form inputs have associated `<label htmlFor>` or `aria-label`
|
|
77
|
+
|
|
78
|
+
## Phase 6: Output pre-write checklist
|
|
79
|
+
|
|
80
|
+
Produce a flat checklist in `round.context.frontend_a11y_checklist`:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
frontend_a11y_checklist:
|
|
84
|
+
- component: "<ComponentName>"
|
|
85
|
+
file: "<path>"
|
|
86
|
+
items:
|
|
87
|
+
- "[Semantic] use <button> not <div onClick>"
|
|
88
|
+
- "[ARIA] aria-expanded on trigger; aria-controls referencing panel id"
|
|
89
|
+
- "[Keyboard] Esc closes panel; focus returns to trigger"
|
|
90
|
+
- "[Contrast] verify focus ring token meets 3:1 vs background"
|
|
91
|
+
- "[Touch] min 44x44px on mobile breakpoint"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The executor consults this checklist when authoring each component in Step 3.
|
|
95
|
+
|
|
96
|
+
## Output back to round-executor
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
round.context.frontend_a11y_loaded: true
|
|
100
|
+
round.context.frontend_a11y_checklist: [per-component checklist items]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Integration
|
|
104
|
+
|
|
105
|
+
- **Invoked by**: `round-executor` Step 2.6 (when `"frontend-a11y"` in `wave.skill_preloads[]`)
|
|
106
|
+
- **Reads**: `reference/semantic-html.md`, `reference/aria-roles-states.md`, `reference/keyboard-patterns.md`, `reference/contrast-visual.md`
|
|
107
|
+
- **Output consumed by**: `round-executor` Step 3 (implementation guidance)
|
|
108
|
+
- **Pairs with**: `frontend-design` (invoked first in Step 2.6), `frontend-ui` + `frontend-ux` (post-implementation Step 3.8)
|
|
109
|
+
- **Trigger rule**: `rules/frontend-accessibility-invocation.md`
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# ARIA Roles, States, and Properties Reference
|
|
2
|
+
|
|
3
|
+
**Golden rule**: Prefer native HTML semantics. ARIA fills gaps — it does not replace semantic elements. An `<input type="checkbox">` is always better than `<div role="checkbox">`.
|
|
4
|
+
|
|
5
|
+
## When to Add a Role
|
|
6
|
+
|
|
7
|
+
Use `role` ONLY when no native HTML element maps to the semantic need:
|
|
8
|
+
|
|
9
|
+
| Pattern | Native element | ARIA role (fallback) |
|
|
10
|
+
|---------|---------------|----------------------|
|
|
11
|
+
| Dialog / modal | — | `role="dialog"` + `aria-modal="true"` |
|
|
12
|
+
| Alerting status message | — | `role="status"` or `role="alert"` |
|
|
13
|
+
| Tab list | — | `role="tablist"`, `role="tab"`, `role="tabpanel"` |
|
|
14
|
+
| Custom listbox | — | `role="listbox"`, `role="option"` |
|
|
15
|
+
| Progress indicator | `<progress>` | `role="progressbar"` if `<progress>` unstyled |
|
|
16
|
+
| Tooltip | `title` attr (limited) | `role="tooltip"` + `aria-describedby` |
|
|
17
|
+
|
|
18
|
+
## aria-label vs aria-labelledby vs aria-describedby
|
|
19
|
+
|
|
20
|
+
| Attribute | Use when | Priority |
|
|
21
|
+
|-----------|----------|----------|
|
|
22
|
+
| `aria-labelledby` | A visible text element names this element | Highest — overrides aria-label and native label |
|
|
23
|
+
| `aria-label` | No visible text label exists (icon buttons, close buttons) | Medium |
|
|
24
|
+
| `aria-describedby` | Additional descriptive text supplements the label | Lowest — supplementary, not a primary name |
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
```jsx
|
|
28
|
+
// Icon button — no visible label
|
|
29
|
+
<button aria-label="Close dialog">
|
|
30
|
+
<Icon name="x" aria-hidden="true" />
|
|
31
|
+
</button>
|
|
32
|
+
|
|
33
|
+
// Element labelled by visible heading
|
|
34
|
+
<section aria-labelledby="billing-heading">
|
|
35
|
+
<h2 id="billing-heading">Billing</h2>
|
|
36
|
+
</section>
|
|
37
|
+
|
|
38
|
+
// Field with hint text
|
|
39
|
+
<input id="password" aria-describedby="password-hint" />
|
|
40
|
+
<span id="password-hint">Must be at least 8 characters</span>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Live Regions
|
|
44
|
+
|
|
45
|
+
Announce dynamic content changes to screen readers without moving focus.
|
|
46
|
+
|
|
47
|
+
| Role / Attribute | Urgency | Use for |
|
|
48
|
+
|-----------------|---------|---------|
|
|
49
|
+
| `aria-live="polite"` | Waits for user to be idle | Status messages, form validation summaries, search result counts |
|
|
50
|
+
| `aria-live="assertive"` | Interrupts immediately | Critical errors, session timeout warnings |
|
|
51
|
+
| `role="status"` | Same as `aria-live="polite"` | Status messages (shorthand) |
|
|
52
|
+
| `role="alert"` | Same as `aria-live="assertive"` | Error alerts (shorthand) |
|
|
53
|
+
|
|
54
|
+
Anti-pattern: using `role="alert"` for non-urgent messages — screen reader interruptions are disruptive. Reserve for true emergencies.
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
// Status (polite)
|
|
58
|
+
<div role="status" aria-live="polite">{statusMessage}</div>
|
|
59
|
+
|
|
60
|
+
// Error (assertive)
|
|
61
|
+
<div role="alert">{errorMessage}</div>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Common State Attributes
|
|
65
|
+
|
|
66
|
+
| Attribute | Values | Use for |
|
|
67
|
+
|-----------|--------|---------|
|
|
68
|
+
| `aria-expanded` | `true` / `false` | Disclosure triggers (accordion, dropdown, menu) |
|
|
69
|
+
| `aria-pressed` | `true` / `false` / `"mixed"` | Toggle buttons (bold, like, mute) |
|
|
70
|
+
| `aria-hidden` | `true` | Decorative elements, icon-only images — removes from accessibility tree |
|
|
71
|
+
| `aria-checked` | `true` / `false` / `"mixed"` | Custom checkbox/radio when not using `<input type="checkbox">` |
|
|
72
|
+
| `aria-disabled` | `true` | Visually disabled but still focusable (use sparingly) |
|
|
73
|
+
| `aria-selected` | `true` / `false` | Selected tab, selected option in listbox |
|
|
74
|
+
| `aria-current` | `"page"` / `"step"` / `true` | Current item in nav, current step in wizard |
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
// Accordion trigger
|
|
78
|
+
<button
|
|
79
|
+
aria-expanded={isOpen}
|
|
80
|
+
aria-controls="panel-1"
|
|
81
|
+
>
|
|
82
|
+
Section title
|
|
83
|
+
</button>
|
|
84
|
+
<div id="panel-1" hidden={!isOpen}>...</div>
|
|
85
|
+
|
|
86
|
+
// Toggle button
|
|
87
|
+
<button
|
|
88
|
+
aria-pressed={isBold}
|
|
89
|
+
onClick={() => setIsBold(!isBold)}
|
|
90
|
+
>
|
|
91
|
+
Bold
|
|
92
|
+
</button>
|
|
93
|
+
|
|
94
|
+
// Decorative icon
|
|
95
|
+
<svg aria-hidden="true" focusable="false">...</svg>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## aria-hidden Usage Rules
|
|
99
|
+
|
|
100
|
+
- `aria-hidden="true"` removes element and ALL descendants from accessibility tree
|
|
101
|
+
- Never place `aria-hidden="true"` on a focusable element (keyboard users still reach it)
|
|
102
|
+
- Common correct uses: decorative icons, background images, duplicate visible text (when the accessible name comes from aria-label)
|
|
103
|
+
|
|
104
|
+
```jsx
|
|
105
|
+
// Correct: icon inside labelled button
|
|
106
|
+
<button aria-label="Delete">
|
|
107
|
+
<TrashIcon aria-hidden="true" />
|
|
108
|
+
</button>
|
|
109
|
+
|
|
110
|
+
// Wrong: aria-hidden on focusable element
|
|
111
|
+
<button aria-hidden="true">...</button> // users can still Tab to it
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Dialog Pattern
|
|
115
|
+
|
|
116
|
+
```jsx
|
|
117
|
+
<dialog
|
|
118
|
+
role="dialog"
|
|
119
|
+
aria-modal="true"
|
|
120
|
+
aria-labelledby="dialog-title"
|
|
121
|
+
aria-describedby="dialog-description"
|
|
122
|
+
>
|
|
123
|
+
<h2 id="dialog-title">Confirm deletion</h2>
|
|
124
|
+
<p id="dialog-description">This action cannot be undone.</p>
|
|
125
|
+
<button onClick={onConfirm}>Delete</button>
|
|
126
|
+
<button onClick={onClose}>Cancel</button>
|
|
127
|
+
</dialog>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Focus must move INTO the dialog on open and RETURN to the trigger on close. See `keyboard-patterns.md` for focus trap implementation.
|