Skip to main content

roder_ext_claude_code/
extension.rs

1use std::sync::Arc;
2
3use roder_api::capabilities::CapabilityRequest;
4use roder_api::catalog::PROVIDER_CLAUDE_CODE;
5use roder_api::extension::{
6    ExtensionManifest, ExtensionRegistryBuilder, ProvidedService, RoderExtension,
7};
8use semver::Version;
9
10use crate::provider::{ClaudeCodeConfig, ClaudeCodeEngine};
11
12pub struct ClaudeCodeExtension {
13    config: ClaudeCodeConfig,
14}
15
16impl ClaudeCodeExtension {
17    pub fn new(config: ClaudeCodeConfig) -> Self {
18        Self { config }
19    }
20}
21
22impl RoderExtension for ClaudeCodeExtension {
23    fn manifest(&self) -> ExtensionManifest {
24        ExtensionManifest {
25            id: "roder-ext-claude-code-provider".to_string(),
26            name: "Claude Code Provider".to_string(),
27            version: Version::new(0, 1, 0),
28            api_version: "0.1.0".to_string(),
29            description: Some(
30                "Claude Code CLI harness provider backed by claude-agent-sdk".to_string(),
31            ),
32            provides: vec![ProvidedService::InferenceEngine(
33                PROVIDER_CLAUDE_CODE.to_string(),
34            )],
35            required_capabilities: vec![CapabilityRequest::new("process.claude")],
36        }
37    }
38
39    fn install(&self, registry: &mut ExtensionRegistryBuilder) -> anyhow::Result<()> {
40        registry.inference_engine(Arc::new(ClaudeCodeEngine::new(self.config.clone())));
41        Ok(())
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use roder_api::extension::RoderExtension;
48
49    use super::*;
50
51    #[test]
52    fn manifest_provides_claude_code_engine() {
53        let manifest = ClaudeCodeExtension::new(ClaudeCodeConfig::default()).manifest();
54        assert_eq!(
55            manifest.provides,
56            vec![ProvidedService::InferenceEngine(
57                PROVIDER_CLAUDE_CODE.to_string()
58            )]
59        );
60    }
61}