Replace the current GitHub Models API + manual token authentication with the Copilot SDK (@github/copilot-sdk), making Team X-Ray a showcase for building VS Code extensions powered by Copilot's agentic runtime.
User pastes GitHub token → TokenManager stores in SecretStorage
→ ExpertiseAnalyzer gathers git data locally
→ Sends data blob to GitHub Models API (https://models.github.ai/inference)
→ Parses JSON response → Webview
Copilot SDK auto-authenticates via user's Copilot subscription (or BYOK)
→ ExpertiseAnalyzer gathers git data locally (unchanged)
→ Creates CopilotClient session with custom tools
→ Agent calls our tools to get team data
→ Agent returns structured analysis → Webview
Key wins:
- No manual token creation/pasting for AI analysis
- Custom tools let the agent request exactly the data it needs
- Streaming support for progressive results
- BYOK fallback for users without Copilot subscription
- Hooks for logging and error recovery
New file: src/core/copilot-service.ts
This replaces the AI analysis portion of expertise-analyzer.ts. It manages:
- CopilotClient lifecycle (start/stop with extension lifecycle)
- Session creation with custom system message
- Custom tools that expose git analysis data to the agent
- Response parsing
// Core interface
export class CopilotService {
private client: CopilotClient | null = null;
private outputChannel: vscode.OutputChannel;
async initialize(): Promise<void> // Start CopilotClient
async dispose(): Promise<void> // Stop CopilotClient
async analyzeTeam(data: RepositoryData, repoStats: RepositoryStats): Promise<ExpertiseAnalysis>
async analyzeFileExpert(filePath: string, data: RepositoryData): Promise<Expert[]>
isAvailable(): boolean // Check if Copilot CLI is accessible
}Custom tools to expose:
| Tool Name | Description | Returns |
|---|---|---|
get_contributors |
Get all git contributors with commit counts | GitContributor[] |
get_recent_commits |
Get recent commits with authors and messages | GitCommit[] |
get_file_experts |
Get contributors for a specific file | Expert candidates |
get_repo_stats |
Get repository size, languages, activity level | RepositoryStats |
get_collaboration_patterns |
Get co-authorship and review patterns | Collaboration data |
System message (append mode):
You are a team expertise analyst helping engineering managers discover the humans behind their codebase.
Use the provided tools to gather repository data, then analyze:
1. Each contributor's expertise areas, communication style, and hidden strengths
2. Team health: knowledge silos, single points of failure, collaboration gaps
3. Management insights: risks, opportunities, mentorship matches, growth paths
Always respond with JSON matching the ExpertiseAnalysis schema.
Focus on human qualities — not just code metrics.
Extract from expertise-analyzer.ts:
- Move AI prompt construction →
CopilotService(system message + tool responses) - Move AI response parsing →
CopilotService.parseAnalysisResponse() - Move data chunking logic →
CopilotService(infinite sessions handle context limits automatically) - Keep git data gathering logic in ExpertiseAnalyzer (GitService calls, file listing, sampling)
- Keep fallback analysis logic (for when Copilot is unavailable)
ExpertiseAnalyzer becomes a thin orchestrator:
assessRepositorySize() → gatherRepositoryData() → copilotService.analyzeTeam() → saveAnalysis()
↓ (if unavailable)
createFallbackAnalysis()
TokenManager changes:
- Keep TokenManager for GitHub API access (user profile, repo checks) — this is separate from AI auth
- Add new
CopilotAuthManageror extend TokenManager with Copilot-specific auth status - Remove the requirement for token before AI analysis (Copilot SDK handles its own auth)
- Add BYOK configuration support via VS Code settings
New settings in package.json contributes.configuration:
{
"teamxray.aiProvider": {
"type": "string",
"enum": ["copilot", "byok-openai", "byok-anthropic", "byok-azure", "github-models"],
"default": "copilot",
"description": "AI provider for team analysis"
},
"teamxray.byokApiKey": {
"type": "string",
"description": "API key for BYOK provider (stored securely)"
},
"teamxray.byokBaseUrl": {
"type": "string",
"description": "Base URL for BYOK provider"
},
"teamxray.byokModel": {
"type": "string",
"description": "Model name for BYOK provider"
}
}Auth flow:
- Check if Copilot SDK can initialize (CLI available + auth)
- If yes → use Copilot SDK (zero config needed from user)
- If no → check BYOK settings → use custom provider
- If no BYOK → fall back to GitHub Models API (existing behavior, needs token)
- If nothing → fall back to local-only analysis (no AI insights)
extension.ts changes:
// In activate():
const copilotService = new CopilotService(outputChannel);
try {
await copilotService.initialize();
outputChannel.appendLine('✅ Copilot SDK connected');
} catch {
outputChannel.appendLine('⚠️ Copilot CLI not available, using fallback');
}
// Pass copilotService to ExpertiseAnalyzer
const analyzer = new ExpertiseAnalyzer(context, tokenManager, copilotService);
// In deactivate():
await copilotService.dispose();
resourceManager.cleanup();Command changes:
teamxray.setGitHubToken→ Keep, but label it "Set GitHub Token (for API access)"- Add
teamxray.configureAI→ Opens settings for AI provider selection - Modify
teamxray.analyzeRepository→ No longer requires GitHub token if Copilot SDK is available
Add progressive analysis display:
Currently the webview only renders after full analysis completes. With SDK streaming:
- Open webview immediately when analysis starts
- Show skeleton/loading state for each section
- As
assistant.message_deltaevents arrive, parse partial JSON and update sections - Expert cards appear one by one as the agent identifies them
- Management insights populate progressively
Implementation:
- Webview receives messages from extension via
panel.webview.postMessage() - Extension listens to SDK session events and forwards deltas
- Webview JavaScript handles incremental DOM updates
What to keep:
detectRepository()— still needed for GitHub repo detectiongetExpertRecentActivity()→ Keep but simplify (uses local git, not MCP)showExpertActivity()→ Keep (UI display)
What to remove:
checkMCPServerStatus()— Docker container checking (Copilot SDK replaces this)ensureMCPServerRunning()— Docker managementgatherRepositoryData()— Replaced by ExpertiseAnalyzer's local git gatheringqueryCopilotWithMCP()— Replaced by CopilotServicebuildMCPDataGatheringPrompt()— Replaced by CopilotService system messagefallbackLocalAnalysis()— Already handled by ExpertiseAnalyzer
This file shrinks significantly. Consider renaming to github-service.ts since it's really just GitHub repo detection + expert activity display.
Test files to create:
| File | Tests |
|---|---|
src/core/__tests__/copilot-service.test.ts |
SDK initialization, tool definitions, response parsing, BYOK config, error handling |
src/core/__tests__/expertise-analyzer.test.ts |
Data gathering, sampling logic, fallback analysis, orchestration |
src/core/__tests__/git-service.test.ts |
Commit parsing, contributor extraction, date handling |
src/utils/__tests__/validation.test.ts |
All validators: token, path, email, URL, shell input |
Use vitest (already in devDependencies).
Add:
npm install @github/copilot-sdk zod
Remove (eventually):
axios— Only used for GitHub Models API calls and token validation. Keep for now (token validation still uses it), remove later if we move token validation to use fetch.
Webpack externals update:
externals: {
vscode: 'commonjs vscode',
'@github/copilot-sdk': 'commonjs @github/copilot-sdk',
}The Copilot SDK communicates with the CLI process and shouldn't be bundled.
| File | Action | Description |
|---|---|---|
src/core/copilot-service.ts |
NEW | CopilotClient wrapper with custom tools |
src/core/expertise-analyzer.ts |
MODIFY | Remove AI prompt/parsing, delegate to CopilotService |
src/core/copilot-mcp-service.ts |
MODIFY | Strip MCP/Docker code, rename to github-service.ts |
src/extension.ts |
MODIFY | Add CopilotService lifecycle, update command wiring |
src/core/token-manager.ts |
MODIFY | Keep for GitHub API, remove as AI analysis requirement |
src/core/expertise-webview.ts |
MODIFY | Add streaming/progressive rendering support |
package.json |
MODIFY | Add dependencies, new settings, update commands |
webpack.config.js |
MODIFY | Add SDK to externals |
src/core/__tests__/*.test.ts |
NEW | Unit tests for core modules |
The extension should work in three modes:
- Copilot SDK mode (preferred) — Zero config, uses Copilot subscription
- BYOK mode — User provides their own API key in settings
- GitHub Models mode (legacy) — User provides GitHub token (existing behavior)
- Local-only mode — No AI, just git statistics (existing fallback)
Detection order: Copilot SDK → BYOK settings → GitHub Models token → Local-only
This means existing users who have a GitHub token configured continue to work unchanged, while new users get the zero-config Copilot experience.
| Risk | Mitigation |
|---|---|
| Copilot SDK is Technical Preview | Keep GitHub Models fallback, graceful degradation |
| SDK requires Copilot CLI installed | Check availability on startup, show helpful install message |
| Breaking API changes in SDK | Pin SDK version, wrap in abstraction layer (CopilotService) |
| Token limits with custom tools | Keep smart sampling from current code, infinite sessions help |
| VS Code extension sandboxing | SDK uses JSON-RPC to external CLI process — should work fine |
- Phase 1 (CopilotService) — Core SDK integration
- Phase 2 (Refactor Analyzer) — Wire new service into existing flow
- Phase 3 (Auth) — Update settings and auth flow
- Phase 4 (Extension lifecycle) — Wire up startup/shutdown
- Phase 7 (Tests) — Add unit tests for new and existing code
- Phase 6 (Simplify MCP service) — Clean up dead code
- Phase 8 (Dependencies) — Update package.json and webpack
- Phase 5 (Streaming) — Progressive webview rendering (nice-to-have, can defer)