AI Developer AssistantA VS Code extension that generates implementation proposals from Azure DevOps work items through natural conversation, grounded in Microsoft's official Azure DevOps MCP server. OverviewMention
Current status: User Stories 1-5 implemented ✅
Features
InstallationPrerequisites
Install from VSIX
ConfigurationOn first activation you'll be prompted for your Azure DevOps organization and project. After that, the embedded connector signs in interactively (no PAT prompt by default). Settings (
|
| Setting | Type | Default | Description |
|---|---|---|---|
devagent.organization |
string | "" |
Azure DevOps organization name (e.g. contoso for https://dev.azure.com/contoso). |
devagent.project |
string | "" |
Azure DevOps project name (e.g. MyProject). |
devagent.pollIntervalSeconds |
number | 45 |
How often (30-60s) to poll for new @devagent mentions while VS Code is active. |
devagent.candidateQueryScope |
enum | assigned-to-me |
Scope of the candidate work item query (FR-017). Only work items assigned to you are polled. |
devagent.auth.mode |
enum | interactive |
How the embedded connector authenticates: interactive (Microsoft/Entra sign-in, default), azcli (reuse az login), or pat (Personal Access Token fallback). |
devagent.generation.maxLookups |
number | 10 |
Max on-demand grounding lookups (code search, work item lookups, file reads) per proposal (FR-006, range 1-100). |
devagent.sharedConnector.allowWrites |
boolean | false |
Expose Azure DevOps write tools (create PR, link work item, add comment) to your own Copilot agent-mode chat via the shared connector (FR-013). |
devagent.models.workItemTriage |
array of strings | ["claude-haiku-4.5", "gpt-4o-mini", "gpt-4.1"] |
Ordered fallback list of vscode.lm model families used to condense a work item into a summary before planning (small/cheap, fast). The final fallback is always "any available Copilot model" (FR-001, FR-002, FR-007). |
devagent.models.planning |
array of strings | ["claude-opus-4.1", "gpt-5", "gpt-4.1", "gpt-4o", "gpt-4"] |
Ordered fallback list of vscode.lm model families used for the planning phase, which gathers grounding context and produces a structured plan (most capable/reasoning-oriented). The final fallback is always "any available Copilot model" (FR-001, FR-002, FR-007). |
devagent.models.implementation |
array of strings | ["claude-sonnet-4.5", "gpt-4.1", "gpt-4o", "gpt-4"] |
Ordered fallback list of vscode.lm model families used for the implementation phase, which turns the plan into the final proposal (balanced coding-oriented). The final fallback is always "any available Copilot model" (FR-001, FR-002, FR-007). |
Usage
1. Open your workspace
Open the Azure Repos repository you want to work with in VS Code.
2. Mention @devagent
In an Azure DevOps work item assigned to you:
- Add a comment mentioning
@devagent - The extension polls and detects the mention (within
pollIntervalSeconds, default 45s) - A proposal appears in VS Code
3. Review the proposal
The extension shows:
- Explanation — what the proposal does and why
- Proposed changes — files to modify and specific changes
- Lookup audit — which read-only tools (
search_code,wit_get_work_item, file reads) were used to ground the proposal - Actions — Accept, Decline, or continue the conversation to refine
Important: Proposals are inert — nothing changes until you Accept.
4. Accept
Accepting runs a deterministic, AI-free transaction:
- Apply the proposed changes locally
- Create a branch
devagent/<work-item-id>-<slug>, commit, and push via local git - Open a pull request against the default branch
- Link the PR to the work item
- Post a traceability comment on the work item
If a step fails, the chat shows per-step status with a Resume button — resuming skips steps that already completed, so exactly one PR/comment is ever created.
5. Decline
Declining is a strict no-op: no branch, commit, PR, or comment is created.
6. Clarification for vague work items
If the work item lacks detail, the extension asks for clarification instead of guessing:
- Add a description or acceptance criteria
- Mention
@devagentagain for a new proposal
How proposal generation works
When you mention @devagent <work item id> in Copilot Chat, the extension builds the proposal in
three sequential phases (src/generation/generator.ts), each driven by an independently
configurable Copilot model:
- Triage — a single, no-tools model call condenses the work item's title, description, and
acceptance criteria into a concise Work Item Summary. It uses the
devagent.models.workItemTriagelist (small/fast models). If no triage model is available the phase is skipped and planning falls back to the raw work item fields. The summary is cached on the conversation, so follow-up requests in the same conversation reuse it instead of re-running triage. - Planning — an agentic tool-calling loop (
devagent.models.planning, the most capable list) grounds a structured Plan in your codebase and the work item. This is the only phase that gathers external context, and it is the sole source of the Lookup audit shown with the proposal. - Implementation — a second bounded loop (
devagent.models.implementation) turns that Plan into the final Explanation and Proposed changes. It reads only local workspace files over the paths the Plan named; these reads are not added to the planning Lookup audit.
The phases hand off in order: the triage summary seeds planning, and the planning Plan (plus its lookup audit) seeds implementation. A phase that cannot find any model aborts generation with a "No Copilot model is available" error.
Per-phase model selection
Each phase reads its own ordered list of vscode.lm model families from devagent.models.<phase>
and tries them in order, always appending "any available Copilot model" as the final fallback
(src/generation/model-selection.ts). The first family that returns a model wins; generation only
fails for a phase if even the catch-all returns nothing.
Read-only tool bridge and the lookup cap
The model never touches your repository or Azure DevOps directly. During the planning and
implementation phases it can request context only through a fixed allowlist of read-only
devagent_* tools (src/generation/tool-bridge.ts):
- Planning (full bridge):
devagent_search_code,devagent_search_workitems,devagent_get_work_item,devagent_get_work_items(Azure DevOps, via the embedded MCP connector), plus the local file tools below. - Implementation (local-only bridge):
devagent_read_fileanddevagent_list_dironly.
No write tools are ever advertised to the model. Every lookup counts against
devagent.generation.maxLookups (default 10, range 1-100); once the cap is reached the loop forces
a final no-tools round and the proposal is flagged as having hit the lookup cap. If the Azure
DevOps connector is unavailable, the bridge degrades to local-only and notes this in the
Explanation.
Known limitations
- Pending proposals are held in memory only. Between generation and your Accept/Decline, a
proposal lives in an in-memory map in the running extension host (
src/chat/participant.ts); it is not persisted. If you reload the window, restart VS Code, or the extension host restarts, that pending proposal is lost — clicking Accept or Decline on the earlier chat response then shows "this proposal is no longer available." The conversation itself is saved, so just mention@devagent <work item id>again to regenerate a fresh proposal you can act on. (Already-started Accept transactions are unaffected: those are persisted to extension storage and are resumable.)
Shared connector for Copilot agent mode
The extension registers an McpServerDefinitionProvider (devagent.azureDevOpsConnector) so
your own Copilot Chat agent mode automatically gets the Azure DevOps MCP tools — no manual
mcp.json editing required. By default this surface is read-only
(devagent.sharedConnector.allowWrites: false); set it to true to also expose write tools,
subject to VS Code's own per-tool approval prompts.
Architecture
Core principles (from constitution.md)
- Work item is source of truth — proposals ground in work item intent
- Human approval mandatory — nothing happens without explicit Accept
- Codebase-grounded — context from your open workspace via agentic lookups, not a fixed slice
- Traceable — all Accept actions link back to the work item
- Secure — your identity, your Copilot seat; write tools are never exposed to the model; nothing hosted or shared
Components
src/
├── extension.ts # Activation & wiring
├── mcp/ # Embedded MCP client + shared connector definition provider
├── poller/ # Mention detection via MCP tool calls, claim dedup, single-instance lock
├── chat/ # @devagent participant
├── generation/ # Agentic grounding + Copilot LM API integration, tool bridge
├── accept/ # Deterministic Accept transaction (branch/commit/PR/link/comment)
├── adapters/ # Work item read models built on MCP tool responses
├── workspace/ # Context gathering
├── state/ # Secrets, claims & globalState
└── models/ # Domain types
Embedded vs. shared connector
- Embedded connector: the extension spawns its own
@azure-devops/mcpserver process for polling (deterministic, no LLM) and for agentic grounding during proposal generation. - Shared connector: a separate definition registered with VS Code so your own Copilot agent
mode chat sessions can use the same Azure DevOps tools, independently configured via
devagent.sharedConnector.allowWrites.
Development
Build & Test
npm install # Install dependencies
npm run compile # Type-check
npm run build # Bundle with esbuild
npm run watch # Watch mode
npm run package # Create .vsix
Lint & Format
npm run lint # ESLint
npm run format # Prettier check
Test
npm test # Run @vscode/test-electron unit, integration, and contract tests
See specs/002-mcp-architecture/quickstart.md for the full end-to-end validation scenarios (Scenarios 1-6, mapping to SC-001…SC-008).
Technical Stack
- Language: TypeScript
- Runtime: VS Code Extension Host (Node.js 20.x)
- APIs: VS Code Extension API, Language Model API (
vscode.lm), Chat Participant API, MCP Server Definition Provider API - External:
@azure-devops/mcp(pinned2.7.0), spawned locally over stdio via@modelcontextprotocol/sdk - Storage: VS Code SecretStorage (PAT fallback only), globalState (claims, conversations)
- Build: esbuild, TypeScript, vsce
- Test: @vscode/test-electron, Mocha
Constraints & Guarantees
Security (FR-008, FR-009, FR-010, FR-016)
- Default auth is interactive Entra ID sign-in; PAT is a documented fallback only, never written to disk or logs
- Uses only your developer identity and your Copilot seat
- Write tools (create PR, link work item, add comment) are never exposed to the model — only called deterministically by extension code after explicit Accept
- No hosted components, no shared storage — the MCP server runs as a local child process under your identity
Safety (FR-004, FR-012, FR-014)
- Proposals are inert until explicit Accept
- Decline is a strict no-op
- No autonomous merges, no protected branch pushes
- No work item state changes beyond traceability comments and PR links
Reliability (FR-006, FR-012, FR-015)
- Exactly-once processing per mention (claim-based dedup, single-instance poller lock)
- Capped agentic lookups per proposal (
devagent.generation.maxLookups) - Resumable Accept transaction — exactly one PR/comment even after a mid-transaction failure
- Clear failure reporting (never silent, never indefinite hangs)
Support & Feedback
For issues:
- Check the "AI Developer Assistant" output channel in VS Code
- Review structured logs for event/context details
- See specs/002-mcp-architecture/ for design rationale
License
Private / Internal Use (update as appropriate for your organization)
Version: 0.1.0 Spec: specs/002-mcp-architecture/spec.md Architecture: .specify/memory/constitution.md