roder_ext_claude_code/
extension.rs1use 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}