{"_id":"@dxheroes/ado-adapters","_rev":"3-c2421830dc3ad0cb3d34b081b0f8cf8d","name":"@dxheroes/ado-adapters","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@dxheroes/ado-adapters","version":"0.1.0","keywords":["ado","adapters","ai-agents","claude","gemini","cursor","copilot"],"_id":"@dxheroes/ado-adapters@0.1.0","maintainers":[{"name":"dxheroes_dev","email":"dev@dxheroes.io"}],"dist":{"shasum":"a16850dcd0382729a27df8094c1b23f4198f8ace","tarball":"https://registry.npmjs.org/@dxheroes/ado-adapters/-/ado-adapters-0.1.0.tgz","fileCount":4,"integrity":"sha512-br1RVcRn2rsRYPTlE2NbgU7icI+bvDNFdmuQt2IUtLdCifW90suhE9RX/dAT8duR0U/Yg64E2POgVp95GTAHJQ==","signatures":[{"sig":"MEUCIAn1YNasvbXGfarsLNsK8vLaniX/f2sAkS8EZpYwr4mkAiEAnfZoJHOclOJ/WgmKJ4ESKwFdt/BK+HlJlepO1LZ6raE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":145117},"main":"./dist/index.js","type":"module","_from":"file:dxheroes-ado-adapters-0.1.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit"},"_npmUser":{"name":"dxheroes_dev","email":"dev@dxheroes.io"},"_resolved":"/tmp/8d97bb444f802826134db442fd332f29/dxheroes-ado-adapters-0.1.0.tgz","_integrity":"sha512-br1RVcRn2rsRYPTlE2NbgU7icI+bvDNFdmuQt2IUtLdCifW90suhE9RX/dAT8duR0U/Yg64E2POgVp95GTAHJQ==","_npmVersion":"10.8.2","description":"Agent adapters for ADO","directories":{},"_nodeVersion":"20.19.5","dependencies":{"@opentelemetry/api":"^1.9.0","@dxheroes/ado-shared":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ado-adapters_0.1.0_1764263837995_0.8194758399354356","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dxheroes/ado-adapters","version":"0.1.1","keywords":["ado","adapters","ai-agents","claude","gemini","cursor","copilot"],"_id":"@dxheroes/ado-adapters@0.1.1","maintainers":[{"name":"dxheroes_dev","email":"dev@dxheroes.io"}],"dist":{"shasum":"bcbd135224e94115e643171287047ce222ef4198","tarball":"https://registry.npmjs.org/@dxheroes/ado-adapters/-/ado-adapters-0.1.1.tgz","fileCount":5,"integrity":"sha512-Ghi+MQmar0kQLlJ3j0eu1Sh9xIIfZ0Hb+KmtxeOMdzJeW5JxkI7xVDe8DlOcnVhVLqNG61uSD7SavCdYsNv+jg==","signatures":[{"sig":"MEUCIQD/a4+2l/PsNpzC4Dhhq94E/uXVFPRaUsKiMUKZXIcoNwIgUvpEsU4sA8pI1U8NdgJzuYU4JUE2/uUcrd9hKtRwnf4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":169223},"main":"./dist/index.js","type":"module","_from":"file:dxheroes-ado-adapters-0.1.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist","typecheck":"tsc --noEmit"},"_npmUser":{"name":"dxheroes_dev","email":"dev@dxheroes.io"},"_resolved":"/tmp/d7b20e48c83866cd86b0aaeaf70dc0ca/dxheroes-ado-adapters-0.1.1.tgz","_integrity":"sha512-Ghi+MQmar0kQLlJ3j0eu1Sh9xIIfZ0Hb+KmtxeOMdzJeW5JxkI7xVDe8DlOcnVhVLqNG61uSD7SavCdYsNv+jg==","_npmVersion":"10.9.4","description":"Agent adapters for ADO","directories":{},"_nodeVersion":"22.21.1","dependencies":{"@opentelemetry/api":"^1.9.0","@dxheroes/ado-shared":"0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.5","typescript":"^5.7.2"},"_npmOperationalInternal":{"tmp":"tmp/ado-adapters_0.1.1_1765657057527_0.8184548165615295","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@dxheroes/ado-adapters","version":"0.1.2","description":"Agent adapters for ADO","type":"module","keywords":["ado","adapters","ai-agents","claude","gemini","cursor","copilot"],"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"dependencies":{"@opentelemetry/api":"^1.9.0","@dxheroes/ado-shared":"0.1.2"},"devDependencies":{"tsup":"^8.3.5","typescript":"^5.7.2"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","clean":"rm -rf dist"},"_id":"@dxheroes/ado-adapters@0.1.2","_integrity":"sha512-IwqRxCoIrBuwO2nH+btElXVYKGy3tqrw4atvwJyOE65+1shCl8RA9ChVUJBmDyAZQo5k4TEwHxr9ao7sCP4G6A==","_resolved":"/tmp/d4931f0293fcd654d38ad5408f9669e3/dxheroes-ado-adapters-0.1.2.tgz","_from":"file:dxheroes-ado-adapters-0.1.2.tgz","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-IwqRxCoIrBuwO2nH+btElXVYKGy3tqrw4atvwJyOE65+1shCl8RA9ChVUJBmDyAZQo5k4TEwHxr9ao7sCP4G6A==","shasum":"d0ef96db6e397e4a2c2ab83f981634a81d811dc1","tarball":"https://registry.npmjs.org/@dxheroes/ado-adapters/-/ado-adapters-0.1.2.tgz","fileCount":5,"unpackedSize":169223,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFxFwgDB5PFOVMQX0F6nEF5FAF0ADUV6O0rY/vSIyx3AAiAwmHWJFnipLa/H7/M9PKXv68nDMwAw8kR0YKx9O9MDHw=="}]},"_npmUser":{"name":"dxheroes_dev","email":"dev@dxheroes.io"},"directories":{},"maintainers":[{"name":"dxheroes_dev","email":"dev@dxheroes.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ado-adapters_0.1.2_1765657537175_0.4254329660631413"},"_hasShrinkwrap":false}},"time":{"created":"2025-11-27T17:17:17.913Z","modified":"2025-12-13T20:25:37.836Z","0.1.0":"2025-11-27T17:17:18.279Z","0.1.1":"2025-12-13T20:17:37.683Z","0.1.2":"2025-12-13T20:25:37.319Z"},"keywords":["ado","adapters","ai-agents","claude","gemini","cursor","copilot"],"description":"Agent adapters for ADO","maintainers":[{"name":"dxheroes_dev","email":"dev@dxheroes.io"}],"readme":"# @dxheroes/ado-adapters\n\nAgent adapters for ADO (Agentic Development Orchestrator). Provides unified interfaces to multiple AI coding agents.\n\n## Features\n\n- **Unified Interface** - Single `AgentAdapter` interface for all providers\n- **Subscription-First** - Prioritize subscription access over API billing\n- **Rate Limit Detection** - Automatic detection and handling of rate limits\n- **Streaming Output** - Real-time task progress via async iterators\n- **OpenTelemetry** - Full observability with distributed tracing\n- **Context Management** - Automatic project context injection\n- **Resume Support** - Resume interrupted sessions where supported\n\n## Installation\n\n```bash\npnpm add @dxheroes/ado-adapters\n```\n\n## Available Adapters\n\n### Claude Code (`claude-code`)\n\n**Status:** ✅ Production Ready\n\n**Installation:**\n```bash\nnpm install -g @anthropic-ai/claude-code\n```\n\n**Capabilities:**\n- Code generation, review, refactoring\n- Testing and debugging\n- Documentation\n- Languages: TypeScript, Python, Go, Rust, Java, JavaScript, C, C++\n- Max context: 200,000 tokens\n- Streaming: ✅\n- MCP support: ✅\n- Resume: ✅\n\n**Configuration:**\n```yaml\nproviders:\n  claude-code:\n    enabled: true\n    accessModes:\n      - mode: subscription\n        priority: 1\n        subscription:\n          plan: \"max\"  # or \"pro\"\n          rateLimits:\n            requestsPerDay: 500\n            requestsPerHour: 100\n      - mode: api\n        priority: 10\n        api:\n          key: \"${ANTHROPIC_API_KEY}\"\n    capabilities:\n      codeGeneration: true\n      codeReview: true\n      refactoring: true\n      testing: true\n      documentation: true\n      debugging: true\n    contextFile: \"CLAUDE.md\"\n```\n\n**Usage:**\n```typescript\nimport { ClaudeCodeAdapter } from '@dxheroes/ado-adapters/claude-code';\n\nconst adapter = new ClaudeCodeAdapter();\n\n// Check availability\nconst isAvailable = await adapter.isAvailable();\n\n// Initialize\nawait adapter.initialize({\n  workingDirectory: '/path/to/project',\n  projectContext: { projectId: 'my-project' },\n});\n\n// Execute task\nfor await (const event of adapter.execute({\n  id: 'task-1',\n  prompt: 'Add user authentication',\n  projectContext: { projectId: 'my-project' },\n})) {\n  console.log(event);\n}\n```\n\n### Gemini CLI (`gemini-cli`)\n\n**Status:** 🚧 Experimental\n\n**Installation:**\n```bash\n# Currently not publicly available\n# Adapter ready for when Google releases Gemini CLI\n```\n\n**Capabilities:**\n- Code generation and review\n- Multi-modal support (code + images)\n- Languages: TypeScript, Python, Go, Java, JavaScript\n- Max context: 1,000,000 tokens\n- Streaming: ✅\n\n**Configuration:**\n```yaml\nproviders:\n  gemini-cli:\n    enabled: false\n    accessModes:\n      - mode: api\n        priority: 10\n        api:\n          key: \"${GOOGLE_API_KEY}\"\n    contextFile: \"GEMINI.md\"\n```\n\n### Cursor CLI (`cursor-cli`)\n\n**Status:** 🚧 Planned\n\n**Installation:**\n```bash\n# Cursor CLI not yet available\n# Adapter ready for future release\n```\n\n**Capabilities:**\n- Code generation via Cursor's AI\n- IDE integration\n- Context-aware suggestions\n- Languages: TypeScript, Python, Go, Rust, Java, JavaScript\n- Streaming: ✅\n\n**Configuration:**\n```yaml\nproviders:\n  cursor-cli:\n    enabled: false\n    accessModes:\n      - mode: subscription\n        priority: 1\n        subscription:\n          plan: \"pro\"\n          rateLimits:\n            requestsPerDay: 1000\n    contextFile: \".cursorrules\"\n```\n\n### GitHub Copilot CLI (`copilot-cli`)\n\n**Status:** 🚧 Planned\n\n**Installation:**\n```bash\n# GitHub Copilot CLI\nnpm install -g @githubnext/copilot-cli\n```\n\n**Capabilities:**\n- Code suggestions and completions\n- GitHub integration\n- Languages: TypeScript, Python, Go, Rust, Java, JavaScript\n- Streaming: ✅\n\n**Configuration:**\n```yaml\nproviders:\n  copilot-cli:\n    enabled: false\n    accessModes:\n      - mode: subscription\n        priority: 1\n        subscription:\n          plan: \"individual\"  # or \"business\"\n          rateLimits:\n            requestsPerDay: 2000\n    contextFile: \".github/copilot-instructions.md\"\n```\n\n### OpenAI Codex CLI (`codex-cli`)\n\n**Status:** 🚧 Planned\n\n**Installation:**\n```bash\n# Custom Codex CLI wrapper\nnpm install -g openai-codex-cli\n```\n\n**Capabilities:**\n- Code generation via GPT-4\n- Function calling\n- Languages: TypeScript, Python, Go, Rust, Java, JavaScript\n- Max context: 128,000 tokens\n- Streaming: ✅\n\n**Configuration:**\n```yaml\nproviders:\n  codex-cli:\n    enabled: false\n    accessModes:\n      - mode: api\n        priority: 10\n        api:\n          key: \"${OPENAI_API_KEY}\"\n          model: \"gpt-4-turbo\"\n    contextFile: \"CODEX.md\"\n```\n\n## Provider Capabilities Matrix\n\n| Provider | Code Gen | Review | Testing | Debugging | Refactoring | Docs | Max Context | Streaming | MCP | Resume |\n|----------|----------|--------|---------|-----------|-------------|------|-------------|-----------|-----|--------|\n| Claude Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 200K | ✅ | ✅ | ✅ |\n| Gemini CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 1M | ✅ | ❌ | ❌ |\n| Cursor CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 100K | ✅ | ❌ | ❌ |\n| Copilot CLI | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | 8K | ✅ | ❌ | ❌ |\n| Codex CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 128K | ✅ | ❌ | ❌ |\n\n## Creating a Custom Adapter\n\n### 1. Implement the `AgentAdapter` Interface\n\n```typescript\nimport { BaseAdapter } from '@dxheroes/ado-adapters/base';\nimport type {\n  AgentCapabilities,\n  AgentEvent,\n  AgentTask,\n} from '@dxheroes/ado-shared';\n\nexport class MyCustomAdapter extends BaseAdapter {\n  // Unique identifier\n  readonly id = 'my-custom-agent';\n\n  // Declare capabilities\n  readonly capabilities: AgentCapabilities = {\n    codeGeneration: true,\n    codeReview: true,\n    refactoring: false,\n    testing: true,\n    documentation: true,\n    debugging: false,\n    languages: ['typescript', 'python'],\n    maxContextTokens: 100000,\n    supportsStreaming: true,\n    supportsMCP: false,\n    supportsResume: false,\n  };\n\n  // Check if agent is available\n  async isAvailable(): Promise<boolean> {\n    try {\n      // Check if CLI is installed\n      const proc = spawn('my-agent', ['--version']);\n      return new Promise((resolve) => {\n        proc.on('close', (code) => resolve(code === 0));\n        proc.on('error', () => resolve(false));\n      });\n    } catch {\n      return false;\n    }\n  }\n\n  // Execute task\n  async *execute(task: AgentTask): AsyncIterable<AgentEvent> {\n    // Wrap with tracing\n    yield* this.executeWithTracing(task, this.executeInternal.bind(this));\n  }\n\n  private async *executeInternal(\n    task: AgentTask,\n    span: Span,\n  ): AsyncIterable<AgentEvent> {\n    const workingDir = this.config?.workingDirectory ?? process.cwd();\n\n    // Yield start event\n    yield this.createEvent<AgentStartEvent>('start', task.id, {\n      agentId: this.id,\n      sessionId: this.generateSessionId(),\n    });\n\n    try {\n      // Spawn agent CLI\n      const proc = spawn('my-agent', [\n        'run',\n        '--prompt', task.prompt,\n        '--cwd', workingDir,\n      ]);\n\n      // Stream output\n      proc.stdout?.on('data', (data) => {\n        const output = data.toString();\n        // Parse and yield events\n      });\n\n      // Wait for completion\n      await new Promise((resolve, reject) => {\n        proc.on('close', (code) => {\n          if (code === 0) resolve(undefined);\n          else reject(new Error(`Exit code ${code}`));\n        });\n      });\n\n      // Yield complete event\n      yield this.createEvent<AgentCompleteEvent>('complete', task.id, {\n        success: true,\n      });\n    } catch (error) {\n      // Yield error event\n      yield this.createEvent<AgentErrorEvent>('error', task.id, {\n        error: error as Error,\n      });\n    }\n  }\n\n  // Interrupt execution\n  async interrupt(): Promise<void> {\n    if (this.process) {\n      this.process.kill('SIGTERM');\n      this.process = null;\n    }\n  }\n\n  // Get context file name\n  getContextFile(): string {\n    return 'MY_AGENT.md';\n  }\n}\n```\n\n### 2. Implement Rate Limit Detection (Optional)\n\n```typescript\nimport type {\n  RateLimitDetector,\n  RateLimitInfo,\n  RateLimitStatus,\n  RemainingCapacity,\n  UsageRecord,\n} from '@dxheroes/ado-shared';\n\nexport class MyAgentRateLimitDetector implements RateLimitDetector {\n  private usageRecords: UsageRecord[] = [];\n\n  async getStatus(): Promise<RateLimitStatus> {\n    // Check if rate limited\n    const dailyUsage = this.getDailyUsage();\n    const dailyLimit = 1000;\n\n    if (dailyUsage >= dailyLimit) {\n      return {\n        isLimited: true,\n        resetAt: this.getNextResetTime(),\n        reason: 'daily_limit_reached',\n      };\n    }\n\n    return { isLimited: false };\n  }\n\n  parseRateLimitError(error: Error): RateLimitInfo | null {\n    // Parse rate limit errors from agent output\n    const message = error.message;\n    if (message.includes('rate limit exceeded')) {\n      return {\n        limit: 1000,\n        remaining: 0,\n        resetAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n      };\n    }\n    return null;\n  }\n\n  async getRemainingCapacity(): Promise<RemainingCapacity> {\n    const dailyUsage = this.getDailyUsage();\n    const dailyLimit = 1000;\n\n    return {\n      requestsPerDay: dailyLimit - dailyUsage,\n    };\n  }\n\n  async recordUsage(usage: UsageRecord): Promise<void> {\n    this.usageRecords.push(usage);\n  }\n\n  private getDailyUsage(): number {\n    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);\n    return this.usageRecords.filter(\n      (r) => r.timestamp > oneDayAgo\n    ).length;\n  }\n\n  private getNextResetTime(): Date {\n    return new Date(Date.now() + 24 * 60 * 60 * 1000);\n  }\n}\n```\n\n### 3. Register Your Adapter\n\nAdd your adapter to the adapter registry:\n\n```typescript\nimport { MyCustomAdapter } from './my-custom-adapter.js';\n\nexport const adapters = {\n  'claude-code': ClaudeCodeAdapter,\n  'gemini-cli': GeminiCLIAdapter,\n  'my-custom-agent': MyCustomAdapter,\n};\n```\n\n### 4. Configure Your Adapter\n\nAdd configuration to `ado.config.yaml`:\n\n```yaml\nproviders:\n  my-custom-agent:\n    enabled: true\n    accessModes:\n      - mode: subscription\n        priority: 1\n        subscription:\n          plan: \"premium\"\n          rateLimits:\n            requestsPerDay: 1000\n    capabilities:\n      codeGeneration: true\n      testing: true\n    contextFile: \"MY_AGENT.md\"\n```\n\n### 5. Create Context File\n\nCreate `MY_AGENT.md` in your project root:\n\n```markdown\n# My Custom Agent Context\n\n## Project Overview\n[Project description]\n\n## Coding Standards\n- Use TypeScript strict mode\n- Write tests for all new features\n- Follow ESLint rules\n\n## Architecture\n[Architecture details]\n```\n\n## Testing Your Adapter\n\n### Unit Tests\n\n```typescript\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { MyCustomAdapter } from './my-custom-adapter.js';\n\ndescribe('MyCustomAdapter', () => {\n  let adapter: MyCustomAdapter;\n\n  beforeEach(() => {\n    adapter = new MyCustomAdapter();\n  });\n\n  it('should have correct id', () => {\n    expect(adapter.id).toBe('my-custom-agent');\n  });\n\n  it('should check availability', async () => {\n    const available = await adapter.isAvailable();\n    expect(typeof available).toBe('boolean');\n  });\n\n  it('should execute task and yield events', async () => {\n    await adapter.initialize({\n      workingDirectory: process.cwd(),\n      projectContext: { projectId: 'test' },\n    });\n\n    const task = {\n      id: 'task-1',\n      prompt: 'Write a hello world function',\n      projectContext: { projectId: 'test' },\n    };\n\n    const events = [];\n    for await (const event of adapter.execute(task)) {\n      events.push(event);\n    }\n\n    expect(events.length).toBeGreaterThan(0);\n    expect(events[0].type).toBe('start');\n  });\n});\n```\n\n### Integration Tests\n\n```typescript\ndescribe('MyCustomAdapter Integration', () => {\n  it('should execute real task', async () => {\n    const adapter = new MyCustomAdapter();\n\n    if (!(await adapter.isAvailable())) {\n      console.log('Skipping: agent not available');\n      return;\n    }\n\n    await adapter.initialize({\n      workingDirectory: '/tmp/test-project',\n      projectContext: { projectId: 'integration-test' },\n    });\n\n    const task = {\n      id: 'integration-task',\n      prompt: 'Create a simple TypeScript function',\n      projectContext: { projectId: 'integration-test' },\n    };\n\n    let completed = false;\n    for await (const event of adapter.execute(task)) {\n      if (event.type === 'complete') {\n        completed = true;\n      }\n    }\n\n    expect(completed).toBe(true);\n  }, 60000); // 60s timeout\n});\n```\n\n## Best Practices\n\n### 1. Handle Errors Gracefully\n\n```typescript\ntry {\n  // Execute agent\n} catch (error) {\n  yield this.createEvent<AgentErrorEvent>('error', task.id, {\n    error: error as Error,\n  });\n}\n```\n\n### 2. Implement Progress Tracking\n\n```typescript\nyield this.createEvent<AgentProgressEvent>('progress', task.id, {\n  progress: 50,\n  message: 'Halfway through implementation',\n});\n```\n\n### 3. Support Interruption\n\n```typescript\nasync interrupt(): Promise<void> {\n  if (this.process) {\n    this.process.kill('SIGTERM');\n\n    // Wait for graceful shutdown\n    await new Promise((resolve) => {\n      this.process?.on('exit', resolve);\n      setTimeout(resolve, 5000); // Force after 5s\n    });\n\n    this.process = null;\n  }\n}\n```\n\n### 4. Parse Output Properly\n\n```typescript\nprivate parseAgentOutput(line: string): AgentEvent | null {\n  // Parse JSON output\n  if (line.startsWith('{')) {\n    try {\n      const data = JSON.parse(line);\n      return this.createEvent(data.type, task.id, data);\n    } catch {\n      return null;\n    }\n  }\n\n  // Parse plain text output\n  return this.createEvent<AgentOutputEvent>('output', task.id, {\n    output: line,\n  });\n}\n```\n\n### 5. Use OpenTelemetry Tracing\n\n```typescript\nasync *execute(task: AgentTask): AsyncIterable<AgentEvent> {\n  // Always wrap with tracing\n  yield* this.executeWithTracing(task, this.executeInternal.bind(this));\n}\n```\n\n## API Reference\n\n### AgentAdapter Interface\n\n```typescript\ninterface AgentAdapter {\n  readonly id: string;\n  readonly capabilities: AgentCapabilities;\n\n  initialize(config: AgentConfig): Promise<void>;\n  isAvailable(): Promise<boolean>;\n  execute(task: AgentTask): AsyncIterable<AgentEvent>;\n  interrupt(): Promise<void>;\n  getContextFile(): string;\n  setProjectContext(context: ProjectContext): Promise<void>;\n  getRateLimitDetector(): RateLimitDetector;\n}\n```\n\n### AgentCapabilities\n\n```typescript\ninterface AgentCapabilities {\n  codeGeneration: boolean;\n  codeReview: boolean;\n  refactoring: boolean;\n  testing: boolean;\n  documentation: boolean;\n  debugging: boolean;\n  languages: string[];\n  maxContextTokens: number;\n  supportsStreaming: boolean;\n  supportsMCP?: boolean;\n  supportsResume?: boolean;\n}\n```\n\n### AgentEvent Types\n\n```typescript\ntype AgentEvent =\n  | AgentStartEvent\n  | AgentOutputEvent\n  | AgentProgressEvent\n  | AgentCompleteEvent\n  | AgentErrorEvent\n  | AgentInterruptEvent;\n```\n\n## Development\n\n```bash\n# Install dependencies\npnpm install\n\n# Build adapters\npnpm --filter @dxheroes/ado-adapters build\n\n# Run tests\npnpm --filter @dxheroes/ado-adapters test\n\n# Type checking\npnpm --filter @dxheroes/ado-adapters typecheck\n\n# Linting\npnpm --filter @dxheroes/ado-adapters lint\n```\n\n## Contributing\n\nTo contribute a new adapter:\n\n1. Create adapter class in `src/<agent-name>/adapter.ts`\n2. Implement `AgentAdapter` interface\n3. Add rate limit detector if needed\n4. Write unit and integration tests\n5. Update this README with provider details\n6. Submit pull request\n\n## License\n\nMIT © DX Heroes\n","readmeFilename":"README.md"}