From agentic-toolkit
Pick up User Story work items from Azure DevOps, assign to developer, create git branch, investigate, plan, and implement the feature
How this skill is triggered — by the user, by Claude, or both
Slash command
/agentic-toolkit:pickup-featureThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
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.
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="[email protected]:${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)
npx claudepluginhub corbinatorx/devops-ai-toolkit-claude-plugin --plugin agentic-toolkitGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.