/ado-close
Close Azure DevOps work item when increment complete
> /plugin marketplace add anton-abyzov/specweave > /plugin install sw@specweave
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/ado-close
Context preview
What this command does when you run it.
Close Azure DevOps work item when increment complete
Command definition
ado-close.mddescription: Close Azure DevOps work item when increment complete
Close ADO Work Item Command
**Usage**: `sw-ado:close <increment-id>`
**Purpose**: Close ADO work item and add completion summary
---
Command Behavior
When user runs this command, Claude should:
1. Check Permission Gate (MANDATORY FIRST STEP)
**Before ANY ADO API calls**, check if status updates are allowed:
// Read .specweave/config.json
const config = JSON.parse(await fs.readFile('.specweave/config.json', 'utf-8'));
const canUpdateExternal = config?.sync?.settings?.canUpdateExternalItems ?? false;
const canUpdateStatus = config?.sync?.settings?.canUpdateStatus ?? false;
// Close requires both permissions (write to close, status to change state)
if (!canUpdateExternal || !canUpdateStatus) {
const missing = [];
if (!canUpdateExternal) missing.push('canUpdateExternalItems');
if (!canUpdateStatus) missing.push('canUpdateStatus');
console.log(`
❌ Permission Denied
Closing ADO work items requires these permissions:
${missing.map(p => ` - sync.settings.${p} = false (required: true)`).join('\n')}
To enable, update .specweave/config.json:
{
"sync": {
"settings": {
"canUpdateExternalItems": true,
"canUpdateStatus": true
}
}
}
`);
return;
}2. Resolve ADO Profile
Use the increment's stored profile or fall back to global activeProfile:
// Load increment metadata
const metadataPath = `.specweave/increments/${incrementId}/metadata.json`;
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
// Priority: increment profile > global activeProfile
let profileName = metadata?.external_sync?.ado?.profile;
if (!profileName) {
profileName = config?.sync?.activeProfile;
}
// Validate profile exists
const profileConfig = config?.sync?.profiles?.[profileName];
if (!profileConfig || profileConfig.provider !== 'ado') {
console.log(`❌ ADO profile "${profileName}" not found`);
return;
}
const { organization, project } = profileConfig.config;3. Validate Increment Completion
Before closing, verify the increment is actually complete:
// Check tasks.md for completion
const tasksPath = `.specweave/increments/${incrementId}/tasks.md`;
const tasksContent = await fs.readFile(tasksPath, 'utf-8');
const totalTasks = (tasksContent.match(/### T-\d+/g) || []).length;
const completedTasks = (tasksContent.match(/\[x\] completed/gi) || []).length;
if (completedTasks < totalTasks) {
console.log(`
⚠️ Increment not complete
Tasks: ${completedTasks}/${totalTasks} completed
Cannot close ADO work item until all tasks are done.
Complete remaining tasks first, then re-run this command.
`);
return;
}4. Invoke ADO Manager Skill
Use Skill tool: Skill({ skill: "sw-ado:ado-sync", args: "Close ADO work item for completed increment {increment-id}.
IMPORTANT:
- Permission verified: canUpdateExternalItems=true, canUpdateStatus=true
- Using profile: {profileName} (org: {organization}, project: {project})
Steps:
1. Validate: All tasks in tasks.md complete
2. Generate: Completion summary (duration, deliverables)
3. Load work item ID from metadata.json
4. PATCH work item: state = Closed (using org: {organization}, project: {project})
5. POST final comment with summary
6. Display: Closure confirmation with profile used"5. Display Result
✅ Closed ADO Work Item
Work Item: #{workItemId}
Profile: {profileName}
Organization: {organization}
Project: {project}
Increment: {increment-id}
Status: 100% complete ({total}/{total} tasks)
Duration: {days} days
Summary posted to ADO work item
URL: https://dev.azure.com/{organization}/{project}/_workitems/edit/{workItemId}---
Permission Requirements
This command requires **both** permissions:
| Permission | Required | Purpose | |------------|----------|---------| | canUpdateExternalItems | true | Write to ADO work item | | canUpdateStatus | true | Change work item state to Closed |
---
Example Output
Success
User: sw-ado:close-workitem 0005-payment-integration
Claude:
Checking permissions...
canUpdateExternalItems: true
canUpdateStatus: true
Resolving ADO profile...
Using: ado-my-project (from increment)
Organization: acme-corp
Project: My Project
Validating completion...
Tasks: 10/10 complete
Closing work item...
✅ Closed ADO Epic #12345
Profile: ado-my-project
Increment: 0005-payment-integration
Status: 100% complete (10/10 tasks)
Duration: 3 days
Summary posted to ADO work item
URL: https://dev.azure.com/acme-corp/My%20Project/_workitems/edit/12345
Permission Denied
User: sw-ado:close-workitem 0005
Claude:
Checking permissions...
canUpdateExternalItems: false
canUpdateStatus: false
❌ Permission Denied
Closing ADO work items requires:
- sync.settings.canUpdateExternalItems = true
- sync.settings.canUpdateStatus = true
Update .specweave/config.json to enable these permissions.
Incomplete Increment
User: sw-ado:close-workitem 0005
Claude:
Checking permissions...
canUpdateExternalItems: true
canUpdateStatus: true
Validating completion...
⚠️ Increment not complete
Tasks: 6/10 completed
Cannot close ADO work item until all tasks are done.
Complete remaining tasks:
- T-007: Add refund functionality
- T-008: Implement subscriptions
- T-009: Add analytics
- T-010: Security audit
---
Related
| Command | Purpose | |---------|---------| | `sw-ado:pull` | Pull changes from ADO | | `sw-ado:push` | Push progress to ADO | | `sw-ado:sync` | Two-way sync | | `sw-ado:create` | Create ADO work item | | `sw-ado:status` | Check sync status |
Read more
description: Close Azure DevOps work item when increment complete
Close ADO Work Item Command
**Usage**: `sw-ado:close <increment-id>`
**Purpose**: Close ADO work item and add completion summary
---
Command Behavior
When user runs this command, Claude should:
1. Check Permission Gate (MANDATORY FIRST STEP)
**Before ANY ADO API calls**, check if status updates are allowed:
// Read .specweave/config.json
const config = JSON.parse(await fs.readFile('.specweave/config.json', 'utf-8'));
const canUpdateExternal = config?.sync?.settings?.canUpdateExternalItems ?? false;
const canUpdateStatus = config?.sync?.settings?.canUpdateStatus ?? false;
// Close requires both permissions (write to close, status to change state)
if (!canUpdateExternal || !canUpdateStatus) {
const missing = [];
if (!canUpdateExternal) missing.push('canUpdateExternalItems');
if (!canUpdateStatus) missing.push('canUpdateStatus');
console.log(`
❌ Permission Denied
Closing ADO work items requires these permissions:
${missing.map(p => ` - sync.settings.${p} = false (required: true)`).join('\n')}
To enable, update .specweave/config.json:
{
"sync": {
"settings": {
"canUpdateExternalItems": true,
"canUpdateStatus": true
}
}
}
`);
return;
}2. Resolve ADO Profile
Use the increment's stored profile or fall back to global activeProfile:
// Load increment metadata
const metadataPath = `.specweave/increments/${incrementId}/metadata.json`;
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
// Priority: increment profile > global activeProfile
let profileName = metadata?.external_sync?.ado?.profile;
if (!profileName) {
profileName = config?.sync?.activeProfile;
}
// Validate profile exists
const profileConfig = config?.sync?.profiles?.[profileName];
if (!profileConfig || profileConfig.provider !== 'ado') {
console.log(`❌ ADO profile "${profileName}" not found`);
return;
}
const { organization, project } = profileConfig.config;3. Validate Increment Completion
Before closing, verify the increment is actually complete:
// Check tasks.md for completion
const tasksPath = `.specweave/increments/${incrementId}/tasks.md`;
const tasksContent = await fs.readFile(tasksPath, 'utf-8');
const totalTasks = (tasksContent.match(/### T-\d+/g) || []).length;
const completedTasks = (tasksContent.match(/\[x\] completed/gi) || []).length;
if (completedTasks < totalTasks) {
console.log(`
⚠️ Increment not complete
Tasks: ${completedTasks}/${totalTasks} completed
Cannot close ADO work item until all tasks are done.
Complete remaining tasks first, then re-run this command.
`);
return;
}4. Invoke ADO Manager Skill
Use Skill tool: Skill({ skill: "sw-ado:ado-sync", args: "Close ADO work item for completed increment {increment-id}.
IMPORTANT:
- Permission verified: canUpdateExternalItems=true, canUpdateStatus=true
- Using profile: {profileName} (org: {organization}, project: {project})
Steps:
1. Validate: All tasks in tasks.md complete
2. Generate: Completion summary (duration, deliverables)
3. Load work item ID from metadata.json
4. PATCH work item: state = Closed (using org: {organization}, project: {project})
5. POST final comment with summary
6. Display: Closure confirmation with profile used"5. Display Result
✅ Closed ADO Work Item
Work Item: #{workItemId}
Profile: {profileName}
Organization: {organization}
Project: {project}
Increment: {increment-id}
Status: 100% complete ({total}/{total} tasks)
Duration: {days} days
Summary posted to ADO work item
URL: https://dev.azure.com/{organization}/{project}/_workitems/edit/{workItemId}---
Permission Requirements
This command requires **both** permissions:
| Permission | Required | Purpose | |------------|----------|---------| | canUpdateExternalItems | true | Write to ADO work item | | canUpdateStatus | true | Change work item state to Closed |
---
Example Output
Success
User: sw-ado:close-workitem 0005-payment-integration Claude: Checking permissions... canUpdateExternalItems: true canUpdateStatus: true Resolving ADO profile... Using: ado-my-project (from increment) Organization: acme-corp Project: My Project Validating completion... Tasks: 10/10 complete Closing work item... ✅ Closed ADO Epic #12345 Profile: ado-my-project Increment: 0005-payment-integration Status: 100% complete (10/10 tasks) Duration: 3 days Summary posted to ADO work item URL: https://dev.azure.com/acme-corp/My%20Project/_workitems/edit/12345
Permission Denied
User: sw-ado:close-workitem 0005 Claude: Checking permissions... canUpdateExternalItems: false canUpdateStatus: false ❌ Permission Denied Closing ADO work items requires: - sync.settings.canUpdateExternalItems = true - sync.settings.canUpdateStatus = true Update .specweave/config.json to enable these permissions.
Incomplete Increment
User: sw-ado:close-workitem 0005 Claude: Checking permissions... canUpdateExternalItems: true canUpdateStatus: true Validating completion... ⚠️ Increment not complete Tasks: 6/10 completed Cannot close ADO work item until all tasks are done. Complete remaining tasks: - T-007: Add refund functionality - T-008: Implement subscriptions - T-009: Add analytics - T-010: Security audit
---
Related
| Command | Purpose | |---------|---------| | `sw-ado:pull` | Pull changes from ADO | | `sw-ado:push` | Push progress to ADO | | `sw-ado:sync` | Two-way sync | | `sw-ado:create` | Create ADO work item | | `sw-ado:status` | Check sync status |
Spec-first AI development: describe a feature → AI creates spec + plan + tasks, builds autonomously, syncs to GitHub/JIRA. Domain-expert skills for PM, Architect, Frontend, QA learn your patterns permanently. Claude Code, Codex, Cursor, Copilot & more.
Repo: anton-abyzov/specweave
Other commands on specweave.
- /abandon
Abandon an incomplete increment (requirements changed, obsolete)
Open command - /ado-cleanup-duplicates
Clean up duplicate Azure DevOps work items for a Feature. Finds work items with duplicate titles and closes all except the first created item.
Open command - /ado-clone
Clone Azure DevOps repositories to local workspace. Use after init if cloning was skipped, or to add repos later.
Open command - /ado-create
Create Azure DevOps work item from SpecWeave increment
Open command - /ado-import-areas
Import Azure DevOps area paths from a project and map them to SpecWeave projects. Creates 2-level directory structure with area path-based organization.
Open command - /ado-import-projects
Import additional Azure DevOps projects post-init with area path mapping, filtering, and dry-run preview
Open command

