Coverage for sources/agentsmgr/renderers/claude.py: 26%

30 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-13 00:43 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Claude Code renderer implementation. 

22 

23 Provides path resolution and targeting mode validation for Claude Code, 

24 which supports both per-user and per-project configuration. 

25''' 

26 

27 

28from . import __ 

29from .base import RENDERERS, ExplicitTargetMode, RendererBase 

30 

31 

32class ClaudeRenderer( RendererBase ): 

33 ''' Renderer for Claude Code coder. 

34 

35 Supports both per-user and per-project configuration modes. 

36 Per-user mode respects CLAUDE_CONFIG_DIR environment variable 

37 with fallback to configuration overrides and default location. 

38 ''' 

39 

40 name = 'claude' 

41 modes_available = frozenset( ( 'per-user', 'per-project' ) ) 

42 mode_default = 'per-project' 

43 memory_filename = 'CLAUDE.md' 

44 

45 def resolve_base_directory( 

46 self, 

47 mode: ExplicitTargetMode, 

48 target: __.Path, 

49 configuration: __.cabc.Mapping[ str, __.typx.Any ], 

50 environment: __.cabc.Mapping[ str, str ], 

51 ) -> __.Path: 

52 ''' Resolves base output directory for Claude Code. 

53 

54 For per-project mode, returns .claude in project root. 

55 For per-user mode, respects precedence: CLAUDE_CONFIG_DIR 

56 environment variable, configuration file override, or default 

57 ~/.claude location. 

58 ''' 

59 self.validate_mode( mode ) 

60 if mode == 'per-project': 

61 return target / ".auxiliary/configuration/coders/claude" 

62 if mode == 'per-user': 

63 return self._resolve_user_directory( configuration, environment ) 

64 raise __.TargetModeNoSupport( self.name, mode ) 

65 

66 def _resolve_user_directory( 

67 self, 

68 configuration: __.cabc.Mapping[ str, __.typx.Any ], 

69 environment: __.cabc.Mapping[ str, str ], 

70 ) -> __.Path: 

71 ''' Resolves per-user directory following precedence rules. 

72 

73 Precedence order: 

74 1. CLAUDE_CONFIG_DIR environment variable 

75 2. Configuration file override (directory for this coder) 

76 3. Default ~/.claude location 

77 ''' 

78 if 'CLAUDE_CONFIG_DIR' in environment: 

79 directory = __.Path( environment[ 'CLAUDE_CONFIG_DIR' ] ) 

80 return directory.expanduser( ) 

81 coder_configuration = self._extract_coder_configuration( 

82 configuration ) 

83 if 'directory' in coder_configuration: 

84 directory = __.Path( coder_configuration[ 'directory' ] ) 

85 return directory.expanduser( ) 

86 return __.Path.home( ) / '.claude' 

87 

88 def _extract_coder_configuration( 

89 self, configuration: __.cabc.Mapping[ str, __.typx.Any ] 

90 ) -> __.cabc.Mapping[ str, __.typx.Any ]: 

91 ''' Extracts configuration for this specific coder. 

92 

93 Looks for coder entry in configuration coders array by name. 

94 ''' 

95 coders = configuration.get( 'coders', ( ) ) 

96 for coder in coders: 

97 if coder.get( 'name' ) == self.name: 

98 return coder 

99 return { } 

100 

101 

102RENDERERS[ 'claude' ] = ClaudeRenderer( )