Skip to content
Development
Command

/ado-sync

Two-way sync between SpecWeave increment and Azure DevOps work item (push & pull by default)

From plugin
specweave
15673 skills20 agents73 commands
Install
> /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-sync

Context preview

What this command does when you run it.

Two-way sync between SpecWeave increment and Azure DevOps work item (push & pull by default)

Command definition

ado-sync.md
description: Two-way sync between SpecWeave increment and Azure DevOps work item (push & pull by default)

Sync ADO Work Item Command

**Usage**: `sw-ado:sync <increment-id> [options]`

**Purpose**: Two-way synchronization between SpecWeave increment and Azure DevOps work item

**Default**: Two-way sync (push & pull)

---

Options

  • `--direction <mode>`: Sync direction (default: `two-way`)
  • `two-way`: SpecWeave <-> ADO (default - recommended)
  • `to-ado`: SpecWeave -> ADO only (push progress)
  • `from-ado`: ADO -> SpecWeave only (pull updates)

Examples

# Two-way sync (default - both directions)
sw-ado:sync 0005

# Push only (one-way to ADO)
sw-ado:sync 0005 --direction to-ado

# Pull only (one-way from ADO)
sw-ado:sync 0005 --direction from-ado

---

Command Behavior

When user runs this command, Claude should:

0. Load Credentials from .env (MANDATORY FIRST)

**CRITICAL**: Read PAT from `.env` file, NOT from shell environment variables.

# Read PAT from .env file
ADO_PAT=$(grep '^AZURE_DEVOPS_PAT=' .env 2>/dev/null | cut -d'=' -f2)

if [ -z "$ADO_PAT" ]; then
  echo "ERROR: AZURE_DEVOPS_PAT not found in .env file"
  echo "Add to .env: AZURE_DEVOPS_PAT=your-pat-here"
  exit 1
fi

1. Check Permission Gate (MANDATORY FIRST STEP)

**Before ANY ADO write operations**, check permissions:

// 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;

// Permission check based on direction
if (direction === 'to-ado' || direction === 'two-way') {
  if (!canUpdateExternal) {
    console.log(`
❌ Permission Denied: ADO Write Operations Disabled

Cannot push changes to ADO (sync.settings.canUpdateExternalItems = false).

Options:
1. Enable writes: Set canUpdateExternalItems to true in config.json
2. Pull-only mode: sw-ado:sync ${incrementId} --direction from-ado
`);
    return;
  }
}

For `--direction from-ado` (pull-only), permission check is skipped as it's read-only.

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`);
  console.log('Available ADO profiles:', Object.entries(config?.sync?.profiles || {})
    .filter(([_, p]) => p.provider === 'ado')
    .map(([name]) => name)
    .join(', '));
  return;
}

const { organization, project } = profileConfig.config;
console.log(`Using ADO profile: ${profileName}`);
console.log(`  Organization: ${organization}`);
console.log(`  Project: ${project}`);

3. Invoke ADO Manager Skill

Use Skill tool: Skill({ skill: "sw-ado:ado-sync", args: "{direction} sync for increment {increment-id} with ADO.

IMPORTANT:
- Permission verified: canUpdateExternalItems={canUpdateExternal}
- Using profile: {profileName} (org: {organization}, project: {project})

Phase 1 - Pull FROM ADO:
1. Fetch work item #{workItemId} from ADO API
2. Detect changes: state, priority, iteration, comments
3. Apply ADO changes to increment metadata
4. Import team comments to increment notes

Phase 2 - Push TO ADO (if direction allows):
1. Read .specweave/increments/{increment-id}/tasks.md
2. Calculate: X/Y tasks complete (Z%)
3. Identify: Recently completed tasks
4. Format comment with progress update
5. Load work item ID from metadata.json
6. POST comment to ADO API using org: {organization}, project: {project}
7. Update work item state/fields

Display: Sync summary with profile used"

4. Display Result

Sync Summary for increment {increment-id}

Profile: {profileName}
  Organization: {organization}
  Project: {project}

Direction: {direction}

FROM ADO:
  State: Active -> Resolved
  Priority: 2 -> 1
  Comments: 3 new

TO ADO:
  Progress: 60% (6/10 tasks)
  Posted comment #98765

Work Item: https://dev.azure.com/{organization}/{project}/_workitems/edit/{workItemId}

---

Permission Check Matrix

| Direction | canUpdateExternalItems | Result | |-----------|------------------------|--------| | from-ado | any | Allowed (read-only) | | to-ado | false | Denied | | to-ado | true | Allowed | | two-way | false | Denied | | two-way | true | Allowed |

---

Profile Resolution

The command resolves the ADO profile in this order:

1. **Increment profile** (metadata.json -> external_sync.ado.profile) 2. **Global profile** (config.json -> sync.activeProfile)

This allows:

  • Different increments to sync to different ADO projects
  • No manual `activeProfile` switching needed
  • Automatic project targeting

---

Example Output

Two-way Sync (Default)

User: sw-ado:sync 0005-payment-integration

Claude:
Checking permissions...
  canUpdateExternalItems: true

Resolving ADO profile...
  Using: ado-my-project (from increment)
  Organization: acme-corp
  Project: My Project

Syncing...

FROM ADO:
  State changed: Active -> Resolved
  Iteration updated: Sprint 23 -> Sprint 24
  Priority changed: 2 -> 1
  3 new comments from team

TO ADO:
  Progress: 60% complete (6/10 tasks)
  Posted comment (ID: 98765)
  Updated completion field: 60%

Sync Complete!
Profile: ado-my-project
Work Item: https://dev.azure.com/acme-corp/My%20Project/_workitems/edit/12345

Permission Denied

User: sw-ado:sync 0005 --direction to-ado

Claude:
Checking permissions...
  canUpdateExternalItems: fals
Read more
Ships withspecweave

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.

Get the whole plugin