Coverage for sources / agentsmgr / renderers / gemini.py: 65%
29 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 23:00 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-03 23:00 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
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#============================================================================#
21''' Gemini CLI renderer implementation.
23 Provides path resolution and targeting mode validation for Gemini CLI,
24 which supports both per-user and per-project configuration.
25'''
28from . import __
29from . import base as _base
32class GeminiRenderer( _base.RendererBase ):
33 ''' Renderer for Gemini CLI coder.
35 Supports both per-user and per-project configuration modes.
36 Per-user mode defaults to ~/.gemini/ with configuration file
37 override support via directory field in coder config.
38 '''
40 name = 'gemini'
41 modes_available = frozenset( ( 'per-user', 'per-project' ) )
42 mode_default = 'per-project'
43 memory_filename = 'GEMINI.md'
44 item_types_available = frozenset( ( 'commands', 'skills' ) )
46 def get_template_flavor( self, item_type: str ) -> str:
47 ''' Determines template flavor for Gemini CLI.
49 Gemini shares TOML command format with Qwen
50 (via gemini.toml.jinja for TOML). Gemini CLI does not
51 support agents/subagents, only commands.
52 '''
53 if item_type == 'commands':
54 return 'gemini'
55 # Gemini CLI does not support agents/subagents
56 error_message = f"Gemini CLI does not support {item_type} generation"
57 raise __.Omnierror( error_message )
60 def resolve_base_directory(
61 self,
62 mode: _base.ExplicitTargetMode,
63 target: __.Path,
64 configuration: __.cabc.Mapping[ str, __.typx.Any ],
65 environment: __.cabc.Mapping[ str, str ],
66 ) -> __.Path:
67 ''' Resolves base output directory for Gemini CLI.
69 Per-project: .auxiliary/configuration/coders/gemini/
70 Per-user: ~/.gemini/ with configuration file overrides.
71 '''
72 self.validate_mode( mode )
73 if mode == 'per-project': 73 ↛ 74line 73 didn't jump to line 74 because the condition on line 73 was never true
74 return target / ".auxiliary/configuration/coders/gemini"
75 if mode == 'per-user': 75 ↛ 77line 75 didn't jump to line 77 because the condition on line 75 was always true
76 return self._resolve_user_directory( configuration, environment )
77 raise __.TargetModeNoSupport( self.name, mode )
79 def _resolve_user_directory(
80 self,
81 configuration: __.cabc.Mapping[ str, __.typx.Any ],
82 environment: __.cabc.Mapping[ str, str ],
83 ) -> __.Path:
84 ''' Resolves per-user directory following precedence rules.
86 Precedence order:
87 1. Configuration file override (directory field for this coder)
88 2. Default ~/.gemini/ location
90 Note: Gemini does not provide environment variable override
91 for user config path (unlike Claude's CLAUDE_CONFIG_DIR).
92 '''
93 coder_configuration = self._extract_coder_configuration(
94 configuration )
95 if 'directory' in coder_configuration: 95 ↛ 96line 95 didn't jump to line 96 because the condition on line 95 was never true
96 directory = __.Path( coder_configuration[ 'directory' ] )
97 return directory.expanduser( )
98 return __.Path.home( ) / '.gemini'
100 def _extract_coder_configuration(
101 self, configuration: __.cabc.Mapping[ str, __.typx.Any ]
102 ) -> __.cabc.Mapping[ str, __.typx.Any ]:
103 ''' Extracts configuration for this specific coder.
105 Looks for coder entry in configuration coders array by name.
106 '''
107 return _base.extract_coder_configuration( configuration, self.name )
110_base.RENDERERS[ 'gemini' ] = GeminiRenderer( )