diff --git a/CLAUDE.md b/CLAUDE.md index 0ec53ec6..5dfd1aff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -69,7 +69,7 @@ devflow/ ```bash # 1. Edit source files vim plugins/devflow-code-review/commands/code-review.md # Commands/agents in plugins -vim shared/skills/security-patterns/SKILL.md # Skills in shared/ +vim shared/skills/security/SKILL.md # Skills in shared/ # 2. Build (compiles CLI + distributes skills/agents to plugins) npm run build diff --git a/README.md b/README.md index be727e13..b3e4ce2f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Claude Code is powerful. DevFlow makes it extraordinary. -**18 parallel code reviewers.** Not a linter. Not a single-pass review. DevFlow deploys up to 18 specialized reviewers simultaneously: security, architecture, performance, complexity, consistency, regression, tests, plus conditional reviewers for TypeScript, React, accessibility, Go, Python, Java, Rust, database, dependencies, and documentation. Each reviewer has domain-specific expertise. Findings include confidence scores, and false positives are tracked and penalized. +**18 parallel code reviewers.** Not a linter. Not a single-pass review. DevFlow deploys up to 18 specialized reviewers simultaneously: security, architecture, performance, complexity, consistency, regression, testing, plus conditional reviewers for TypeScript, React, accessibility, Go, Python, Java, Rust, database, dependencies, and documentation. Each reviewer has domain-specific expertise. Findings include confidence scores, and false positives are tracked and penalized. **Working memory that never forgets.** Three shell hooks preserve session context across restarts, `/clear`, and context compaction. Zero ceremony. Your AI remembers what it was doing, what decisions were made, and what files were modified. Every session picks up exactly where the last one left off. @@ -28,7 +28,7 @@ Claude Code is powerful. DevFlow makes it extraordinary. ## Features -- **18 parallel code reviewers** with security, architecture, performance, complexity, consistency, regression, tests, plus conditional language and framework reviewers +- **18 parallel code reviewers** with security, architecture, performance, complexity, consistency, regression, testing, plus conditional language and framework reviewers - **Working memory** that survives restarts, `/clear`, and context compaction. Zero ceremony. - **Self-learning** that detects repeated workflows and auto-creates slash commands and skills - **Long-term project knowledge** with architectural decisions and known pitfalls that persist and inform reviews @@ -124,14 +124,12 @@ The `devflow-core-skills` plugin provides quality enforcement skills that activa | Skill | Triggers When | |-------|---------------| -| `core-patterns` | Implementing business logic, error handling | +| `software-design` | Implementing business logic, error handling | | `docs-framework` | Creating documentation artifacts in .docs/ | -| `git-safety` | Rebasing, force-pushing, merge conflicts | -| `git-workflow` | Staging files, creating commits, PRs | -| `github-patterns` | GitHub API operations, PR comments, releases | +| `git` | Git operations, commits, PRs, GitHub API | | `test-driven-development` | Implementing new features (RED-GREEN-REFACTOR) | -| `test-patterns` | Writing or modifying tests | -| `input-validation` | Creating API endpoints | +| `testing` | Writing or modifying tests | +| `boundary-validation` | Creating API endpoints | | `search-first` | Adding utilities, helpers, or infrastructure code | ## Language & Ecosystem Plugins @@ -143,7 +141,7 @@ Optional plugins for language-specific patterns. Install only what you need: | `devflow-typescript` | `typescript` | Working in TypeScript codebases | | `devflow-react` | `react` | Working with React components | | `devflow-accessibility` | `accessibility` | Creating UI components, forms | -| `devflow-frontend-design` | `frontend-design` | Working with CSS, styling | +| `devflow-frontend-design` | `ui-design` | Working with CSS, styling | | `devflow-go` | `go` | Working in Go codebases | | `devflow-python` | `python` | Working in Python codebases | | `devflow-java` | `java` | Working in Java codebases | @@ -315,16 +313,16 @@ Override any DevFlow skill with your own version. Shadowed skills survive `devfl ```bash # Create a personal override (copies current version as reference) -npx devflow-kit skills shadow core-patterns +npx devflow-kit skills shadow software-design # Edit your override -vim ~/.devflow/skills/core-patterns/SKILL.md +vim ~/.devflow/skills/software-design/SKILL.md # List all overrides npx devflow-kit skills list-shadowed # Remove override (next init restores DevFlow's version) -npx devflow-kit skills unshadow core-patterns +npx devflow-kit skills unshadow software-design ``` ### Uninstall Options diff --git a/docs/reference/file-organization.md b/docs/reference/file-organization.md index 491202d9..e98fc9ba 100644 --- a/docs/reference/file-organization.md +++ b/docs/reference/file-organization.md @@ -9,11 +9,11 @@ devflow/ ├── .claude-plugin/ # Marketplace registry (repo root) │ └── marketplace.json ├── shared/ -│ ├── skills/ # SINGLE SOURCE OF TRUTH (31 skills) -│ │ ├── git-workflow/ +│ ├── skills/ # SINGLE SOURCE OF TRUTH (37 skills) +│ │ ├── git/ │ │ │ ├── SKILL.md │ │ │ └── references/ -│ │ ├── core-patterns/ +│ │ ├── software-design/ │ │ └── ... │ └── agents/ # SINGLE SOURCE OF TRUTH (10 shared agents) │ ├── git.md diff --git a/docs/reference/skills-architecture.md b/docs/reference/skills-architecture.md index 13eb2ebd..bc31adb5 100644 --- a/docs/reference/skills-architecture.md +++ b/docs/reference/skills-architecture.md @@ -12,13 +12,11 @@ Shared patterns used by multiple agents. | Skill | Purpose | Used By | |-------|---------|---------| -| `core-patterns` | Engineering patterns (Result types, DI, immutability, workaround labeling) | Coder, Scrutinizer, Resolver, Shepherd | +| `software-design` | Engineering patterns (Result types, DI, immutability, workaround labeling) | Coder, Scrutinizer, Resolver, Shepherd | | `review-methodology` | 6-step review process, 3-category issue classification | Reviewer, Synthesizer | | `self-review` | 9-pillar self-review framework | Scrutinizer | | `docs-framework` | Documentation conventions (.docs/ structure, naming, templates) | Synthesizer | -| `git-safety` | Git operations, lock handling, sequential ops | Coder, Git, Resolver | -| `git-workflow` | Atomic commits, message format, PR descriptions, size assessment | Coder, Git, Resolver | -| `github-patterns` | GitHub API patterns (rate limiting, PR comments, issues, releases) | Git | +| `git` | Git safety, atomic commits, PR descriptions, GitHub API patterns | Coder, Git, Resolver | | `implementation-patterns` | CRUD, API endpoints, events, config, logging | Coder, Resolver | | `agent-teams` | Agent Teams patterns for peer-to-peer collaboration, debate, consensus | /code-review, /implement, /debug | | `ambient-router` | Intent classification and proportional skill loading for ambient mode (unrestricted tools — orchestrator) | Ambient UserPromptSubmit hook | @@ -30,16 +28,16 @@ Domain expertise for Reviewer agent focus areas. Loaded dynamically based on rev | Skill | Purpose | Reviewer Focus | |-------|---------|----------------| -| `security-patterns` | Injection, auth, crypto, OWASP vulnerabilities | `security` | -| `architecture-patterns` | SOLID violations, coupling, layering, modularity | `architecture` | -| `performance-patterns` | Algorithms, N+1, memory, I/O, caching | `performance` | -| `complexity-patterns` | Cyclomatic complexity, readability, maintainability | `complexity` | -| `consistency-patterns` | Pattern violations, simplification, truncation | `consistency` | -| `test-patterns` | Coverage, quality, brittle tests, mocking, test design | `tests` | -| `database-patterns` | Schema, queries, migrations, indexes | `database` | -| `documentation-patterns` | Docs quality, alignment, code-comment drift | `documentation` | -| `dependencies-patterns` | CVEs, versions, licenses, supply chain | `dependencies` | -| `regression-patterns` | Lost functionality, broken behavior, migrations | `regression` | +| `security` | Injection, auth, crypto, OWASP vulnerabilities | `security` | +| `architecture` | SOLID violations, coupling, layering, modularity | `architecture` | +| `performance` | Algorithms, N+1, memory, I/O, caching | `performance` | +| `complexity` | Cyclomatic complexity, readability, maintainability | `complexity` | +| `consistency` | Pattern violations, simplification, truncation | `consistency` | +| `testing` | Coverage, quality, brittle tests, mocking, test design | `testing` | +| `database` | Schema, queries, migrations, indexes | `database` | +| `documentation` | Docs quality, alignment, code-comment drift | `documentation` | +| `dependencies` | CVEs, versions, licenses, supply chain | `dependencies` | +| `regression` | Lost functionality, broken behavior, migrations | `regression` | ### Tier 2: Specialized Skills @@ -47,7 +45,7 @@ Listed in Claude Code's skill catalog. May auto-invoke based on description matc | Skill | Purpose | Agent Refs | |-------|---------|------------| -| `input-validation` | Boundary validation enforcement | Coder | +| `boundary-validation` | Boundary validation enforcement | Coder | | `search-first` | Research-before-building enforcement for utility code | Coder | | `test-driven-development` | RED-GREEN-REFACTOR cycle enforcement | Coder | @@ -60,7 +58,7 @@ Language and framework patterns. Referenced by agents via frontmatter and condit | `typescript` | Type safety, generics, utility types, type guards | TypeScript codebases | | `react` | Components, hooks, state management, performance | React codebases | | `accessibility` | Keyboard, ARIA, focus, color contrast | Frontend codebases | -| `frontend-design` | Typography, color, spacing, visual design | Frontend codebases | +| `ui-design` | Typography, color, spacing, visual design | Frontend codebases | | `go` | Error handling, interfaces, concurrency, package design | Go codebases | | `python` | Type hints, protocols, dataclasses, async patterns | Python codebases | | `java` | Records, sealed classes, composition, modern Java | Java codebases | @@ -71,7 +69,7 @@ Language and framework patterns. Referenced by agents via frontmatter and condit Skills activate through two guaranteed mechanisms: 1. **Agent frontmatter `skills:` field** — When an agent runs, all skills listed in its frontmatter are loaded into context. This is the primary activation path. -2. **Reviewer dynamic read** — The Reviewer agent reads the pattern skill file for its assigned focus area from a lookup table (e.g., `focus=tests` → `test-patterns/SKILL.md`). +2. **Reviewer dynamic read** — The Reviewer agent reads the pattern skill file for its assigned focus area from a lookup table (e.g., `focus=testing` → `testing/SKILL.md`). Skills with `user-invocable: false` also appear in Claude Code's skill catalog with their description. Claude MAY auto-invoke them based on description matching, but this is not guaranteed and should not be relied upon as the sole activation path. @@ -82,7 +80,7 @@ The `activation: file-patterns` frontmatter is metadata for documentation purpos ```yaml --- name: Coder -skills: core-patterns, git-safety, implementation-patterns, git-workflow, ... +skills: software-design, git, implementation-patterns, ... --- ``` @@ -209,12 +207,12 @@ activation: | `react` | `**/*.tsx`, `**/*.jsx` | `node_modules/**`, `**/*.test.*` | | `typescript` | `**/*.ts`, `**/*.tsx` | `node_modules/**`, `**/*.d.ts` | | `accessibility` | `**/*.tsx`, `**/*.jsx`, `**/*.css` | `node_modules/**` | -| `frontend-design` | `**/*.tsx`, `**/*.jsx`, `**/*.css`, `**/*.scss` | `node_modules/**` | +| `ui-design` | `**/*.tsx`, `**/*.jsx`, `**/*.css`, `**/*.scss` | `node_modules/**` | | `go` | `**/*.go` | `vendor/**` | | `python` | `**/*.py` | `venv/**`, `.venv/**`, `**/__pycache__/**` | | `java` | `**/*.java` | `**/build/**`, `**/target/**` | | `rust` | `**/*.rs` | `**/target/**` | -| `test-patterns` | `**/*.test.*`, `**/*.spec.*`, `**/test/**` | `node_modules/**` | +| `testing` | `**/*.test.*`, `**/*.spec.*`, `**/test/**` | `node_modules/**` | **Note:** Glob patterns are metadata hints for documentation. Claude Code does not currently read glob patterns to trigger skills — activation happens through agent frontmatter and Reviewer dynamic read (see "How Skills Activate" above). diff --git a/plugins/devflow-ambient/.claude-plugin/plugin.json b/plugins/devflow-ambient/.claude-plugin/plugin.json index 452719d5..333810c9 100644 --- a/plugins/devflow-ambient/.claude-plugin/plugin.json +++ b/plugins/devflow-ambient/.claude-plugin/plugin.json @@ -36,16 +36,16 @@ "resolve-orchestration", "pipeline-orchestration", "review-methodology", - "security-patterns", - "architecture-patterns", - "performance-patterns", - "complexity-patterns", - "consistency-patterns", - "regression-patterns", - "test-patterns", - "database-patterns", - "dependencies-patterns", - "documentation-patterns", + "security", + "architecture", + "performance", + "complexity", + "consistency", + "regression", + "testing", + "database", + "dependencies", + "documentation", "implementation-patterns", "knowledge-persistence", "worktree-support" diff --git a/plugins/devflow-ambient/README.md b/plugins/devflow-ambient/README.md index 5aed4a47..6abe3d52 100644 --- a/plugins/devflow-ambient/README.md +++ b/plugins/devflow-ambient/README.md @@ -45,9 +45,9 @@ Skills are loaded via the Skill tool and work happens in the main session: | Intent | Skills | Main Session Work | Post-Work | |--------|--------|-------------------|-----------| | IMPLEMENT | test-driven-development, implementation-patterns, search-first | Implement with TDD | `Task(subagent_type="Simplifier")` | -| DEBUG | core-patterns, test-patterns | Investigate, diagnose, fix | `Task(subagent_type="Simplifier")` | -| PLAN | implementation-patterns, core-patterns | Explore and design | — | -| REVIEW | self-review, core-patterns | Review directly | — | +| DEBUG | software-design, testing | Investigate, diagnose, fix | `Task(subagent_type="Simplifier")` | +| PLAN | implementation-patterns, software-design | Explore and design | — | +| REVIEW | self-review, software-design | Review directly | — | ## ORCHESTRATED Pipelines diff --git a/plugins/devflow-code-review/.claude-plugin/plugin.json b/plugins/devflow-code-review/.claude-plugin/plugin.json index f7a43865..09daeab2 100644 --- a/plugins/devflow-code-review/.claude-plugin/plugin.json +++ b/plugins/devflow-code-review/.claude-plugin/plugin.json @@ -22,18 +22,18 @@ ], "skills": [ "agent-teams", - "architecture-patterns", - "complexity-patterns", - "consistency-patterns", - "database-patterns", - "dependencies-patterns", - "documentation-patterns", + "architecture", + "complexity", + "consistency", + "database", + "dependencies", + "documentation", "knowledge-persistence", - "performance-patterns", - "regression-patterns", + "performance", + "regression", "review-methodology", - "security-patterns", - "test-patterns", + "security", + "testing", "worktree-support" ] } diff --git a/plugins/devflow-code-review/README.md b/plugins/devflow-code-review/README.md index d7730e54..4093fd16 100644 --- a/plugins/devflow-code-review/README.md +++ b/plugins/devflow-code-review/README.md @@ -32,7 +32,7 @@ The plugin spawns 7-11 parallel Reviewer agents, each with a specific focus: | complexity | Cyclomatic complexity, readability | | consistency | Pattern violations, style drift | | regression | Lost functionality, broken behavior | -| tests | Coverage gaps, brittle tests | +| testing | Coverage gaps, brittle tests | | database | Schema issues, slow queries | | dependencies | CVEs, outdated packages | | documentation | Doc drift, stale comments | @@ -49,16 +49,16 @@ The plugin spawns 7-11 parallel Reviewer agents, each with a specific focus: ### Skills (11) - `review-methodology` - 6-step review process -- `security-patterns` - Security vulnerabilities -- `architecture-patterns` - Design patterns -- `performance-patterns` - Performance issues -- `complexity-patterns` - Complexity metrics -- `consistency-patterns` - Pattern violations -- `regression-patterns` - Regression detection -- `test-patterns` - Test quality -- `database-patterns` - Database issues -- `dependencies-patterns` - Dependency management -- `documentation-patterns` - Documentation quality +- `security` - Security vulnerabilities +- `architecture` - Design patterns +- `performance` - Performance issues +- `complexity` - Complexity metrics +- `consistency` - Pattern violations +- `regression` - Regression detection +- `testing` - Test quality +- `database` - Database issues +- `dependencies` - Dependency management +- `documentation` - Documentation quality ## Output diff --git a/plugins/devflow-code-review/commands/code-review-teams.md b/plugins/devflow-code-review/commands/code-review-teams.md index 786cc298..44d78045 100644 --- a/plugins/devflow-code-review/commands/code-review-teams.md +++ b/plugins/devflow-code-review/commands/code-review-teams.md @@ -71,7 +71,7 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio | Any .ts or .tsx files | typescript | | .tsx or .jsx files (React components) | react | | .tsx or .jsx files (React components) | accessibility | -| .tsx/.jsx/.css/.scss files | frontend-design | +| .tsx/.jsx/.css/.scss files | ui-design | | .go files | go | | .java files | java | | .py files | python | @@ -80,7 +80,7 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio | Dependency files changed | dependencies | | Docs or significant code | documentation | -**Skill availability check**: Language/ecosystem reviews (typescript, react, accessibility, frontend-design, go, java, python, rust) require their optional skill plugin to be installed. Before adding a conditional perspective, use Read to check if `~/.claude/skills/devflow:{focus}/SKILL.md` exists. If Read returns an error (file not found), **skip that perspective** — the language plugin isn't installed. Non-language reviews (database, dependencies, documentation) use skills bundled with this plugin and are always available. +**Skill availability check**: Language/ecosystem reviews (typescript, react, accessibility, ui-design, go, java, python, rust) require their optional skill plugin to be installed. Before adding a conditional perspective, use Read to check if `~/.claude/skills/devflow:{focus}/SKILL.md` exists. If Read returns an error (file not found), **skip that perspective** — the language plugin isn't installed. Non-language reviews (database, dependencies, documentation) use skills bundled with this plugin and are always available. ### Phase 2: Spawn Review Team @@ -92,7 +92,7 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio - **Security**: vulnerabilities, injection, auth, crypto issues - **Architecture**: SOLID violations, coupling, layering, modularity - **Performance**: queries, algorithms, caching, I/O bottlenecks -- **Quality**: complexity, tests, consistency, regression, naming +- **Quality**: complexity, testing, consistency, regression, naming **Conditional perspectives (based on changed files):** - **TypeScript**: type safety, generics, utility types (if .ts/.tsx changed) @@ -116,7 +116,7 @@ Spawn review teammates with self-contained prompts: Prompt: | You are reviewing PR #{pr_number} on branch {branch} (base: {base_branch}). WORKTREE_PATH: {worktree_path} (omit if cwd) - 1. Read your skill: `Read ~/.claude/skills/devflow:security-patterns/SKILL.md` + 1. Read your skill: `Read ~/.claude/skills/devflow:security/SKILL.md` 2. Read review methodology: `Read ~/.claude/skills/devflow:review-methodology/SKILL.md` 3. Read `.memory/knowledge/pitfalls.md` if it exists. Check for known pitfall patterns in the diff. 4. Get the diff: `git -C {WORKTREE_PATH} diff {DIFF_RANGE}` @@ -131,7 +131,7 @@ Spawn review teammates with self-contained prompts: Prompt: | You are reviewing PR #{pr_number} on branch {branch} (base: {base_branch}). WORKTREE_PATH: {worktree_path} (omit if cwd) - 1. Read your skill: `Read ~/.claude/skills/devflow:architecture-patterns/SKILL.md` + 1. Read your skill: `Read ~/.claude/skills/devflow:architecture/SKILL.md` 2. Read review methodology: `Read ~/.claude/skills/devflow:review-methodology/SKILL.md` 3. Read `.memory/knowledge/pitfalls.md` if it exists. Check for known pitfall patterns in the diff. 4. Get the diff: `git -C {WORKTREE_PATH} diff {DIFF_RANGE}` @@ -146,7 +146,7 @@ Spawn review teammates with self-contained prompts: Prompt: | You are reviewing PR #{pr_number} on branch {branch} (base: {base_branch}). WORKTREE_PATH: {worktree_path} (omit if cwd) - 1. Read your skill: `Read ~/.claude/skills/devflow:performance-patterns/SKILL.md` + 1. Read your skill: `Read ~/.claude/skills/devflow:performance/SKILL.md` 2. Read review methodology: `Read ~/.claude/skills/devflow:review-methodology/SKILL.md` 3. Read `.memory/knowledge/pitfalls.md` if it exists. Check for known pitfall patterns in the diff. 4. Get the diff: `git -C {WORKTREE_PATH} diff {DIFF_RANGE}` @@ -162,10 +162,10 @@ Spawn review teammates with self-contained prompts: You are reviewing PR #{pr_number} on branch {branch} (base: {base_branch}). WORKTREE_PATH: {worktree_path} (omit if cwd) 1. Read your skills: - - `Read ~/.claude/skills/devflow:complexity-patterns/SKILL.md` - - `Read ~/.claude/skills/devflow:consistency-patterns/SKILL.md` - - `Read ~/.claude/skills/devflow:test-patterns/SKILL.md` - - `Read ~/.claude/skills/devflow:regression-patterns/SKILL.md` + - `Read ~/.claude/skills/devflow:complexity/SKILL.md` + - `Read ~/.claude/skills/devflow:consistency/SKILL.md` + - `Read ~/.claude/skills/devflow:testing/SKILL.md` + - `Read ~/.claude/skills/devflow:regression/SKILL.md` 2. Read review methodology: `Read ~/.claude/skills/devflow:review-methodology/SKILL.md` 3. Read `.memory/knowledge/pitfalls.md` if it exists. Check for known pitfall patterns in the diff. 4. Get the diff: `git -C {WORKTREE_PATH} diff {DIFF_RANGE}` diff --git a/plugins/devflow-code-review/commands/code-review.md b/plugins/devflow-code-review/commands/code-review.md index 1c8a774c..990c8986 100644 --- a/plugins/devflow-code-review/commands/code-review.md +++ b/plugins/devflow-code-review/commands/code-review.md @@ -71,7 +71,7 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio | Any .ts or .tsx files | typescript | | .tsx or .jsx files (React components) | react | | .tsx or .jsx files (React components) | accessibility | -| .tsx/.jsx/.css/.scss files | frontend-design | +| .tsx/.jsx/.css/.scss files | ui-design | | .go files | go | | .java files | java | | .py files | python | @@ -80,7 +80,7 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio | Dependency files changed | dependencies | | Docs or significant code | documentation | -**Skill availability check**: Language/ecosystem reviews (typescript, react, accessibility, frontend-design, go, java, python, rust) require their optional skill plugin to be installed. Before spawning a conditional Reviewer for these focuses, use Read to check if `~/.claude/skills/devflow:{focus}/SKILL.md` exists. If Read returns an error (file not found), **skip that review** — the language plugin isn't installed. Non-language reviews (database, dependencies, documentation) use skills bundled with this plugin and are always available. +**Skill availability check**: Language/ecosystem reviews (typescript, react, accessibility, ui-design, go, java, python, rust) require their optional skill plugin to be installed. Before spawning a conditional Reviewer for these focuses, use Read to check if `~/.claude/skills/devflow:{focus}/SKILL.md` exists. If Read returns an error (file not found), **skip that review** — the language plugin isn't installed. Non-language reviews (database, dependencies, documentation) use skills bundled with this plugin and are always available. ### Phase 2: Run Reviews (Parallel) @@ -88,29 +88,29 @@ Spawn Reviewer agents **in a single message**. Always run 7 core reviews; condit | Focus | Always | Pattern Skill | |-------|--------|---------------| -| security | ✓ | devflow:security-patterns | -| architecture | ✓ | devflow:architecture-patterns | -| performance | ✓ | devflow:performance-patterns | -| complexity | ✓ | devflow:complexity-patterns | -| consistency | ✓ | devflow:consistency-patterns | -| regression | ✓ | devflow:regression-patterns | -| tests | ✓ | devflow:test-patterns | +| security | ✓ | devflow:security | +| architecture | ✓ | devflow:architecture | +| performance | ✓ | devflow:performance | +| complexity | ✓ | devflow:complexity | +| consistency | ✓ | devflow:consistency | +| regression | ✓ | devflow:regression | +| testing | ✓ | devflow:testing | | typescript | conditional | devflow:typescript | | react | conditional | devflow:react | | accessibility | conditional | devflow:accessibility | -| frontend-design | conditional | devflow:frontend-design | +| ui-design | conditional | devflow:ui-design | | go | conditional | devflow:go | | java | conditional | devflow:java | | python | conditional | devflow:python | | rust | conditional | devflow:rust | -| database | conditional | devflow:database-patterns | -| dependencies | conditional | devflow:dependencies-patterns | -| documentation | conditional | devflow:documentation-patterns | +| database | conditional | devflow:database | +| dependencies | conditional | devflow:dependencies | +| documentation | conditional | devflow:documentation | Each Reviewer invocation (all in one message, **NOT background**): ``` Task(subagent_type="Reviewer", run_in_background=false): -"Review focusing on {focus}. Apply devflow:{focus}-patterns. +"Review focusing on {focus}. Load the pattern skill for your focus from the Focus Areas table. Follow 6-step process from devflow:review-methodology. PR: #{pr_number}, Base: {base_branch} WORKTREE_PATH: {worktree_path} (omit if cwd) @@ -190,7 +190,7 @@ Per worktree, if the review summary contains CRITICAL or HIGH blocking issues: │ ├─ Phase 2: Reviews (PARALLEL within worktree) │ │ ├─ Reviewer: security │ │ ├─ Reviewer: architecture, performance, complexity -│ │ ├─ Reviewer: consistency, regression, tests +│ │ ├─ Reviewer: consistency, regression, testing │ │ └─ Reviewer: [conditional] │ │ │ ├─ Phase 3: Synthesis (PARALLEL within worktree) diff --git a/plugins/devflow-core-skills/.claude-plugin/plugin.json b/plugins/devflow-core-skills/.claude-plugin/plugin.json index 27782314..00889a90 100644 --- a/plugins/devflow-core-skills/.claude-plugin/plugin.json +++ b/plugins/devflow-core-skills/.claude-plugin/plugin.json @@ -18,14 +18,12 @@ ], "agents": [], "skills": [ - "core-patterns", + "software-design", "docs-framework", - "git-safety", - "git-workflow", - "github-patterns", - "input-validation", + "git", + "boundary-validation", "search-first", "test-driven-development", - "test-patterns" + "testing" ] } diff --git a/plugins/devflow-core-skills/README.md b/plugins/devflow-core-skills/README.md index 91dfb40d..629cd979 100644 --- a/plugins/devflow-core-skills/README.md +++ b/plugins/devflow-core-skills/README.md @@ -16,10 +16,10 @@ npx devflow-kit init --plugin=core-skills | Skill | Auto-Triggers When | What It Enforces | |-------|-------------------|------------------| -| `core-patterns` | Business logic, error handling | Result types, DI, immutability, workaround labeling | -| `git-workflow` | Staging files, creating commits, PRs | Atomic commits, message format, PR descriptions | -| `test-patterns` | Tests written or modified | Test quality, setup complexity, behavior testing, coverage | -| `input-validation` | API endpoints, external data handling | Boundary validation, parse-don't-validate | +| `software-design` | Business logic, error handling | Result types, DI, immutability, workaround labeling | +| `git` | Git operations, commits, PRs, GitHub API | Sequential ops, atomic commits, PR descriptions, rate limiting | +| `testing` | Tests written or modified | Test quality, setup complexity, behavior testing, coverage | +| `boundary-validation` | API endpoints, external data handling | Boundary validation, parse-don't-validate | | `typescript` | TypeScript codebases | Type safety, generics, utility types | | `react` | React codebases | Components, hooks, state management | @@ -33,10 +33,10 @@ Each skill enforces a non-negotiable principle: | Skill | Iron Law | |-------|----------| -| `core-patterns` | NEVER THROW IN BUSINESS LOGIC | -| `git-workflow` | ATOMIC COMMITS WITH HONEST DESCRIPTIONS | -| `test-patterns` | TESTS VALIDATE BEHAVIOR, NOT IMPLEMENTATION | -| `input-validation` | ALL EXTERNAL DATA IS HOSTILE | +| `software-design` | NEVER THROW IN BUSINESS LOGIC | +| `git` | EVERY COMMIT TELLS AN HONEST, ATOMIC STORY | +| `testing` | TESTS VALIDATE BEHAVIOR, NOT IMPLEMENTATION | +| `boundary-validation` | ALL EXTERNAL DATA IS HOSTILE | | `typescript` | UNKNOWN OVER ANY | | `react` | COMPOSITION OVER PROPS | diff --git a/plugins/devflow-debug/.claude-plugin/plugin.json b/plugins/devflow-debug/.claude-plugin/plugin.json index bcbe0c96..b7fdd650 100644 --- a/plugins/devflow-debug/.claude-plugin/plugin.json +++ b/plugins/devflow-debug/.claude-plugin/plugin.json @@ -20,7 +20,7 @@ ], "skills": [ "agent-teams", - "git-safety", + "git", "knowledge-persistence", "worktree-support" ] diff --git a/plugins/devflow-debug/README.md b/plugins/devflow-debug/README.md index 10997e23..09ecf33e 100644 --- a/plugins/devflow-debug/README.md +++ b/plugins/devflow-debug/README.md @@ -42,7 +42,7 @@ Requires Agent Teams feature: ### Skills - `agent-teams` - Team coordination patterns -- `git-safety` - Safe git operations +- `git` - Git safety, commits, GitHub API ## Output diff --git a/plugins/devflow-frontend-design/.claude-plugin/plugin.json b/plugins/devflow-frontend-design/.claude-plugin/plugin.json index 1a24ff8f..2d584269 100644 --- a/plugins/devflow-frontend-design/.claude-plugin/plugin.json +++ b/plugins/devflow-frontend-design/.claude-plugin/plugin.json @@ -16,6 +16,6 @@ ], "agents": [], "skills": [ - "frontend-design" + "ui-design" ] } diff --git a/plugins/devflow-implement/README.md b/plugins/devflow-implement/README.md index 7ef4eb8f..624715a8 100644 --- a/plugins/devflow-implement/README.md +++ b/plugins/devflow-implement/README.md @@ -46,13 +46,12 @@ npx devflow-kit init --plugin=implement - `shepherd` - Alignment validation - `validator` - Build/test validation -### Skills (10) -- `core-patterns` - Result types, DI, immutability, workaround labeling -- `git-safety` - Safe git operations -- `git-workflow` - Atomic commits, PR descriptions +### Skills (9) +- `software-design` - Result types, DI, immutability, workaround labeling +- `git` - Git safety, atomic commits, PR descriptions - `implementation-patterns` - CRUD, API, events -- `test-patterns` - Test quality, coverage -- `input-validation` - Boundary validation +- `testing` - Test quality, coverage +- `boundary-validation` - Boundary validation - `self-review` - 9-pillar framework - `typescript` - TypeScript patterns - `react` - React patterns diff --git a/plugins/devflow-implement/commands/implement-teams.md b/plugins/devflow-implement/commands/implement-teams.md index bbd9aea9..c8fe4679 100644 --- a/plugins/devflow-implement/commands/implement-teams.md +++ b/plugins/devflow-implement/commands/implement-teams.md @@ -186,7 +186,7 @@ Spawn planning teammates with self-contained prompts: - Name: "testing-planner" Prompt: | You are planning the test strategy for task: {task description} - 1. Read your skill: `Read ~/.claude/skills/devflow:test-patterns/SKILL.md` + 1. Read your skill: `Read ~/.claude/skills/devflow:testing/SKILL.md` 2. Exploration synthesis (what we know about the codebase): {synthesis output from Phase 4} 3. Your deliverable: Test strategy — unit tests, integration tests, @@ -523,7 +523,7 @@ Step 3: GATE — Verify TeamDelete succeeded ### Phase 13: Create PR -**For SEQUENTIAL_CODERS or PARALLEL_CODERS**: The last sequential Coder (with CREATE_PR: true) handles PR creation. For parallel coders, create unified PR using `devflow:git-workflow` skill patterns. Push branch and run `gh pr create` with comprehensive description, targeting `BASE_BRANCH`. +**For SEQUENTIAL_CODERS or PARALLEL_CODERS**: The last sequential Coder (with CREATE_PR: true) handles PR creation. For parallel coders, create unified PR using `devflow:git` skill patterns. Push branch and run `gh pr create` with comprehensive description, targeting `BASE_BRANCH`. **For SINGLE_CODER**: PR is created by the Coder agent (CREATE_PR: true). diff --git a/plugins/devflow-implement/commands/implement.md b/plugins/devflow-implement/commands/implement.md index f3784c84..d5d2b8e1 100644 --- a/plugins/devflow-implement/commands/implement.md +++ b/plugins/devflow-implement/commands/implement.md @@ -336,7 +336,7 @@ Validate alignment with request and plan. Report ALIGNED or MISALIGNED with deta ### Phase 13: Create PR -**For SEQUENTIAL_CODERS or PARALLEL_CODERS**: The last sequential Coder (with CREATE_PR: true) handles PR creation. For parallel coders, create unified PR using `devflow:git-workflow` skill patterns. Push branch and run `gh pr create` with comprehensive description, targeting `BASE_BRANCH`. +**For SEQUENTIAL_CODERS or PARALLEL_CODERS**: The last sequential Coder (with CREATE_PR: true) handles PR creation. For parallel coders, create unified PR using `devflow:git` skill patterns. Push branch and run `gh pr create` with comprehensive description, targeting `BASE_BRANCH`. **For SINGLE_CODER**: PR is created by the Coder agent (CREATE_PR: true). diff --git a/plugins/devflow-resolve/.claude-plugin/plugin.json b/plugins/devflow-resolve/.claude-plugin/plugin.json index b48be477..94a274f8 100644 --- a/plugins/devflow-resolve/.claude-plugin/plugin.json +++ b/plugins/devflow-resolve/.claude-plugin/plugin.json @@ -24,7 +24,7 @@ "agent-teams", "implementation-patterns", "knowledge-persistence", - "security-patterns", + "security", "worktree-support" ] } diff --git a/plugins/devflow-resolve/README.md b/plugins/devflow-resolve/README.md index 481498d2..2d3138fe 100644 --- a/plugins/devflow-resolve/README.md +++ b/plugins/devflow-resolve/README.md @@ -46,12 +46,11 @@ npx devflow-kit init --plugin=resolve - `resolver` - Validates and implements fixes - `simplifier` - Code refinement after fixes -### Skills (5) -- `core-patterns` - Result types, DI -- `git-safety` - Safe git operations -- `commit` - Atomic commit patterns +### Skills (4) +- `software-design` - Result types, DI +- `git` - Git safety, atomic commits, GitHub API - `implementation-patterns` - Implementation guidance -- `security-patterns` - Security fix patterns +- `security` - Security fix patterns ## Output diff --git a/plugins/devflow-resolve/skills/security-patterns/SKILL.md b/plugins/devflow-resolve/skills/security-patterns/SKILL.md deleted file mode 100644 index da1f7c0e..00000000 --- a/plugins/devflow-resolve/skills/security-patterns/SKILL.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -name: security-patterns -description: This skill should be used when reviewing code for injection flaws, auth bypasses, or hardcoded secrets. -user-invocable: false -allowed-tools: Read, Grep, Glob ---- - -# Security Patterns - -Domain expertise for security vulnerability detection. Use alongside `devflow:review-methodology` for complete security reviews. - -## Iron Law - -> **ASSUME ALL INPUT IS MALICIOUS** -> -> Every user input, URL parameter, header, and cookie is an attack vector. Use parameterized -> queries always. Escape output always. Validate schemas always. "This field is internal" -> is not a defense. Defense in depth, not wishful thinking. - ---- - -## Vulnerability Categories - -### 1. Input Validation & Injection - -**SQL Injection** -```typescript -// VULNERABLE -const query = `SELECT * FROM users WHERE email = '${email}'`; - -// SECURE -await db.execute("SELECT * FROM users WHERE email = ?", [email]); -``` - -**XSS (Cross-Site Scripting)** -```typescript -// VULNERABLE -element.innerHTML = userInput; - -// SECURE -element.textContent = userInput; -``` - -> See `references/injection.md` for NoSQL, command injection, path traversal patterns. - -### 2. Authentication & Authorization - -**Missing Auth Checks** -```typescript -// VULNERABLE -app.delete('/api/users/:id', async (req, res) => { - await deleteUser(req.params.id); // No auth! -}); - -// SECURE -app.delete('/api/users/:id', requireAuth, requireRole('admin'), handler); -``` - -> See `references/auth.md` for password policies, session management, JWT patterns. - -### 3. Cryptography & Secrets - -**Hardcoded Secrets** -```typescript -// VULNERABLE -const API_KEY = 'sk-abc123xyz789'; - -// SECURE -const API_KEY = process.env.API_KEY; -``` - -**Insecure Random** -```typescript -// VULNERABLE -const token = Math.random().toString(36); - -// SECURE -const token = crypto.randomBytes(32).toString('hex'); -``` - -> See `references/crypto.md` for weak crypto detection, encryption patterns. - -### 4. Configuration & Headers - -```typescript -// REQUIRED: Use helmet or set manually -app.use(helmet()); -res.setHeader('Content-Security-Policy', "default-src 'self'"); -res.setHeader('X-Frame-Options', 'DENY'); -res.setHeader('Strict-Transport-Security', 'max-age=31536000'); - -// CORS: Never use origin: '*' -app.use(cors({ origin: ['https://myapp.com'], credentials: true })); -``` - -### 5. Business Logic - -**Race Conditions** -```typescript -// VULNERABLE -if (balance >= amount) await withdraw(userId, amount); - -// SECURE: Use transactions with row locks -await db.transaction(async (tx) => { - const balance = await tx.getBalance(userId, { forUpdate: true }); - if (balance >= amount) await tx.withdraw(userId, amount); -}); -``` - -**Mass Assignment** -```typescript -// VULNERABLE -await User.create(req.body); // All fields accepted! - -// SECURE: Explicitly list allowed fields -await User.create({ email: req.body.email, name: req.body.name }); -``` - ---- - -## Extended References - -| Reference | Content | -|-----------|---------| -| `references/injection.md` | NoSQL, command, path traversal, LDAP, template injection | -| `references/auth.md` | Password policy, session management, JWT, RBAC/ABAC | -| `references/crypto.md` | Secret management, weak crypto, encryption, timing attacks | -| `references/detection.md` | All grep patterns for automated scanning | - ---- - -## Severity Guidelines - -| Level | Criteria | Examples | -|-------|----------|----------| -| **CRITICAL** | Immediate exploitation | SQL injection in auth, RCE, hardcoded admin creds | -| **HIGH** | Significant risk | XSS, broken access control, weak crypto, CSRF | -| **MEDIUM** | Moderate with conditions | Missing headers, permissive CORS, missing rate limits | -| **LOW** | Minor improvement | Outdated deps (no CVE), suboptimal CSP | - ---- - -## OWASP Reference - -| ID | Category | Examples | -|----|----------|----------| -| A01 | Broken Access Control | Missing auth, IDOR, privilege escalation | -| A02 | Cryptographic Failures | Weak hashing, hardcoded secrets | -| A03 | Injection | SQL, NoSQL, command, XSS | -| A04 | Insecure Design | Missing rate limits, mass assignment | -| A05 | Security Misconfiguration | Debug enabled, missing headers | -| A06 | Vulnerable Components | Outdated deps with known CVEs | -| A07 | Auth Failures | Weak passwords, session issues | -| A08 | Data Integrity Failures | Untrusted deserialization | -| A09 | Logging Failures | Missing security logs | -| A10 | SSRF | Unvalidated URLs in server requests | diff --git a/plugins/devflow-resolve/skills/security-patterns/references/patterns.md b/plugins/devflow-resolve/skills/security-patterns/references/patterns.md deleted file mode 100644 index 41e69292..00000000 --- a/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +++ /dev/null @@ -1,507 +0,0 @@ -# Security Correct Patterns - -Extended correct patterns for security implementation. Reference from main SKILL.md. - -## Injection Prevention - -### SQL Injection Prevention -```typescript -// SECURE: Parameterized queries -const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]); -const result = await db.query('SELECT * FROM products WHERE name LIKE $1', [`%${search}%`]); -``` - -### NoSQL Injection Prevention -```typescript -// SECURE: Coerce to string -const username = String(req.body.username); -const user = await db.users.findOne({ username }); - -// SECURE: Escape regex special characters -const escaped = userInput.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -db.users.find({ name: { $regex: escaped } }); -``` - -### Command Injection Prevention -```typescript -// SECURE: Use execFile with arguments array -execFile('ls', [userInput]); // Arguments are escaped -spawn('convert', [filename, 'output.png']); - -// SECURE: Validate input format -const hostnamePattern = /^[a-zA-Z0-9.-]+$/; -if (!hostnamePattern.test(hostname)) { - throw new Error('Invalid hostname'); -} -const args = ['-c', '4', hostname]; -spawn('ping', args); -``` - -### Path Traversal Prevention -```typescript -// SECURE: Normalize and validate path -const file = path.basename(req.params.filename); // Strip directory -const requestedPath = path.normalize( - path.join('./uploads', path.basename(req.params.filename)) -); -const absoluteUploads = path.resolve('./uploads'); -const absoluteRequested = path.resolve(requestedPath); - -if (!absoluteRequested.startsWith(absoluteUploads + path.sep)) { - throw new Error('Path traversal attempt blocked'); -} -fs.readFile(absoluteRequested); -``` - -### LDAP Injection Prevention -```typescript -// SECURE: Escape LDAP special characters -function escapeLDAP(str: string): string { - return str.replace(/[\\*()]/g, char => `\\${char.charCodeAt(0).toString(16)}`); -} -const filter = `(uid=${escapeLDAP(username)})`; -ldap.search(baseDN, filter); -``` - -### Template Injection Prevention -```typescript -// SECURE: Never build templates from user input -const template = 'Hello <%= name %>!'; -ejs.render(template, { name: req.body.name }); -``` - -### Header Injection Prevention -```typescript -// SECURE: Validate or encode header values -const safeInput = encodeURIComponent(userInput); -res.setHeader('Location', `/user/${safeInput}`); -``` - ---- - -## Authentication Patterns - -### Password Validation -```typescript -import { z } from 'zod'; - -const PasswordSchema = z.string() - .min(12, 'Password must be at least 12 characters') - .max(128, 'Password cannot exceed 128 characters') - .regex(/[A-Z]/, 'Password must contain uppercase letter') - .regex(/[a-z]/, 'Password must contain lowercase letter') - .regex(/[0-9]/, 'Password must contain number') - .regex(/[^A-Za-z0-9]/, 'Password must contain special character'); - -// Check against breach databases -import { pwnedPassword } from 'hibp'; - -async function validatePassword(password: string): Promise> { - const schemaResult = PasswordSchema.safeParse(password); - if (!schemaResult.success) { - return { ok: false, error: new Error(schemaResult.error.message) }; - } - - const breachCount = await pwnedPassword(password); - if (breachCount > 0) { - return { ok: false, error: new Error('Password found in breach database') }; - } - - return { ok: true, value: undefined }; -} -``` - -### Secure Session Management -```typescript -// SECURE: httpOnly cookie with secure flags -res.cookie('session', token, { - httpOnly: true, - secure: true, - sameSite: 'strict', - maxAge: 3600000 // 1 hour -}); - -// Cryptographically random session ID -const sessionId = crypto.randomBytes(32).toString('hex'); - -// Session rotation on privilege change -async function login(userId: string, res: Response): Promise { - const newSessionId = crypto.randomBytes(32).toString('hex'); - - // Invalidate old session - await sessionStore.destroy(req.sessionID); - - // Create new session with new ID - await sessionStore.create(newSessionId, { - userId, - createdAt: Date.now(), - lastAccess: Date.now() - }); - - res.cookie('session', newSessionId, { - httpOnly: true, - secure: true, - sameSite: 'strict', - maxAge: 3600000 - }); -} - -// Session timeout with sliding window -async function validateSession(sessionId: string): Promise> { - const session = await sessionStore.get(sessionId); - - if (!session) { - return { ok: false, error: new Error('Session not found') }; - } - - const MAX_IDLE_TIME = 30 * 60 * 1000; // 30 minutes - const MAX_SESSION_AGE = 24 * 60 * 60 * 1000; // 24 hours - - const now = Date.now(); - - if (now - session.lastAccess > MAX_IDLE_TIME) { - await sessionStore.destroy(sessionId); - return { ok: false, error: new Error('Session expired (idle)') }; - } - - if (now - session.createdAt > MAX_SESSION_AGE) { - await sessionStore.destroy(sessionId); - return { ok: false, error: new Error('Session expired (max age)') }; - } - - // Update last access for sliding window - await sessionStore.update(sessionId, { lastAccess: now }); - - return { ok: true, value: session }; -} -``` - -### Secure JWT Handling -```typescript -// SECURE: Proper JWT configuration -jwt.sign(payload, process.env.JWT_SECRET, { - algorithm: 'HS256', - expiresIn: '15m', - issuer: 'myapp' -}); - -jwt.verify(token, secret, { - algorithms: ['HS256'], // Explicitly specify - issuer: 'myapp' -}); - -// Refresh token pattern -interface TokenPair { - accessToken: string; - refreshToken: string; -} - -async function createTokenPair(userId: string): Promise { - const accessToken = jwt.sign( - { userId, type: 'access' }, - process.env.JWT_ACCESS_SECRET, - { algorithm: 'HS256', expiresIn: '15m' } - ); - - const refreshToken = jwt.sign( - { userId, type: 'refresh', jti: crypto.randomUUID() }, - process.env.JWT_REFRESH_SECRET, - { algorithm: 'HS256', expiresIn: '7d' } - ); - - // Store refresh token hash for revocation - await tokenStore.save({ - jti: jwt.decode(refreshToken).jti, - userId, - expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) - }); - - return { accessToken, refreshToken }; -} - -async function refreshTokens(refreshToken: string): Promise> { - try { - const payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET, { - algorithms: ['HS256'] - }); - - // Check if token is revoked - const stored = await tokenStore.find(payload.jti); - if (!stored) { - return { ok: false, error: new Error('Token revoked') }; - } - - // Revoke old refresh token - await tokenStore.delete(payload.jti); - - // Issue new token pair - return { ok: true, value: await createTokenPair(payload.userId) }; - } catch (error) { - return { ok: false, error: error as Error }; - } -} -``` - -### Authorization Patterns -```typescript -// SECURE: Layered auth middleware -app.delete('/api/users/:id', - requireAuth, - requireRole('admin'), - async (req, res) => { - await deleteUser(req.params.id); - } -); - -// Role-Based Access Control (RBAC) -type Permission = 'read' | 'write' | 'delete' | 'admin'; - -interface Role { - name: string; - permissions: Permission[]; -} - -const ROLES: Record = { - viewer: { name: 'viewer', permissions: ['read'] }, - editor: { name: 'editor', permissions: ['read', 'write'] }, - admin: { name: 'admin', permissions: ['read', 'write', 'delete', 'admin'] } -}; - -function requirePermission(...required: Permission[]) { - return (req: Request, res: Response, next: NextFunction) => { - const userRole = ROLES[req.user.role]; - - if (!userRole) { - return res.status(403).json({ error: 'Invalid role' }); - } - - const hasAll = required.every(p => userRole.permissions.includes(p)); - - if (!hasAll) { - return res.status(403).json({ error: 'Insufficient permissions' }); - } - - next(); - }; -} - -// Usage -app.delete('/api/posts/:id', requireAuth, requirePermission('delete'), handler); - -// Attribute-Based Access Control (ABAC) -interface AccessPolicy { - resource: string; - action: string; - conditions: (user: User, resource: Resource) => boolean; -} - -const policies: AccessPolicy[] = [ - { - resource: 'post', - action: 'delete', - conditions: (user, post) => - user.role === 'admin' || post.authorId === user.id - }, - { - resource: 'comment', - action: 'edit', - conditions: (user, comment) => - comment.authorId === user.id && - Date.now() - comment.createdAt < 15 * 60 * 1000 // 15 min window - } -]; - -function checkAccess(user: User, resource: Resource, action: string): boolean { - const policy = policies.find( - p => p.resource === resource.type && p.action === action - ); - - if (!policy) { - return false; // Deny by default - } - - return policy.conditions(user, resource); -} -``` - ---- - -## Cryptography Patterns - -### Secret Management -```typescript -// SECURE: Environment variables with validation -import { z } from 'zod'; - -const SecretsSchema = z.object({ - DB_PASSWORD: z.string().min(20), - API_KEY: z.string().regex(/^sk-(live|test)-[a-zA-Z0-9]{32}$/), - JWT_SECRET: z.string().min(64), - ENCRYPTION_KEY: z.string().length(64) // 32 bytes hex-encoded -}); - -function loadSecrets(): Result { - const result = SecretsSchema.safeParse(process.env); - if (!result.success) { - return { ok: false, error: new Error('Invalid secrets configuration') }; - } - return { ok: true, value: result.data }; -} - -// AWS Secrets Manager -import { SecretsManager } from '@aws-sdk/client-secrets-manager'; - -async function getSecret(secretId: string): Promise> { - const client = new SecretsManager({ region: 'us-east-1' }); - - try { - const response = await client.getSecretValue({ SecretId: secretId }); - if (!response.SecretString) { - return { ok: false, error: new Error('Secret not found') }; - } - return { ok: true, value: response.SecretString }; - } catch (error) { - return { ok: false, error: error as Error }; - } -} -``` - -### Password Hashing -```typescript -// SECURE: Argon2id (recommended) -import argon2 from 'argon2'; - -async function hashPassword(password: string): Promise { - return argon2.hash(password, { - type: argon2.argon2id, - memoryCost: 65536, // 64 MB - timeCost: 3, // 3 iterations - parallelism: 4 // 4 parallel threads - }); -} - -async function verifyPassword(password: string, hash: string): Promise { - return argon2.verify(hash, password); -} - -// SECURE: bcrypt (widely supported) -import bcrypt from 'bcrypt'; - -async function hashPassword(password: string): Promise { - const COST_FACTOR = 12; // Minimum for production - return bcrypt.hash(password, COST_FACTOR); -} -``` - -### Key Derivation -```typescript -// SECURE: Derive key using scrypt -async function deriveKey(password: string, salt: Buffer): Promise { - return new Promise((resolve, reject) => { - crypto.scrypt(password, salt, 32, (err, key) => { - if (err) reject(err); - else resolve(key); - }); - }); -} - -// Usage -const salt = crypto.randomBytes(16); -const key = await deriveKey(password, salt); -const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); -``` - -### Secure Random Generation -```typescript -// SECURE: Cryptographic random -const token = crypto.randomBytes(32).toString('hex'); -const id = crypto.randomUUID(); -const code = crypto.randomInt(100000, 1000000); - -// Secure token generation -function generateToken(bytes: number = 32): string { - return crypto.randomBytes(bytes).toString('hex'); -} - -// Secure numeric code (e.g., 2FA) -function generateOTP(digits: number = 6): string { - const max = Math.pow(10, digits); - const min = Math.pow(10, digits - 1); - return crypto.randomInt(min, max).toString(); -} - -// Secure API key generation -function generateApiKey(): string { - const prefix = 'sk'; - const env = process.env.NODE_ENV === 'production' ? 'live' : 'test'; - const random = crypto.randomBytes(24).toString('base64url'); - return `${prefix}_${env}_${random}`; -} - -// Secure password reset token -function generateResetToken(): { token: string; hash: string; expires: Date } { - const token = crypto.randomBytes(32).toString('hex'); - const hash = crypto.createHash('sha256').update(token).digest('hex'); - const expires = new Date(Date.now() + 60 * 60 * 1000); // 1 hour - - return { token, hash, expires }; -} -``` - -### Authenticated Encryption -```typescript -// SECURE: AES-256-GCM (authenticated encryption) -interface EncryptedData { - ciphertext: string; - iv: string; - authTag: string; -} - -function encrypt(plaintext: string, key: Buffer): EncryptedData { - const iv = crypto.randomBytes(12); // 96-bit IV for GCM - const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); - - let ciphertext = cipher.update(plaintext, 'utf8', 'hex'); - ciphertext += cipher.final('hex'); - - const authTag = cipher.getAuthTag(); - - return { - ciphertext, - iv: iv.toString('hex'), - authTag: authTag.toString('hex') - }; -} - -function decrypt(data: EncryptedData, key: Buffer): string { - const decipher = crypto.createDecipheriv( - 'aes-256-gcm', - key, - Buffer.from(data.iv, 'hex') - ); - - decipher.setAuthTag(Buffer.from(data.authTag, 'hex')); - - let plaintext = decipher.update(data.ciphertext, 'hex', 'utf8'); - plaintext += decipher.final('utf8'); - - return plaintext; -} -``` - -### Timing-Safe Comparison -```typescript -// SECURE: Constant-time comparison -import { timingSafeEqual } from 'crypto'; - -function verifyToken(provided: string, stored: string): boolean { - if (provided.length !== stored.length) { - return false; - } - - return timingSafeEqual( - Buffer.from(provided), - Buffer.from(stored) - ); -} -``` diff --git a/plugins/devflow-resolve/skills/security-patterns/references/violations.md b/plugins/devflow-resolve/skills/security-patterns/references/violations.md deleted file mode 100644 index 10d784fc..00000000 --- a/plugins/devflow-resolve/skills/security-patterns/references/violations.md +++ /dev/null @@ -1,237 +0,0 @@ -# Security Violation Examples - -Extended violation patterns for security reviews. Reference from main SKILL.md. - -## Injection Vulnerabilities - -### SQL Injection -```typescript -// VULNERABLE: String interpolation in query -const user = await db.query(`SELECT * FROM users WHERE id = '${userId}'`); -const result = await db.query(`SELECT * FROM products WHERE name LIKE '%${search}%'`); -``` - -### NoSQL Injection -```typescript -// VULNERABLE: Direct object from request -const user = await db.users.findOne({ username: req.body.username }); -// Attacker sends: { username: { $gt: "" } } - -// VULNERABLE: $where operator accepts arbitrary JS -db.users.find({ $where: `this.name === '${userInput}'` }); - -// VULNERABLE: regex injection -db.users.find({ name: { $regex: userInput } }); -// Attacker sends: ".*" (matches everything) -``` - -### Command Injection -```typescript -// VULNERABLE: User input in shell command -exec(`ls ${userInput}`); -exec(`convert ${filename} output.png`); -exec(`ping -c 4 ${hostname}`); - -// Dangerous characters: ; | & $ ` ( ) < > \ ' " -// Example attack: userInput = "file.txt; rm -rf /" -``` - -### Path Traversal -```typescript -// VULNERABLE: Direct path concatenation -const file = req.params.filename; -fs.readFile(`./uploads/${file}`); // Attacker: ../../../etc/passwd - -// VULNERABLE: Encoded traversal -// Attacker sends: %2e%2e%2f%2e%2e%2fetc/passwd (URL encoded ../..) -const decoded = decodeURIComponent(req.params.filename); -fs.readFile(`./uploads/${decoded}`); - -// VULNERABLE: Double encoding -// Attacker sends: %252e%252e%252f (double-encoded ../) -``` - -### LDAP Injection -```typescript -// VULNERABLE: Unescaped LDAP filter -const filter = `(uid=${username})`; -ldap.search(baseDN, filter); -// Attacker: username = "admin)(&(password=*)" -``` - -### Template Injection (SSTI) -```typescript -// VULNERABLE: User input in template -const template = `Hello ${req.body.name}!`; -ejs.render(template); -// Attacker: name = "<%= process.env.SECRET %>" -``` - -### Header Injection -```typescript -// VULNERABLE: CRLF injection -res.setHeader('Location', `/user/${userInput}`); -// Attacker: userInput = "test\r\nSet-Cookie: admin=true" -``` - ---- - -## Authentication Vulnerabilities - -### Weak Password Policies -```typescript -// VULNERABLE: Weak password requirements -if (password.length >= 6) { /* accept */ } -``` - -### Session Management Issues -```typescript -// VULNERABLE: Session ID in URL -app.get('/dashboard?session=abc123'); - -// VULNERABLE: Predictable session IDs -const sessionId = `user_${userId}`; - -// VULNERABLE: No session timeout or rotation -``` - -### JWT Misuse -```typescript -// VULNERABLE: Weak secret -jwt.sign(payload, 'secret123'); - -// VULNERABLE: No expiration -jwt.sign(payload, secret); - -// VULNERABLE: Algorithm confusion (accepts 'none') -jwt.verify(token, secret); // Without algorithm specification -``` - -### Missing Authorization -```typescript -// VULNERABLE: No auth checks -app.delete('/api/users/:id', async (req, res) => { - await deleteUser(req.params.id); // No auth check! -}); -``` - ---- - -## Cryptography Vulnerabilities - -### Hardcoded Secrets -```typescript -// VULNERABLE: Secrets in code -const API_KEY = 'sk-abc123xyz789'; -const dbPassword = 'admin123'; -const jwtSecret = 'mysecret'; - -// VULNERABLE: Secrets in config files -const config = { - database: { - password: 'prod_password_123' - }, - api: { - key: 'sk-live-abcdef123456' - } -}; -``` - -### Weak Cryptography -```typescript -// VULNERABLE: Broken hash algorithms -crypto.createHash('md5').update(password); // MD5 is broken -crypto.createHash('sha1').update(password); // SHA1 weak for passwords - -// VULNERABLE: Using password directly as key -const key = password; -crypto.createCipheriv('aes-256-gcm', key, iv); -``` - -### Insecure Random -```typescript -// VULNERABLE: Predictable random -const token = Math.random().toString(36); // Predictable! -const id = Date.now().toString(); -const code = Math.floor(Math.random() * 1000000); -``` - -### Weak Encryption -```typescript -// VULNERABLE: ECB mode (patterns visible) -crypto.createCipheriv('aes-256-ecb', key, null); - -// VULNERABLE: No authentication (CBC without HMAC) -crypto.createCipheriv('aes-256-cbc', key, iv); -``` - -### Timing Attacks -```typescript -// VULNERABLE: Early exit reveals length info -function verifyToken(provided: string, stored: string): boolean { - return provided === stored; // Early exit reveals info -} -``` - ---- - -## Detection Grep Commands - -### Injection Detection -```bash -# SQL Injection -grep -rn "query.*\${" --include="*.ts" --include="*.js" -grep -rn "query.*+ " --include="*.ts" --include="*.js" -grep -rn "execute.*\`" --include="*.ts" --include="*.js" - -# NoSQL Injection -grep -rn "findOne.*req\.\|find.*req\." --include="*.ts" --include="*.js" -grep -rn "\$where" --include="*.ts" --include="*.js" - -# Command Injection -grep -rn "exec\s*\(" --include="*.ts" --include="*.js" -grep -rn "spawn.*\`\|execSync.*\`" --include="*.ts" --include="*.js" - -# Path Traversal -grep -rn "readFile.*req\.\|readFileSync.*req\." --include="*.ts" --include="*.js" -grep -rn "path\.join.*req\." --include="*.ts" --include="*.js" -``` - -### Auth Detection -```bash -# Missing auth middleware -grep -rn "app\.\(get\|post\|put\|delete\).*async" --include="*.ts" --include="*.js" | \ - grep -v "requireAuth\|isAuthenticated\|authorize" - -# Weak JWT configuration -grep -rn "jwt\.sign\|jwt\.verify" --include="*.ts" --include="*.js" -A 5 | \ - grep -v "algorithm\|expiresIn" - -# Session issues -grep -rn "session\|cookie" --include="*.ts" --include="*.js" | \ - grep -v "httpOnly\|secure\|sameSite" - -# Password handling -grep -rn "password.*length" --include="*.ts" --include="*.js" -``` - -### Crypto Detection -```bash -# Hardcoded secrets -grep -rn "password.*=.*['\"]" --include="*.ts" --include="*.js" -grep -rn "api.key.*=.*['\"]" --include="*.ts" --include="*.js" -grep -rn "secret.*=.*['\"]" --include="*.ts" --include="*.js" -grep -rn "sk-\|pk-\|api_" --include="*.ts" --include="*.js" - -# Weak crypto -grep -rn "createHash.*md5\|sha1" --include="*.ts" --include="*.js" -grep -rn "DES\|RC4\|Blowfish" --include="*.ts" --include="*.js" -grep -rn "aes-.*-ecb\|aes-.*-cbc" --include="*.ts" --include="*.js" - -# Insecure random -grep -rn "Math.random" --include="*.ts" --include="*.js" -grep -rn "Date.now.*id\|Date.now.*token" --include="*.ts" --include="*.js" - -# String comparison for secrets -grep -rn "token.*===\|secret.*===\|key.*===" --include="*.ts" --include="*.js" -``` diff --git a/plugins/devflow-self-review/.claude-plugin/plugin.json b/plugins/devflow-self-review/.claude-plugin/plugin.json index 64f7d2eb..29c2d56d 100644 --- a/plugins/devflow-self-review/.claude-plugin/plugin.json +++ b/plugins/devflow-self-review/.claude-plugin/plugin.json @@ -21,7 +21,7 @@ ], "skills": [ "self-review", - "core-patterns", + "software-design", "worktree-support" ] } diff --git a/scripts/hooks/ambient-prompt b/scripts/hooks/ambient-prompt index 1acd3c09..c43956dc 100755 --- a/scripts/hooks/ambient-prompt +++ b/scripts/hooks/ambient-prompt @@ -42,13 +42,13 @@ RESOLVE: always ORCHESTRATED. PIPELINE (end-to-end/implement and review): always MULTI_WORKTREE: all worktrees/branches, each worktree, review everything, resolve all → ORCHESTRATED. Follow code-review/resolve command flow (auto-discovers worktrees). GUIDED/ORCHESTRATED: Call Skill tool for ALL skills listed for intent — one Skill call per skill, before ANY text. IMPLEMENT → devflow:test-driven-development, devflow:implementation-patterns, devflow:search-first -DEBUG → devflow:core-patterns, devflow:test-patterns -REVIEW/GUIDED → devflow:self-review, devflow:core-patterns +DEBUG → devflow:software-design, devflow:testing +REVIEW/GUIDED → devflow:self-review, devflow:software-design REVIEW/ORCHESTRATED → devflow:review-orchestration -RESOLVE → devflow:resolve-orchestration, devflow:core-patterns +RESOLVE → devflow:resolve-orchestration, devflow:software-design PIPELINE → devflow:pipeline-orchestration, devflow:implementation-patterns -PLAN → devflow:implementation-patterns, devflow:core-patterns -Also add if file type matches: devflow:typescript, devflow:react, devflow:go, devflow:java, devflow:python, devflow:rust, devflow:input-validation, devflow:security-patterns, devflow:frontend-design +PLAN → devflow:implementation-patterns, devflow:software-design +Also add if file type matches: devflow:typescript, devflow:react, devflow:go, devflow:java, devflow:python, devflow:rust, devflow:boundary-validation, devflow:security, devflow:ui-design ORCHESTRATED also add: devflow:implementation-orchestration / devflow:debug-orchestration / devflow:plan-orchestration / devflow:review-orchestration / devflow:resolve-orchestration / devflow:pipeline-orchestration State: Ambient: INTENT/DEPTH. Loading: skills. Then proceed." diff --git a/shared/agents/coder.md b/shared/agents/coder.md index 36fa3334..9ba38acd 100644 --- a/shared/agents/coder.md +++ b/shared/agents/coder.md @@ -2,7 +2,7 @@ name: Coder description: Autonomous task implementation on feature branch. Implements, tests, and commits. model: sonnet -skills: devflow:core-patterns, devflow:git-safety, devflow:implementation-patterns, devflow:git-workflow, devflow:test-patterns, devflow:test-driven-development, devflow:search-first, devflow:input-validation, devflow:worktree-support +skills: devflow:software-design, devflow:git, devflow:implementation-patterns, devflow:testing, devflow:test-driven-development, devflow:search-first, devflow:boundary-validation, devflow:worktree-support --- # Coder Agent @@ -42,13 +42,13 @@ You receive from orchestrator: - If `.docs/handoff.md` exists, read it for prior phase context. Cross-reference against actual code — code is authoritative, handoff is supplementary. 2. **Load domain skills**: Based on DOMAIN hint and files in scope, dynamically load relevant language/ecosystem skills by reading their SKILL.md. Only load skills that are installed: - - `backend` (TypeScript): Read `~/.claude/skills/devflow:typescript/SKILL.md`, `~/.claude/skills/devflow:input-validation/SKILL.md` + - `backend` (TypeScript): Read `~/.claude/skills/devflow:typescript/SKILL.md`, `~/.claude/skills/devflow:boundary-validation/SKILL.md` - `backend` (Go): Read `~/.claude/skills/devflow:go/SKILL.md` - `backend` (Java): Read `~/.claude/skills/devflow:java/SKILL.md` - `backend` (Python): Read `~/.claude/skills/devflow:python/SKILL.md` - `backend` (Rust): Read `~/.claude/skills/devflow:rust/SKILL.md` - - `frontend`: Read `~/.claude/skills/devflow:react/SKILL.md`, `~/.claude/skills/devflow:typescript/SKILL.md`, `~/.claude/skills/devflow:accessibility/SKILL.md`, `~/.claude/skills/devflow:frontend-design/SKILL.md` - - `tests`: Read `~/.claude/skills/devflow:test-patterns/SKILL.md`, `~/.claude/skills/devflow:typescript/SKILL.md` + - `frontend`: Read `~/.claude/skills/devflow:react/SKILL.md`, `~/.claude/skills/devflow:typescript/SKILL.md`, `~/.claude/skills/devflow:accessibility/SKILL.md`, `~/.claude/skills/devflow:ui-design/SKILL.md` + - `tests`: Read `~/.claude/skills/devflow:testing/SKILL.md`, `~/.claude/skills/devflow:typescript/SKILL.md` - `fullstack`: Combine backend + frontend skills - If a Read fails (skill not installed), skip it silently and continue. diff --git a/shared/agents/git.md b/shared/agents/git.md index e744a589..223fa7fb 100644 --- a/shared/agents/git.md +++ b/shared/agents/git.md @@ -2,7 +2,7 @@ name: Git description: Unified agent for all git/GitHub operations - issues, PR comments, tech debt, releases model: haiku -skills: devflow:github-patterns, devflow:git-safety, devflow:git-workflow, devflow:worktree-support +skills: devflow:git, devflow:worktree-support --- # Git Agent @@ -39,9 +39,9 @@ Pre-flight checks and fixes for `/code-review`. Ensures branch is ready for code **Process:** 1. Verify on feature branch (not main/master/develop/release/*/staging/production) - error if not -2. Check for uncommitted changes - if any, create atomic commit using `devflow:git-workflow` patterns +2. Check for uncommitted changes - if any, create atomic commit using `devflow:git` patterns 3. Check if branch pushed to remote - if not, push with `-u` flag -4. Check if PR exists - if not, create PR using `devflow:git-workflow` patterns +4. Check if PR exists - if not, create PR using `devflow:git` patterns 5. Get base branch from PR 6. Derive branch-slug (replace `/` with `-`) @@ -210,7 +210,7 @@ Update tech debt backlog with pre-existing issues from code review. **Process:** 1. Find or create "Tech Debt Backlog" issue with `tech-debt` label -2. Check issue body size; archive if > 60000 chars (per devflow:github-patterns) +2. Check issue body size; archive if > 60000 chars (per devflow:git) 3. Extract pre-existing issues (Category 3) from review reports 4. Deduplicate against existing items using semantic matching 5. Remove items that have been fixed (verify in codebase) diff --git a/shared/agents/resolver.md b/shared/agents/resolver.md index 44df2cd4..ecb3b987 100644 --- a/shared/agents/resolver.md +++ b/shared/agents/resolver.md @@ -2,7 +2,7 @@ name: Resolver description: Validates review issues, implements fixes with risk-proportional care. Tech debt only for architectural overhauls. model: sonnet -skills: devflow:core-patterns, devflow:git-safety, devflow:implementation-patterns, devflow:git-workflow, devflow:worktree-support +skills: devflow:software-design, devflow:git, devflow:implementation-patterns, devflow:worktree-support --- # Resolver Agent diff --git a/shared/agents/reviewer.md b/shared/agents/reviewer.md index 7a793351..64fd530f 100644 --- a/shared/agents/reviewer.md +++ b/shared/agents/reviewer.md @@ -23,20 +23,20 @@ The orchestrator provides: | Focus | Pattern Skill File (Read this first) | |-------|--------------------------------------| -| `security` | `~/.claude/skills/devflow:security-patterns/SKILL.md` | -| `architecture` | `~/.claude/skills/devflow:architecture-patterns/SKILL.md` | -| `performance` | `~/.claude/skills/devflow:performance-patterns/SKILL.md` | -| `complexity` | `~/.claude/skills/devflow:complexity-patterns/SKILL.md` | -| `consistency` | `~/.claude/skills/devflow:consistency-patterns/SKILL.md` | -| `regression` | `~/.claude/skills/devflow:regression-patterns/SKILL.md` | -| `tests` | `~/.claude/skills/devflow:test-patterns/SKILL.md` | +| `security` | `~/.claude/skills/devflow:security/SKILL.md` | +| `architecture` | `~/.claude/skills/devflow:architecture/SKILL.md` | +| `performance` | `~/.claude/skills/devflow:performance/SKILL.md` | +| `complexity` | `~/.claude/skills/devflow:complexity/SKILL.md` | +| `consistency` | `~/.claude/skills/devflow:consistency/SKILL.md` | +| `regression` | `~/.claude/skills/devflow:regression/SKILL.md` | +| `testing` | `~/.claude/skills/devflow:testing/SKILL.md` | | `typescript` | `~/.claude/skills/devflow:typescript/SKILL.md` | -| `database` | `~/.claude/skills/devflow:database-patterns/SKILL.md` | -| `dependencies` | `~/.claude/skills/devflow:dependencies-patterns/SKILL.md` | -| `documentation` | `~/.claude/skills/devflow:documentation-patterns/SKILL.md` | +| `database` | `~/.claude/skills/devflow:database/SKILL.md` | +| `dependencies` | `~/.claude/skills/devflow:dependencies/SKILL.md` | +| `documentation` | `~/.claude/skills/devflow:documentation/SKILL.md` | | `react` | `~/.claude/skills/devflow:react/SKILL.md` | | `accessibility` | `~/.claude/skills/devflow:accessibility/SKILL.md` | -| `frontend-design` | `~/.claude/skills/devflow:frontend-design/SKILL.md` | +| `ui-design` | `~/.claude/skills/devflow:ui-design/SKILL.md` | | `go` | `~/.claude/skills/devflow:go/SKILL.md` | | `java` | `~/.claude/skills/devflow:java/SKILL.md` | | `python` | `~/.claude/skills/devflow:python/SKILL.md` | @@ -154,14 +154,14 @@ Report format for `{output_path}`: | Focus | Condition | |-------|-----------| -| security, architecture, performance, complexity, consistency, tests, regression | Always | +| security, architecture, performance, complexity, consistency, testing, regression | Always | | typescript | If .ts/.tsx files changed | | database | If migration/schema files changed | | documentation | If docs changed | | dependencies | If package.json/lock files changed | | react | If .tsx/.jsx files changed | | accessibility | If .tsx/.jsx files changed | -| frontend-design | If .tsx/.jsx/.css/.scss files changed | +| ui-design | If .tsx/.jsx/.css/.scss files changed | | go | If .go files changed | | java | If .java files changed | | python | If .py files changed | diff --git a/shared/agents/scrutinizer.md b/shared/agents/scrutinizer.md index c67f728f..70789fa6 100644 --- a/shared/agents/scrutinizer.md +++ b/shared/agents/scrutinizer.md @@ -2,7 +2,7 @@ name: Scrutinizer description: Self-review agent that evaluates and fixes implementation issues using 9-pillar framework. Runs in fresh context after Coder completes. model: opus -skills: devflow:self-review, devflow:core-patterns, devflow:worktree-support +skills: devflow:self-review, devflow:software-design, devflow:worktree-support --- # Scrutinizer Agent diff --git a/shared/agents/shepherd.md b/shared/agents/shepherd.md index 17c1a3fa..cd2dfc97 100644 --- a/shared/agents/shepherd.md +++ b/shared/agents/shepherd.md @@ -2,7 +2,7 @@ name: Shepherd description: Validates implementation aligns with original request and plan. Catches missed requirements, scope creep, and intent drift. Reports misalignments for Coder to fix. model: opus -skills: devflow:core-patterns, devflow:worktree-support +skills: devflow:software-design, devflow:worktree-support --- # Shepherd Agent diff --git a/shared/agents/simplifier.md b/shared/agents/simplifier.md index d5850a45..d204f7aa 100644 --- a/shared/agents/simplifier.md +++ b/shared/agents/simplifier.md @@ -1,7 +1,7 @@ --- name: Simplifier description: Simplifies and refines code for clarity, consistency, and maintainability while preserving all functionality. Focuses on recently modified code unless instructed otherwise. -skills: devflow:core-patterns, devflow:worktree-support +skills: devflow:software-design, devflow:worktree-support model: sonnet --- diff --git a/shared/agents/validator.md b/shared/agents/validator.md index 09b33083..b491cb52 100644 --- a/shared/agents/validator.md +++ b/shared/agents/validator.md @@ -2,7 +2,7 @@ name: Validator description: Dedicated agent for running validation commands (build, typecheck, lint, test). Reports pass/fail with structured failure details - never fixes. model: haiku -skills: devflow:test-patterns, devflow:worktree-support +skills: devflow:testing, devflow:worktree-support --- # Validator Agent diff --git a/shared/skills/accessibility/SKILL.md b/shared/skills/accessibility/SKILL.md index 4731ffba..c481e72f 100644 --- a/shared/skills/accessibility/SKILL.md +++ b/shared/skills/accessibility/SKILL.md @@ -1,6 +1,6 @@ --- name: accessibility -description: This skill should be used when the user asks to "add accessibility", "check ARIA", "handle keyboard navigation", "add focus management", or creates UI components, forms, or interactive elements. Provides WCAG 2.1 AA patterns for keyboard navigation, ARIA roles and states, focus management, color contrast, and screen reader support. +description: This skill should be used when the user asks to "add accessibility", "check ARIA", "handle keyboard navigation", "add focus management", or creates UI components, forms, or interactive elements. Provides WCAG 2.2 AA patterns for keyboard navigation, ARIA roles and states, focus management, color contrast, and screen reader support. user-invocable: false allowed-tools: Read, Grep, Glob activation: @@ -17,213 +17,129 @@ activation: # Accessibility Patterns -Reference for web accessibility (WCAG 2.1 AA compliance), keyboard navigation, screen reader support, and inclusive design. +Reference for web accessibility (WCAG 2.2 AA compliance), keyboard navigation, screen reader support, and inclusive design. Sources in `references/sources.md`. ## Iron Law -> **EVERY INTERACTION MUST BE POSSIBLE WITHOUT A MOUSE** +> **EVERY INTERACTION MUST BE POSSIBLE WITHOUT A MOUSE** [1][3] > -> If a user cannot complete an action using only keyboard, the feature is broken. -> Mouse-only interactions exclude users with motor disabilities, power users, -> and anyone navigating with assistive technology. Tab order, focus management, -> and keyboard shortcuts are not optional enhancements. +> Mouse-only interactions exclude users with motor disabilities, power users, and AT users. +> Tab order, focus management, and keyboard shortcuts are not optional enhancements. +> — WCAG 2.1 Principle 2 (Operable) [1] -## When This Skill Activates - -- Creating interactive UI components -- Building forms and inputs -- Working with React/JSX code -- Discussing focus, ARIA, or screen readers -- Reviewing color schemes or contrast +**Activates for**: interactive UI components · forms · React/JSX or CSS · focus/ARIA/contrast reviews --- -## Keyboard Navigation +## Keyboard Navigation [1][3] -### Focus Management +**Focus management**: On modal open, move focus to the first focusable element; on close, return to the trigger. Trap focus inside. [3] ```tsx -// CORRECT: Focus trap in modal +// CORRECT: Focus trap — APG dialog pattern [3] function Modal({ isOpen, onClose, children }) { - const firstFocusable = useRef(null); - - useEffect(() => { - if (isOpen) firstFocusable.current?.focus(); - }, [isOpen]); - + const first = useRef(null); + useEffect(() => { if (isOpen) first.current?.focus(); }, [isOpen]); return ( -
{ - if (e.key === 'Escape') onClose(); - }}> - - {children} +
{ if (e.key === 'Escape') onClose(); }}> + {children}
); } - -// VIOLATION: No focus management, no escape handler -function BadModal({ children }) { - return
{children}
; -} ``` -### Skip Links - -```tsx -// CORRECT: Skip to main content - - Skip to main content - -
...
-``` +**Skip links**: First focusable element — visible on focus, links to `#main-content`. [1][4] +**Roving tabIndex**: Active item `tabIndex={0}`, others `tabIndex={-1}` — radio groups, toolbars, tabs. [3] --- -## ARIA and Semantic HTML +## ARIA and Semantic HTML [2][15][18] -### Prefer Semantic Elements +**First rule of ARIA**: Use native HTML before adding ARIA roles — no ARIA is better than bad ARIA. [15][18] -```tsx -// CORRECT: Native semantics - - -
...
- -// VIOLATION: Div with role instead of semantic element -
Submit
-
...
-``` +| CORRECT [18] | VIOLATION [15] | +|---|---| +| `` | `
Submit
` | +| `