From agentic-toolkit
Pick up User Story work items from Azure DevOps, assign to developer, create git branch, investigate, plan, and implement the feature
npx claudepluginhub corbinatorx/devops-ai-toolkit-claude-plugin --plugin agentic-toolkitThis skill is limited to using the following tools:
Complete workflow for picking up "User Story" work items from Azure DevOps. Handles assignment, branch creation, requirements analysis, implementation planning, coding, and testing in an 11-step process.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Designs, implements, and audits WCAG 2.2 AA accessible UIs for Web (ARIA/HTML5), iOS (SwiftUI traits), and Android (Compose semantics). Audits code for compliance gaps.
Complete workflow for picking up "User Story" work items from Azure DevOps. Handles assignment, branch creation, requirements analysis, implementation planning, coding, and testing in an 11-step process.
This Skill integrates with Azure DevOps for work item management and follows {Product} git branching conventions.
This Skill automatically activates when users mention:
"Pick up user story 25200"
"Work on story #25150"
"Pickup feature 25175"
"I need to work on user story 25180"
This Skill uses shared helper modules for common patterns:
Azure DevOps (.claude/shared/azure-devops/):
Git (.claude/shared/git/):
feature/{id}-{slug}Teams (.claude/shared/teams/):
.claude/techops-config.json (flow_url, team_id, channel_id)TeamsChannelMessageIdSee shared module READMEs for detailed patterns and examples.
First, determine the work item provider:
provider=$(jq -r '.work_items.provider // empty' .claude/techops-config.json 2>/dev/null)
if [ -z "$provider" ]; then
echo "Error: No work item provider configured. Set work_items.provider in .claude/techops-config.json"
exit 1
fi
Use mcp__azure-devops__wit_get_work_item to fetch user story details.
Parameters:
{
"project": "ERM",
"id": work_item_id,
"expand": "relations"
}
Extract:
work_item_id: Use the id field from response (integer)Use mcp__notion__notion-fetch to fetch the page.
Parameters:
{
"pageId": "{user_provided_id}"
}
CRITICAL - Work Item ID Extraction:
# The work_item_id for worktree creation MUST come from the page response:
work_item_id = notion_page.id # Page UUID, unique per work item
# DO NOT use database_id from config - it's the same for ALL work items!
# WRONG: work_item_id = config.work_items.providers.notion.database_id
Extract (using property_mappings from config):
work_item_id: Use the page's id field from response (UUID)Reference: See .claude/shared/work-items/providers/notion/README.md for property mapping patterns.
Present formatted summary:
## User Story #{work_item_id}: {title}
**Current State:** {state}
**Assigned To:** {assignee or "Unassigned"}
**Priority:** {priority}
**Story Points:** {story_points}
**Iteration:** {iteration_path}
**Reported:** {created_date}
**Last Updated:** {changed_date}
### Description
{description}
### Acceptance Criteria
{acceptance_criteria}
### Related Work Items
- Parent Feature: #{id}: {title} ({state})
- Child Tasks:
- #{id}: {title} ({state})
Engage in natural conversation to gather additional context:
Allow user to provide extra information or say "no"/"none"/"proceed" to continue.
Store any additional context for use in the implementation plan.
Use mcp__azure-devops__core_get_identity_ids:
Parameters:
{
"searchFilter": "Corbin Taylor"
}
Store the identity ID for assignment update.
Reference: See .claude/shared/azure-devops/README.md for identity resolution patterns.
Use mcp__azure-devops__wit_update_work_item:
Parameters:
{
"id": work_item_id,
"updates": [
{
"op": "add",
"path": "/fields/System.State",
"value": "Active"
},
{
"op": "add",
"path": "/fields/System.AssignedTo",
"value": "{identity_id from Step 4}"
}
]
}
IMPORTANT:
Reference: See .claude/shared/azure-devops/README.md for work item update patterns.
Use mcp__azure-devops__wit_add_work_item_comment:
Parameters:
{
"project": "ERM",
"workItemId": work_item_id,
"comment": "{comment_text}",
"format": "html"
}
Comment text:
User story picked up by Corbin Taylor for implementation via Claude Code /pickup-feature command
User story picked up by Corbin Taylor for implementation via Claude Code /pickup-feature command (previously assigned to {previous_assignee})
If the work item has a Custom.TeamsChannelMessageId field populated, reply to the Teams thread to notify the team.
Prerequisites:
.claude/techops-config.json from the consuming repoteams.flow_url, teams.team_id, teams.channel_idSkip if:
Custom.TeamsChannelMessageId is empty or not setHTTP Request:
curl -X POST "{flow_url}" \
-H "Content-Type: application/json" \
-d '{
"action": "reply",
"teamId": "{team_id}",
"channelId": "{channel_id}",
"messageId": "{TeamsChannelMessageId from Step 1}",
"content": "๐ก **Feature Picked Up**\n\nUser story #{work_item_id} has been picked up by **Corbin Taylor** for implementation.\n\n**Branch:** `feature/{work_item_id}-{slug}`\n\n_via Claude Code /pickup-feature command_"
}'
On Success: Log that Teams thread was notified.
On Failure: Log warning but continue workflow (Teams notification is non-blocking).
Reference: See .claude/shared/teams/README.md for Logic App patterns.
Generate branch name: feature/{work_item_id}-{title-slug}
Branch slug generation (7-step algorithm from .claude/shared/git/README.md):
' โ remove, /\ โ -, & โ and, + โ plusExamples:
feature/25200-add-user-notification-preferencesfeature/25099-implement-p95-p99-metrics-displayFirst, check if worktree mode is enabled in .claude/techops-config.json:
worktree_enabled=$(cat .claude/techops-config.json 2>/dev/null | jq -r '.worktree.enabled // false')
If worktree.enabled is true, create an isolated worktree for this feature:
Custom.Repository field from Step 1.claude/shared/worktree/README.mdif [ "$worktree_enabled" = "true" ]; then
# Get repository from work item
repository_field="{work_item.Custom.Repository}"
# Parse repo name
repo_name=$(echo "$repository_field" | sed 's|.*/||' | sed 's|\.git$||')
# Build paths
user=$(whoami)
base_path="/home/${user}/workspace/github/agent-worktrees"
repo_cache="/home/${user}/.claude/repos"
worktree_path="${base_path}/${repo_name}-{work_item_id}"
cached_repo="${repo_cache}/${repo_name}.git"
branch_name="feature/{work_item_id}-{slug}"
# Create directories
mkdir -p "$base_path" "$repo_cache"
# Check if worktree already exists
if [ -d "$worktree_path" ]; then
cd "$worktree_path"
echo "Using existing worktree: $worktree_path"
else
# Ensure bare repo cache exists
if [ ! -d "$cached_repo" ]; then
repo_url="git@github.com:${repository_field}.git"
git clone --bare "$repo_url" "$cached_repo"
else
git -C "$cached_repo" fetch --all --prune
fi
# Fetch latest main
git -C "$cached_repo" fetch origin main:main 2>/dev/null || \
git -C "$cached_repo" fetch origin master:master
# Create worktree with new branch
git -C "$cached_repo" worktree add -b "$branch_name" "$worktree_path" main 2>/dev/null || \
git -C "$cached_repo" worktree add -b "$branch_name" "$worktree_path" master
cd "$worktree_path"
git push -u origin "$branch_name" 2>/dev/null || true
fi
fi
Output (worktree mode):
## Worktree Created
Working in isolated worktree: `/home/{user}/workspace/github/agent-worktrees/{repo}-{work_item_id}`
**Repository:** {repository_field}
**Branch:** `feature/{work_item_id}-{slug}`
This worktree is independent of your main workspace. All changes will be made here.
If worktree mode is disabled, use existing behavior:
# Check if branch exists
git rev-parse --verify feature/{work_item_id}-{slug} 2>/dev/null
If exists: git checkout feature/{work_item_id}-{slug}
If not: git checkout -b feature/{work_item_id}-{slug}
Inform user of branch created or checked out.
Reference:
.claude/shared/git/README.md for branch creation patterns.claude/shared/worktree/README.md for worktree patternsCreate detailed implementation plan by researching codebase.
Research Phase:
Plan Structure:
# Feature Implementation Plan: #{work_item_id} - {title}
**Created:** {timestamp}
**Story State:** {old_state} โ Active
**Assigned To:** Corbin Taylor
**Branch:** feature/{work_item_id}-{slug}
**Story Points:** {points}
## 1. Feature Summary
{1-2 paragraph summary with business value and user benefit}
## 2. Requirements Analysis
### User Story
{description from work item}
### Acceptance Criteria
{numbered list of acceptance criteria}
### Additional Context (from Step 3)
{context provided by user}
### Out of Scope
{explicitly state what is NOT included in this story}
## 3. Technical Approach
### Architecture Overview
{how this feature fits into existing architecture}
### Design Decisions
**Decision 1:** {choice} - **Rationale:** {reason}
**Decision 2:** {choice} - **Rationale:** {reason}
### Integration Points
- {existing service/component it integrates with}
- {API endpoints it consumes}
- {databases/stores it uses}
## 4. Implementation Details
### API Layer Changes (`api/`)
**Files to Create:**
- `api/src/{product}_api/features/{feature}/models.py` - Pydantic request/response models
- `api/src/{product}_api/features/{feature}/controller.py` - HTTP logic
- `api/src/{product}_api/features/{feature}/router.py` - FastAPI routes
**Files to Modify:**
- `api/src/{product}_api/main.py` - Register new router
### Application Layer Changes (`application/`)
**Files to Create:**
- `application/src/{product}_application/features/{feature}/models.py` - SQLAlchemy entities
- `application/src/{product}_application/features/{feature}/service.py` - Business logic
- `application/src/{product}_application/features/{feature}/repository.py` - Data access
**Database Changes:**
- Migration: `application/alembic/versions/{timestamp}_{description}.py`
- Tables: {list new tables}
- Indexes: {list indexes for performance}
### UI Changes (if applicable) (`ui/`)
**Files to Create:**
- `ui/src/features/{feature}/components/` - React components
- `ui/src/features/{feature}/hooks/` - Custom hooks
- `ui/src/features/{feature}/services/` - API client
## 5. Testing Strategy
### Unit Tests
**API Tests** (`api/tests/`):
- Test request validation
- Test response serialization
- Test error handling
**Application Tests** (`application/tests/`):
- Test business logic in services
- Test repository data access
- Test entity behavior
### Integration Tests
- End-to-end API endpoint tests
- Database integration tests
- External service integration (if applicable)
### Manual Testing
1. {manual test step 1}
2. {manual test step 2}
3. **Expected Result:** {what should happen}
## 6. Implementation Checklist
- [ ] Create API layer (models, controller, router)
- [ ] Create Application layer (entities, service, repository)
- [ ] Create database migration
- [ ] Write unit tests (API layer)
- [ ] Write unit tests (Application layer)
- [ ] Write integration tests
- [ ] Create UI components (if applicable)
- [ ] Update API documentation
- [ ] Manual testing
- [ ] Verify acceptance criteria met
## 7. Architecture Compliance
**{Product} Architecture (from CLAUDE.md):**
- API layer: FastAPI routers, Pydantic models, HTTP only
- Application layer: Business logic, SQLAlchemy entities, repositories
- Feature-based organization: `features/{feature}/`
- Constructor injection with protocol-based interfaces
- Clean Architecture: No business logic in API layer
## 8. Performance Considerations
- Database query optimization (indexes, eager loading)
- API response caching (if applicable)
- Pagination for large result sets
- Async/await patterns
## 9. Security Considerations
- Input validation in Pydantic models
- Authorization checks in controllers
- SQL injection prevention (parameterized queries)
- No secrets in code
## 10. Deployment Notes
- Database migration must run before deployment
- Feature flags (if applicable)
- Backward compatibility considerations
---
**Ready to implement?** Reply 'yes' or provide feedback.
Present plan and wait for approval.
User responses:
Iterate until user approves.
Once approved, implement the feature:
Follow {Product} Architecture:
API Layer (api/):
Application Layer (application/):
Feature Organization:
features/{feature_name}/
โโโ models.py # Pydantic (API) / SQLAlchemy (Application)
โโโ controller.py # HTTP logic (API only)
โโโ router.py # FastAPI routes (API only)
โโโ service.py # Business logic (Application)
โโโ repository.py # Data access (Application)
โโโ __init__.py
Code Quality:
Testing:
After implementation, BLOCK and require manual testing.
## โ
Implementation Complete - Manual Testing Required
### Changes Made
{summary of files created/modified}
### Testing Instructions
#### Manual Test Steps
1. {step 1 from plan}
2. {step 2}
3. **Expected Result:** {what should happen}
#### Acceptance Criteria Verification
- [ ] {acceptance criterion 1}
- [ ] {acceptance criterion 2}
- [ ] {acceptance criterion 3}
#### Verification Checklist
- [ ] All acceptance criteria met
- [ ] No regression in related functionality
- [ ] All automated tests pass
- [ ] Code follows project standards
- [ ] Aligns with {Product} architecture
### Running Tests Locally
**API Tests:**
```bash
cd api/
poetry run pytest
poetry run flake8 .
Application Tests:
cd application/
pytest -v --strict-markers --cov=.
UI Tests (if applicable):
cd ui/
npm test
npm run lint
After manual testing, confirm feature works before committing.
Wait for user confirmation that manual testing passed.
## Error Handling
### Work Item Not Found
โ Work Item Not Found
Work item #{id} was not found in Azure DevOps project "ERM".
Please verify:
### Wrong Work Item Type
โ Invalid Work Item Type
Work item #{id} is type "{type}", but /pickup-feature requires "User Story".
Use instead:
### Identity Resolution Failed
โ User Identity Not Found
Could not find Azure DevOps identity for "Corbin Taylor".
Troubleshooting:
### Git Branch Creation Failed
โ Git Branch Creation Failed
Error: {error_message}
Troubleshooting:
### Teams Notification Failed (Non-Blocking)
โ ๏ธ Teams Notification Skipped
Could not notify Teams thread: {error_message}
This is non-blocking. The workflow continues.
Possible causes:
## Integration with Workflow
**Downstream:**
- After feature is implemented and tested, use `/commit` command
- Then use `/create-pr` to create pull request
- Link PR back to work item
**Related Skills:**
- `pickup-bug` - Similar workflow for Bug work items
- `implement-task` - For implementing tasks from blueprints
- `blueprint` - For creating architecture blueprints for new features
**Related Commands:**
- `/commit` - Smart commit with conventional message
- `/create-pr` - Create pull request with auto-generated description
## Notes
- This Skill is specific to "User Story" work items
- Always reassigns to Corbin Taylor regardless of current assignment
- Branch naming follows {Product} git conventions (`feature/{id}-{slug}`)
- Implementation plans are comprehensive and require approval
- Manual testing is mandatory before considering feature complete
- Follows Clean Architecture and feature-based organization
- References {Product} CLAUDE.md for architecture patterns
- Pre-commit hooks will validate formatting and linting
- Acceptance criteria from work item must be explicitly verified
- Teams notification is optional and non-blocking (requires `TeamsChannelMessageId` field and config)