M07: Advanced Workflows — Workshop Guide
Self-directed | 45–60 min | Requires: M07 study guide read beforehand
Before You Start
Section titled “Before You Start”Prerequisites
- M07 study guide and pre-work theory completed
- Access to a team Git repository (or a test repo you control)
- Familiarity with YAML frontmatter
- Basic shell scripting knowledge (bash)
- Git basics (add, commit, push)
What you’ll do
- Create your first skill (Pure Markdown)
- Create a subagent for code quality review
- Create a PostToolUse hook for auto-linting
- Create a feature development workflow skill
- Test the full integration
- Commit everything to your repository
Context
Section titled “Context”Your team needs a repeatable workflow: developers write code, subagents review it, hooks auto-lint, everything feeds into CI/CD. You’ll build:
- Team skill:
/new-component— scaffolds a new React component with skeleton code - Subagent: Code quality reviewer specialized in your codebase
- Hook: Auto-lints code on every file write
Step 1: Create Your First Skill — Pure Markdown
Section titled “Step 1: Create Your First Skill — Pure Markdown”Create .claude/skills/new-component.md in your repository:
---name: New Componentdescription: Scaffold a new React component following team conventionsdisable-model-invocation: falseallowed-tools: []---
# New Component Scaffold
Create a new React component that follows our team conventions:
## Structure- Component file in `components/{ComponentName}.tsx`- PropTypes validation- Storybook story file- Unit test file- Export from `components/index.ts`
## Template: components/Button.tsx
```typescriptimport React from 'react';import PropTypes from 'prop-types';
interface ButtonProps { label: string; onClick: () => void; variant?: 'primary' | 'secondary'; disabled?: boolean;}
export const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary', disabled = false,}) => { return ( <button onClick={onClick} disabled={disabled} className={`btn btn-${variant}`} > {label} </button> );};
Button.propTypes = { label: PropTypes.string.isRequired, onClick: PropTypes.func.isRequired, variant: PropTypes.oneOf(['primary', 'secondary']), disabled: PropTypes.bool,};```
## Checklist- [ ] Component exports named function- [ ] PropTypes defined- [ ] JSDoc comments on props- [ ] Story file created (Storybook integration)- [ ] Test file created with at least one snapshot test- [ ] Component exported from `components/index.ts`
## Test Pattern
```typescriptimport { render } from '@testing-library/react';import { Button } from './Button';
describe('Button', () => { it('renders with label', () => { const { getByText } = render( <Button label="Click me" onClick={() => {}} /> ); expect(getByText('Click me')).toBeInTheDocument(); });
it('matches snapshot', () => { const { container } = render( <Button label="Click me" onClick={() => {}} /> ); expect(container).toMatchSnapshot(); });});```Now run: /new-component in Claude Code. It will generate boilerplate.
Step 2: Create a Subagent for Code Quality
Section titled “Step 2: Create a Subagent for Code Quality”Create .claude/agents/code-quality.md:
---name: code-qualitydescription: Code quality and architecture reviewermodel: claude-opus-4-1instructions: | You are a senior code reviewer focused on quality and maintainability. Evaluate code for: readability, testability, performance, architectural fit. Provide constructive feedback aligned with team standards.tools: - read_file - grep_codebase - analyze_imports---
# Code Quality Reviewer
Review the provided code for quality issues:
## Readability- Variable names clear and descriptive?- Functions focused (single responsibility)?- Comments explain "why", not "what"?
## Testability- Code can be unit tested (minimal side effects)?- Dependencies injectable?- Mock-friendly?
## Performance- N+1 queries? Database inefficiencies?- Unnecessary re-renders (React)?- Unbounded loops or arrays?
## Architectural Fit- Follows team patterns (styling, routing, state management)?- Proper separation of concerns?- Reusable or tightly coupled to one use case?
Return structured feedback:- Category (Readability, Testability, Performance, Architecture)- Severity (Must Fix, Should Fix, Nice to Have)- Specific location- Suggested improvementTest it by calling @code-quality in a Claude Code session:
“@code-quality review src/components/Button.tsx”
Step 3: Create a PostToolUse Hook
Section titled “Step 3: Create a PostToolUse Hook”Create .claude/hooks/post_tool_use.sh:
#!/bin/bashset -e
# Auto-lint JavaScript/TypeScript files after writesif [[ "$TOOL_NAME" == "write_file" || "$TOOL_NAME" == "edit_file" ]]; then if [[ "$TOOL_OUTPUT" =~ \.(ts|tsx|js|jsx)$ ]]; then if command -v npx &> /dev/null; then echo "🔧 Auto-linting $TOOL_OUTPUT..." npx eslint --fix "$TOOL_OUTPUT" 2>/dev/null || true echo "✓ Linting complete" fi fifi
# Run tests if test file was modifiedif [[ "$TOOL_OUTPUT" =~ \.test\.(ts|tsx|js|jsx)$ ]]; then echo "🧪 Running tests for $TOOL_OUTPUT..." npx jest "$TOOL_OUTPUT" --passWithNoTests 2>/dev/null || truefi
# Validate TypeScript on any .ts/.tsx writeif [[ "$TOOL_OUTPUT" =~ \.(ts|tsx)$ ]]; then echo "✓ TypeScript valid"fiMake it executable:
chmod +x .claude/hooks/post_tool_use.shNow whenever Claude Code writes a TypeScript file, it auto-lints.
Step 4: Create a Feature Development Skill
Section titled “Step 4: Create a Feature Development Skill”Create .claude/skills/new-feature.md:
---name: New Featuredescription: Start a new feature following team workflowdisable-model-invocation: falseallowed-tools: [write_file, read_file, execute_bash]---
# New Feature Workflow
When creating a new feature:
1. **Read the requirements** — Understand what you're building2. **Design the interface** — Component props, API contract, types3. **Implement** — Write code, follow component scaffold pattern4. **Test** — Unit tests, integration tests5. **Self-review** — Run `/code-quality @code-quality` to review your own work6. **Security check** — Request `@security-reviewer` to validate
## Typical Feature Checklist
- [ ] Types defined (`interface` or `type`)- [ ] Unit tests (>80% coverage)- [ ] Integration test (happy path)- [ ] Storybook story (if UI component)- [ ] Code quality review passed- [ ] Security review passed- [ ] Documentation/comments added- [ ] Committed and pushed to feature branch
## Example: Add User Profile Page
```/new-feature→ Claude creates: pages/Profile.tsx, pages/Profile.test.tsx, components/ProfileCard.tsx→ Human writes requirements in the files→ @code-quality reviews implementation→ @security-reviewer checks for auth bypass, data exposure→ Hooks auto-lint, run tests→ Ready for PR```Step 5: Test Integration
Section titled “Step 5: Test Integration”In Claude Code, try the full workflow:
/new-feature
[Claude scaffolds a component]
@code-quality review the implementation
[Code quality subagent provides feedback]
[Your PostToolUse hook auto-lints]
Feature ready for PRWhat to observe:
- Does the
/new-featureskill guide you through a checklist? - When you call
@code-quality, does it run in isolation with its own context? - Does the hook auto-lint files you write?
Step 6: End-to-End Workflow Recipe (Optional Capstone)
Section titled “Step 6: End-to-End Workflow Recipe (Optional Capstone)”If time allows, build a complete feature development workflow that chains all the building blocks together:
1. CLAUDE.md → contains implementation standards ("write tests first", "don't commit until approved")2. /feature-spec skill → creates user story, acceptance criteria, technical approach3. Subagent → researches the codebase for existing patterns and dependencies (separate context)4. Plan Mode → produces implementation plan with spec and research as input5. Hooks: PostToolUse on Write → auto-runs linter; PreToolUse on Bash(git commit) → validates tests pass6. GitHub MCP → creates a branch, commits, and opens a PR7. Second subagent → reviews the PR from a fresh context (Writer/Reviewer pattern)This is the composition stack in action — each layer does one thing, and together they automate the full development lifecycle.
Step 7: Commit to Repository
Section titled “Step 7: Commit to Repository”cd /path/to/repogit add .claude/skills/ .claude/agents/ .claude/hooks/git commit -m "feat: add feature workflow (skill + subagent + hook)"git push origin mainNow every team member cloning the repo gets these skills and hooks automatically.
Hands-on Exercise: Custom Skill + Hook (30–45 minutes)
Section titled “Hands-on Exercise: Custom Skill + Hook (30–45 minutes)”Choose One Scenario
Section titled “Choose One Scenario”Option A: Database Migration Skill
Create a /migrate skill that:
- Scaffolds a migration file (src/migrations/TIMESTAMP_description.sql)
- Provides migration template (up, down, safety checks)
- Includes a hook that validates SQL syntax before commit
Option B: PR Checklist Skill
Create a /review-checklist skill that:
- Asks questions about the PR (scope, tests, docs)
- Generates a structured checklist
- Includes a PostToolUse hook that validates checklist completion
Option C: API Endpoint Skill
Create a /new-endpoint skill that:
- Scaffolds a new Express.js endpoint
- Creates route, validation, tests
- Includes a hook that validates OpenAPI/Swagger compliance
What to Produce
Section titled “What to Produce”- Skills: All
.ymlfiles in.claude/skills/ - Subagents: All
.mdfiles in.claude/agents/ - Hooks: All
.shfiles in.claude/hooks/ - Documentation: A 1-page README explaining:
- What each skill does and when to use it
- What the subagent specializes in
- How the hook improves the workflow
- Team adoption plan (e.g., “Commit to repo, document in wiki”)
Reflection Questions
Section titled “Reflection Questions”Use these questions to consolidate what you have learned before moving on:
- When you created the skill definition, what was the hardest part? Consider: clarity of instructions, what to include in the checklist, when to delegate to a subagent.
- How would you describe the difference between a skill and a subagent? Skills are instructions and templates; subagents are independent sessions with specialized roles and their own tool access.
- If the hook did not run, how would you debug it? Consider:
chmod +x, verifying the file location, and confirming the filename matches the lifecycle event name. - What is the biggest risk of committing a buggy skill to the repo? Everyone who clones the repo gets it immediately — test thoroughly before committing, and use git to roll back if needed.
Troubleshooting
Section titled “Troubleshooting”Skill doesn’t appear in / menu:
- Check YAML syntax (use a YAML validator)
- Ensure file is in
.claude/skills/or~/.claude/skills/ - Reload Claude Code
Subagent not responding:
- Verify
.claude/agents/agent-name.mdexists - Check instructions aren’t contradictory
- Test with
@agent-name test message
Hook not running:
- Check file is in
.claude/hooks/and executable (chmod +x) - Verify hook name matches lifecycle event (post_tool_use.sh, etc.)
- Add logging:
echo "Hook executed"to see if it runs
Skill calls restricted tool:
- Check
allowed-toolsin frontmatter - If empty, skill can’t call tools; add tool names explicitly
- If
disable-model-invocation: true, Claude won’t improve the skill
Workshop Completion Checklist
Section titled “Workshop Completion Checklist”Before moving on, confirm you have:
- At least one skill defined in
.claude/skills/(YAML frontmatter + markdown content) - At least one subagent defined in
.claude/agents/ - At least one hook in
.claude/hooks/and executable - Tested the skill by running
/skill-namein Claude Code - Committed all files to the repository
- Documented the workflow in a README or wiki
References
Section titled “References”- Claude Code Skills Documentation: https://claude.com/docs/skills
- Subagents Guide: https://claude.com/docs/subagents
- Hooks Documentation: https://claude.com/docs/hooks
- YAML Syntax: https://yaml.org/
- Composition Stack Reference: (From M07 study guide pre-work)