stigmergy 1.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/README.de.md +301 -0
- package/README.en.md +301 -0
- package/README.es.md +301 -0
- package/README.fr.md +301 -0
- package/README.ja.md +301 -0
- package/README.ko.md +301 -0
- package/README.md +301 -0
- package/README.ru.md +301 -0
- package/README.zh.md +301 -0
- package/package.json +82 -0
- package/src/adapters/claude/__init__.py +13 -0
- package/src/adapters/claude/claude_skills_integration.py +609 -0
- package/src/adapters/claude/hook_adapter.py +663 -0
- package/src/adapters/claude/install_claude_integration.py +265 -0
- package/src/adapters/claude/skills_hook_adapter.py +841 -0
- package/src/adapters/claude/standalone_claude_adapter.py +384 -0
- package/src/adapters/cline/__init__.py +20 -0
- package/src/adapters/cline/config.py +108 -0
- package/src/adapters/cline/install_cline_integration.py +617 -0
- package/src/adapters/cline/mcp_server.py +713 -0
- package/src/adapters/cline/standalone_cline_adapter.py +459 -0
- package/src/adapters/codebuddy/__init__.py +13 -0
- package/src/adapters/codebuddy/buddy_adapter.py +1125 -0
- package/src/adapters/codebuddy/install_codebuddy_integration.py +279 -0
- package/src/adapters/codebuddy/skills_hook_adapter.py +672 -0
- package/src/adapters/codebuddy/skills_integration.py +395 -0
- package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +403 -0
- package/src/adapters/codex/__init__.py +11 -0
- package/src/adapters/codex/base.py +46 -0
- package/src/adapters/codex/install_codex_integration.py +311 -0
- package/src/adapters/codex/mcp_server.py +493 -0
- package/src/adapters/codex/natural_language_parser.py +82 -0
- package/src/adapters/codex/slash_command_adapter.py +326 -0
- package/src/adapters/codex/standalone_codex_adapter.py +362 -0
- package/src/adapters/copilot/__init__.py +13 -0
- package/src/adapters/copilot/install_copilot_integration.py +564 -0
- package/src/adapters/copilot/mcp_adapter.py +772 -0
- package/src/adapters/copilot/mcp_server.py +168 -0
- package/src/adapters/copilot/standalone_copilot_adapter.py +114 -0
- package/src/adapters/gemini/__init__.py +13 -0
- package/src/adapters/gemini/extension_adapter.py +690 -0
- package/src/adapters/gemini/install_gemini_integration.py +257 -0
- package/src/adapters/gemini/standalone_gemini_adapter.py +366 -0
- package/src/adapters/iflow/__init__.py +7 -0
- package/src/adapters/iflow/hook_adapter.py +1038 -0
- package/src/adapters/iflow/hook_installer.py +536 -0
- package/src/adapters/iflow/install_iflow_integration.py +271 -0
- package/src/adapters/iflow/official_hook_adapter.py +1272 -0
- package/src/adapters/iflow/standalone_iflow_adapter.py +48 -0
- package/src/adapters/iflow/workflow_adapter.py +793 -0
- package/src/adapters/qoder/hook_installer.py +732 -0
- package/src/adapters/qoder/install_qoder_integration.py +265 -0
- package/src/adapters/qoder/notification_hook_adapter.py +863 -0
- package/src/adapters/qoder/standalone_qoder_adapter.py +48 -0
- package/src/adapters/qwen/__init__.py +17 -0
- package/src/adapters/qwencode/__init__.py +13 -0
- package/src/adapters/qwencode/inheritance_adapter.py +818 -0
- package/src/adapters/qwencode/install_qwencode_integration.py +276 -0
- package/src/adapters/qwencode/standalone_qwencode_adapter.py +399 -0
- package/src/atomic_collaboration_handler.py +461 -0
- package/src/cli_collaboration_agent.py +697 -0
- package/src/collaboration/hooks.py +315 -0
- package/src/core/__init__.py +21 -0
- package/src/core/ai_environment_scanner.py +331 -0
- package/src/core/base_adapter.py +220 -0
- package/src/core/cli_hook_integration.py +406 -0
- package/src/core/cross_cli_executor.py +713 -0
- package/src/core/cross_cli_mapping.py +1163 -0
- package/src/core/cross_platform_encoding.py +365 -0
- package/src/core/cross_platform_safe_cli.py +894 -0
- package/src/core/direct_cli_executor.py +805 -0
- package/src/core/direct_cli_hook_system.py +958 -0
- package/src/core/enhanced_init_processor.py +427 -0
- package/src/core/graceful_cli_executor.py +912 -0
- package/src/core/md_enhancer.py +342 -0
- package/src/core/md_generator.py +619 -0
- package/src/core/models.py +218 -0
- package/src/core/parser.py +108 -0
- package/src/core/real_cli_hook_system.py +852 -0
- package/src/core/real_cross_cli_system.py +925 -0
- package/src/core/verified_cross_cli_system.py +961 -0
- package/src/deploy.js +737 -0
- package/src/enhanced_deploy.js +303 -0
- package/src/enhanced_universal_cli_setup.py +930 -0
- package/src/kimi_wrapper.py +104 -0
- package/src/main.js +1309 -0
- package/src/shell_integration.py +398 -0
- package/src/simple-main.js +315 -0
- package/src/smart_router_creator.py +323 -0
- package/src/universal_cli_setup.py +1289 -0
- package/src/utils/__init__.py +12 -0
- package/src/utils/cli_detector.py +445 -0
- package/src/utils/file_utils.py +246 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Gemini CLI Extension集成安装脚本
|
|
3
|
+
为Gemini CLI安装跨CLI协作感知能力
|
|
4
|
+
|
|
5
|
+
使用方法:
|
|
6
|
+
python install_gemini_integration.py [--verify|--uninstall]
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
import json
|
|
12
|
+
import shutil
|
|
13
|
+
import argparse
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
|
|
17
|
+
# 获取当前文件目录
|
|
18
|
+
current_dir = Path(__file__).parent
|
|
19
|
+
project_root = current_dir.parent.parent.parent
|
|
20
|
+
|
|
21
|
+
# Gemini CLI配置路径
|
|
22
|
+
GEMINI_CONFIG_DIR = os.path.expanduser("~/.config/gemini")
|
|
23
|
+
GEMINI_EXTENSIONS_FILE = os.path.join(GEMINI_CONFIG_DIR, "extensions.json")
|
|
24
|
+
|
|
25
|
+
def create_gemini_config_directory():
|
|
26
|
+
"""创建Gemini配置目录"""
|
|
27
|
+
os.makedirs(GEMINI_CONFIG_DIR, exist_ok=True)
|
|
28
|
+
print(f"[OK] 创建Gemini配置目录: {GEMINI_CONFIG_DIR}")
|
|
29
|
+
|
|
30
|
+
def install_gemini_extensions():
|
|
31
|
+
"""安装Gemini Extension配置"""
|
|
32
|
+
# 读取现有extensions配置
|
|
33
|
+
existing_extensions = {}
|
|
34
|
+
if os.path.exists(GEMINI_EXTENSIONS_FILE):
|
|
35
|
+
try:
|
|
36
|
+
with open(GEMINI_EXTENSIONS_FILE, 'r', encoding='utf-8') as f:
|
|
37
|
+
existing_extensions = json.load(f)
|
|
38
|
+
except Exception as e:
|
|
39
|
+
print(f"⚠️ 读取现有extensions配置失败: {e}")
|
|
40
|
+
existing_extensions = {}
|
|
41
|
+
|
|
42
|
+
# 定义跨CLI协作的Extension配置
|
|
43
|
+
cross_cli_extensions = {
|
|
44
|
+
"cross_cli_preprocessor": {
|
|
45
|
+
"module": "src.adapters.gemini.extension_adapter",
|
|
46
|
+
"class": "GeminiExtensionAdapter",
|
|
47
|
+
"enabled": True,
|
|
48
|
+
"priority": 100,
|
|
49
|
+
"config": {
|
|
50
|
+
"cross_cli_enabled": True,
|
|
51
|
+
"supported_clis": ["claude", "qwencode", "iflow", "qoder", "codebuddy", "copilot"],
|
|
52
|
+
"auto_detect": True,
|
|
53
|
+
"timeout": 30,
|
|
54
|
+
"error_handling": "continue",
|
|
55
|
+
"collaboration_mode": "active"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"cross_cli_response_processor": {
|
|
59
|
+
"module": "src.adapters.gemini.extension_adapter",
|
|
60
|
+
"class": "GeminiExtensionAdapter",
|
|
61
|
+
"enabled": True,
|
|
62
|
+
"priority": 90,
|
|
63
|
+
"config": {
|
|
64
|
+
"cross_cli_enabled": True,
|
|
65
|
+
"format_cross_cli_results": True,
|
|
66
|
+
"add_collaboration_header": True,
|
|
67
|
+
"include_tool_status": True
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# 合并配置(保留现有配置,添加协作功能)
|
|
73
|
+
merged_extensions = existing_extensions.copy()
|
|
74
|
+
for ext_name, ext_config in cross_cli_extensions.items():
|
|
75
|
+
merged_extensions[ext_name] = ext_config
|
|
76
|
+
|
|
77
|
+
# 写入extensions配置文件
|
|
78
|
+
try:
|
|
79
|
+
with open(GEMINI_EXTENSIONS_FILE, 'w', encoding='utf-8') as f:
|
|
80
|
+
json.dump(merged_extensions, f, indent=2, ensure_ascii=False)
|
|
81
|
+
|
|
82
|
+
print(f"[OK] Gemini Extension配置已安装: {GEMINI_EXTENSIONS_FILE}")
|
|
83
|
+
print("🔗 已安装的Extension:")
|
|
84
|
+
for ext_name in cross_cli_extensions.keys():
|
|
85
|
+
print(f" - {ext_name}: [OK] 跨CLI协作感知")
|
|
86
|
+
|
|
87
|
+
return True
|
|
88
|
+
except Exception as e:
|
|
89
|
+
print(f"❌ 安装Gemini Extension配置失败: {e}")
|
|
90
|
+
return False
|
|
91
|
+
|
|
92
|
+
def copy_adapter_file():
|
|
93
|
+
"""复制适配器文件到Gemini配置目录"""
|
|
94
|
+
try:
|
|
95
|
+
# 创建适配器目录
|
|
96
|
+
adapter_dir = os.path.join(GEMINI_CONFIG_DIR, "adapters")
|
|
97
|
+
os.makedirs(adapter_dir, exist_ok=True)
|
|
98
|
+
|
|
99
|
+
# 复制适配器文件
|
|
100
|
+
adapter_files = [
|
|
101
|
+
"extension_adapter.py",
|
|
102
|
+
"standalone_gemini_adapter.py"
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
for file_name in adapter_files:
|
|
106
|
+
src_file = current_dir / file_name
|
|
107
|
+
dst_file = os.path.join(adapter_dir, file_name)
|
|
108
|
+
|
|
109
|
+
if src_file.exists():
|
|
110
|
+
shutil.copy2(src_file, dst_file)
|
|
111
|
+
print(f"[OK] 复制适配器文件: {file_name}")
|
|
112
|
+
else:
|
|
113
|
+
print(f"⚠️ 适配器文件不存在: {file_name}")
|
|
114
|
+
|
|
115
|
+
return True
|
|
116
|
+
except Exception as e:
|
|
117
|
+
print(f"❌ 复制适配器文件失败: {e}")
|
|
118
|
+
return False
|
|
119
|
+
|
|
120
|
+
def verify_installation():
|
|
121
|
+
"""验证安装是否成功"""
|
|
122
|
+
print("\n🔍 验证Gemini CLI集成安装...")
|
|
123
|
+
|
|
124
|
+
# 检查配置目录
|
|
125
|
+
if not os.path.exists(GEMINI_CONFIG_DIR):
|
|
126
|
+
print(f"❌ 配置目录不存在: {GEMINI_CONFIG_DIR}")
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
# 检查extensions文件
|
|
130
|
+
if not os.path.exists(GEMINI_EXTENSIONS_FILE):
|
|
131
|
+
print(f"❌ Extensions配置文件不存在: {GEMINI_EXTENSIONS_FILE}")
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
# 检查适配器目录
|
|
135
|
+
adapter_dir = os.path.join(GEMINI_CONFIG_DIR, "adapters")
|
|
136
|
+
if not os.path.exists(adapter_dir):
|
|
137
|
+
print(f"❌ 适配器目录不存在: {adapter_dir}")
|
|
138
|
+
return False
|
|
139
|
+
|
|
140
|
+
# 读取并验证extensions配置
|
|
141
|
+
try:
|
|
142
|
+
with open(GEMINI_EXTENSIONS_FILE, 'r', encoding='utf-8') as f:
|
|
143
|
+
extensions_config = json.load(f)
|
|
144
|
+
|
|
145
|
+
required_extensions = ["cross_cli_preprocessor", "cross_cli_response_processor"]
|
|
146
|
+
for ext_name in required_extensions:
|
|
147
|
+
if ext_name in extensions_config:
|
|
148
|
+
ext_config = extensions_config[ext_name]
|
|
149
|
+
if ext_config.get("enabled", False):
|
|
150
|
+
print(f"[OK] Extension {ext_name}: 已启用")
|
|
151
|
+
if "cross_cli_enabled" in ext_config.get("config", {}):
|
|
152
|
+
print(f"[OK] 跨CLI协作: 已启用")
|
|
153
|
+
else:
|
|
154
|
+
print(f"⚠️ Extension {ext_name}: 未启用")
|
|
155
|
+
else:
|
|
156
|
+
print(f"❌ 缺少Extension: {ext_name}")
|
|
157
|
+
|
|
158
|
+
return True
|
|
159
|
+
except Exception as e:
|
|
160
|
+
print(f"❌ 验证配置失败: {e}")
|
|
161
|
+
return False
|
|
162
|
+
|
|
163
|
+
def uninstall_gemini_integration():
|
|
164
|
+
"""卸载Gemini CLI集成"""
|
|
165
|
+
try:
|
|
166
|
+
# 备份现有配置
|
|
167
|
+
if os.path.exists(GEMINI_EXTENSIONS_FILE):
|
|
168
|
+
backup_file = f"{GEMINI_EXTENSIONS_FILE}.backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|
169
|
+
shutil.copy2(GEMINI_EXTENSIONS_FILE, backup_file)
|
|
170
|
+
print(f"📦 已备份现有配置: {backup_file}")
|
|
171
|
+
|
|
172
|
+
# 移除适配器目录
|
|
173
|
+
adapter_dir = os.path.join(GEMINI_CONFIG_DIR, "adapters")
|
|
174
|
+
if os.path.exists(adapter_dir):
|
|
175
|
+
shutil.rmtree(adapter_dir)
|
|
176
|
+
print(f"🗑️ 已删除适配器目录: {adapter_dir}")
|
|
177
|
+
|
|
178
|
+
print("[OK] Gemini CLI集成已卸载")
|
|
179
|
+
return True
|
|
180
|
+
except Exception as e:
|
|
181
|
+
print(f"❌ 卸载失败: {e}")
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
def main():
|
|
185
|
+
parser = argparse.ArgumentParser(
|
|
186
|
+
description="Gemini CLI跨CLI协作集成安装脚本",
|
|
187
|
+
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"--install",
|
|
192
|
+
action="store_true",
|
|
193
|
+
help="安装Gemini CLI跨CLI协作集成"
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
parser.add_argument(
|
|
197
|
+
"--verify",
|
|
198
|
+
action="store_true",
|
|
199
|
+
help="验证Gemini CLI集成安装"
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
parser.add_argument(
|
|
203
|
+
"--uninstall",
|
|
204
|
+
action="store_true",
|
|
205
|
+
help="卸载Gemini CLI跨CLI协作集成"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
args = parser.parse_args()
|
|
209
|
+
|
|
210
|
+
print("[INSTALL] Gemini CLI跨CLI协作集成安装器")
|
|
211
|
+
print("=" * 50)
|
|
212
|
+
|
|
213
|
+
if args.uninstall:
|
|
214
|
+
print("[UNINSTALL] 卸载模式...")
|
|
215
|
+
success = uninstall_gemini_integration()
|
|
216
|
+
elif args.verify:
|
|
217
|
+
print("[VERIFY] 验证模式...")
|
|
218
|
+
success = verify_installation()
|
|
219
|
+
elif args.install or len(sys.argv) == 1:
|
|
220
|
+
print("[INSTALL] 安装模式...")
|
|
221
|
+
|
|
222
|
+
# 1. 创建配置目录
|
|
223
|
+
print("\nStep 1. 创建配置目录...")
|
|
224
|
+
create_gemini_config_directory()
|
|
225
|
+
|
|
226
|
+
# 2. 安装Extension配置
|
|
227
|
+
print("\nStep 2. 安装Extension配置...")
|
|
228
|
+
extensions_success = install_gemini_extensions()
|
|
229
|
+
|
|
230
|
+
# 3. 复制适配器文件
|
|
231
|
+
print("\nStep 3. 复制适配器文件...")
|
|
232
|
+
adapter_success = copy_adapter_file()
|
|
233
|
+
|
|
234
|
+
# 4. 验证安装
|
|
235
|
+
print("\nStep 4. 验证安装...")
|
|
236
|
+
verify_success = verify_installation()
|
|
237
|
+
|
|
238
|
+
success = extensions_success and adapter_success and verify_success
|
|
239
|
+
|
|
240
|
+
if success:
|
|
241
|
+
print("\n🎉 Gemini CLI集成安装成功!")
|
|
242
|
+
print("\n[INFO] 安装摘要:")
|
|
243
|
+
print(f" [OK] 配置目录: {GEMINI_CONFIG_DIR}")
|
|
244
|
+
print(f" [OK] Extensions配置: {GEMINI_EXTENSIONS_FILE}")
|
|
245
|
+
print(f" [OK] 适配器目录: {os.path.join(GEMINI_CONFIG_DIR, 'adapters')}")
|
|
246
|
+
|
|
247
|
+
print("\n[INSTALL] 下一步:")
|
|
248
|
+
print(" 1. 安装其他CLI工具的集成: ai-cli-router deploy --all")
|
|
249
|
+
print(" 2. 初始化项目: ai-cli-router init")
|
|
250
|
+
print(" 3. 开始使用协作功能: gemini-cli '请用claude帮我审查代码'")
|
|
251
|
+
else:
|
|
252
|
+
print("\n❌ Gemini CLI集成安装失败,请检查错误信息")
|
|
253
|
+
else:
|
|
254
|
+
parser.print_help()
|
|
255
|
+
|
|
256
|
+
if __name__ == "__main__":
|
|
257
|
+
main()
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"""
|
|
2
|
+
独立 Gemini CLI 适配器 - 完全无抽象层
|
|
3
|
+
|
|
4
|
+
基于 Gemini CLI 官方 Extension 系统的原生集成:
|
|
5
|
+
- 使用 Gemini CLI 官方 Extension 机制
|
|
6
|
+
- 无任何抽象基类或 Factory 系统
|
|
7
|
+
- 不改变 CLI 启动和使用方式
|
|
8
|
+
- 纯粹的原生扩展实现
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import json
|
|
13
|
+
import logging
|
|
14
|
+
import asyncio
|
|
15
|
+
import re
|
|
16
|
+
from typing import Dict, Any, Optional, List
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GeminiExtensionContext:
|
|
23
|
+
"""Gemini CLI Extension 上下文 - 独立实现"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, prompt: str = "", metadata: Optional[Dict] = None):
|
|
26
|
+
self.prompt = prompt
|
|
27
|
+
self.metadata = metadata or {}
|
|
28
|
+
self.session_id = self.metadata.get('session_id', 'unknown')
|
|
29
|
+
self.user_id = self.metadata.get('user_id', 'unknown')
|
|
30
|
+
self.timestamp = datetime.now()
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class StandaloneGeminiAdapter:
|
|
34
|
+
"""
|
|
35
|
+
独立的 Gemini CLI Extension 适配器
|
|
36
|
+
|
|
37
|
+
直接基于 Gemini CLI 官方 Extension 系统,无任何抽象层:
|
|
38
|
+
- @extend('preprocessor') 装饰器
|
|
39
|
+
- Extension 配置系统
|
|
40
|
+
- 原生请求处理管道
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(self):
|
|
44
|
+
"""初始化 - 纯实现,无抽象"""
|
|
45
|
+
self.cli_name = "gemini"
|
|
46
|
+
self.version = "1.0.0"
|
|
47
|
+
|
|
48
|
+
# Extension 配置
|
|
49
|
+
self.extensions_file = os.path.expanduser("~/.config/gemini/extensions.json")
|
|
50
|
+
self.extension_registered = False
|
|
51
|
+
|
|
52
|
+
# 统计信息
|
|
53
|
+
self.execution_count = 0
|
|
54
|
+
self.error_count = 0
|
|
55
|
+
self.extension_calls_count = 0
|
|
56
|
+
self.cross_cli_calls_count = 0
|
|
57
|
+
self.processed_requests: List[Dict[str, Any]] = []
|
|
58
|
+
self.last_execution: Optional[datetime] = None
|
|
59
|
+
|
|
60
|
+
# 直接跨CLI处理器 - 无Factory
|
|
61
|
+
self._cli_handlers = {}
|
|
62
|
+
self._init_cli_handlers()
|
|
63
|
+
|
|
64
|
+
# 配置
|
|
65
|
+
self.config = self._load_config()
|
|
66
|
+
|
|
67
|
+
logger.info("独立 Gemini CLI Extension 适配器初始化完成")
|
|
68
|
+
|
|
69
|
+
def _load_config(self) -> Dict[str, Any]:
|
|
70
|
+
"""加载配置"""
|
|
71
|
+
config_file = os.path.join(os.path.dirname(__file__), "config.json")
|
|
72
|
+
try:
|
|
73
|
+
with open(config_file, 'r', encoding='utf-8') as f:
|
|
74
|
+
return json.load(f)
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.warning(f"配置加载失败: {e}")
|
|
77
|
+
return {"extensions": [], "integration_settings": {"enable_cross_cli": True}}
|
|
78
|
+
|
|
79
|
+
def _init_cli_handlers(self):
|
|
80
|
+
"""初始化跨CLI处理器 - 直接导入,无Factory"""
|
|
81
|
+
try:
|
|
82
|
+
# 可以直接添加其他CLI处理器
|
|
83
|
+
# from ..claude.standalone_claude_adapter import get_standalone_claude_adapter
|
|
84
|
+
# self._cli_handlers['claude'] = get_standalone_claude_adapter()
|
|
85
|
+
logger.info("跨CLI处理器初始化完成")
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.warning(f"跨CLI处理器初始化失败: {e}")
|
|
88
|
+
|
|
89
|
+
def is_available(self) -> bool:
|
|
90
|
+
"""检查是否可用 - 直接检查 Gemini CLI"""
|
|
91
|
+
try:
|
|
92
|
+
# 检查Gemini CLI是否可用
|
|
93
|
+
import subprocess
|
|
94
|
+
result = subprocess.run(['gemini', '--version'], capture_output=True, text=True, timeout=10)
|
|
95
|
+
return result.returncode == 0
|
|
96
|
+
except Exception:
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
async def execute_task(self, task: str, context: Dict[str, Any] = None) -> str:
|
|
100
|
+
"""
|
|
101
|
+
执行任务 - 纯实现,无抽象层
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
task: 任务内容
|
|
105
|
+
context: 执行上下文
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
str: 执行结果
|
|
109
|
+
"""
|
|
110
|
+
if context is None:
|
|
111
|
+
context = {}
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
self.execution_count += 1
|
|
115
|
+
self.last_execution = datetime.now()
|
|
116
|
+
|
|
117
|
+
# 创建 Extension 上下文
|
|
118
|
+
extension_context = GeminiExtensionContext(
|
|
119
|
+
prompt=task,
|
|
120
|
+
metadata=context.get('metadata', {})
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# 通过 Extension 预处理器处理
|
|
124
|
+
result = await self._preprocess_request(extension_context)
|
|
125
|
+
|
|
126
|
+
# 如果预处理器没有处理,则本地处理
|
|
127
|
+
if result is None:
|
|
128
|
+
# 检测跨CLI调用
|
|
129
|
+
cross_cli_intent = self._detect_cross_cli_intent(task)
|
|
130
|
+
if cross_cli_intent:
|
|
131
|
+
return await self._handle_cross_cli_call(cross_cli_intent, context)
|
|
132
|
+
|
|
133
|
+
# 本地 Gemini 处理
|
|
134
|
+
result = f"[Gemini CLI 本地处理] {task}"
|
|
135
|
+
|
|
136
|
+
return result
|
|
137
|
+
|
|
138
|
+
except Exception as e:
|
|
139
|
+
self.error_count += 1
|
|
140
|
+
logger.error(f"任务执行失败: {task}, 错误: {e}")
|
|
141
|
+
return f"[错误] {task} 执行失败: {str(e)}"
|
|
142
|
+
|
|
143
|
+
def _detect_cross_cli_intent(self, text: str) -> Optional[str]:
|
|
144
|
+
"""检测跨CLI调用意图 - 简单实现,无抽象"""
|
|
145
|
+
# 中文模式
|
|
146
|
+
cn_patterns = [
|
|
147
|
+
r'请用(\w+)\s*帮我?([^。!?\n]*)',
|
|
148
|
+
r'调用(\w+)\s*来([^。!?\n]*)',
|
|
149
|
+
r'用(\w+)\s*帮我?([^。!?\n]*)'
|
|
150
|
+
]
|
|
151
|
+
|
|
152
|
+
for pattern in cn_patterns:
|
|
153
|
+
match = re.search(pattern, text, re.IGNORECASE)
|
|
154
|
+
if match:
|
|
155
|
+
cli_name = match.group(1).lower()
|
|
156
|
+
task = match.group(2).strip()
|
|
157
|
+
if cli_name != self.cli_name: # 避免自我调用
|
|
158
|
+
return f"{cli_name} {task}"
|
|
159
|
+
|
|
160
|
+
# 英文模式
|
|
161
|
+
en_patterns = [
|
|
162
|
+
r'use\s+(\w+)\s+to\s+([^.\n!?]*)',
|
|
163
|
+
r'call\s+(\w+)\s+to\s+([^.\n!?]*)',
|
|
164
|
+
r'ask\s+(\w+)\s+for\s+([^.\n!?]*)'
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
for pattern in en_patterns:
|
|
168
|
+
match = re.search(pattern, text, re.IGNORECASE)
|
|
169
|
+
if match:
|
|
170
|
+
cli_name = match.group(1).lower()
|
|
171
|
+
task = match.group(2).strip()
|
|
172
|
+
if cli_name != self.cli_name: # 避免自我调用
|
|
173
|
+
return f"{cli_name} {task}"
|
|
174
|
+
|
|
175
|
+
return None
|
|
176
|
+
|
|
177
|
+
async def _handle_cross_cli_call(self, command: str, context: Dict[str, Any]) -> str:
|
|
178
|
+
"""处理跨CLI调用 - 直接实现,无抽象层"""
|
|
179
|
+
if ' ' not in command:
|
|
180
|
+
return "跨CLI命令格式错误,请使用: <CLI> <任务>"
|
|
181
|
+
|
|
182
|
+
cli_name, task = command.split(' ', 1)
|
|
183
|
+
cli_name = cli_name.lower()
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
self.cross_cli_calls_count += 1
|
|
187
|
+
|
|
188
|
+
# 直接调用目标CLI - 无抽象层
|
|
189
|
+
if cli_name in self._cli_handlers:
|
|
190
|
+
handler = self._cli_handlers[cli_name]
|
|
191
|
+
if hasattr(handler, 'execute_task'):
|
|
192
|
+
result = await handler.execute_task(task, {'source_cli': 'gemini'})
|
|
193
|
+
return self._format_cross_cli_result(cli_name, task, result)
|
|
194
|
+
|
|
195
|
+
# 模拟跨CLI调用结果
|
|
196
|
+
result = f"[{cli_name.upper()} CLI 处理结果] {task}"
|
|
197
|
+
return self._format_cross_cli_result(cli_name, task, result)
|
|
198
|
+
|
|
199
|
+
except Exception as e:
|
|
200
|
+
logger.error(f"跨CLI调用失败: {cli_name}, {e}")
|
|
201
|
+
return f"跨CLI调用失败: {cli_name} - {str(e)}"
|
|
202
|
+
|
|
203
|
+
def _format_cross_cli_result(self, target_cli: str, task: str, result: str) -> str:
|
|
204
|
+
"""格式化跨CLI调用结果"""
|
|
205
|
+
return f"""## 🔗 跨CLI调用结果
|
|
206
|
+
|
|
207
|
+
**源工具**: Gemini CLI (Extension 系统)
|
|
208
|
+
**目标工具**: {target_cli.upper()}
|
|
209
|
+
**任务**: {task}
|
|
210
|
+
**执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
{result}
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
*Gemini Extension 系统原生集成 - 无抽象层*"""
|
|
219
|
+
|
|
220
|
+
# Extension 预处理器 - 基于 Gemini CLI 官方 Extension 机制
|
|
221
|
+
async def _preprocess_request(self, context: GeminiExtensionContext) -> Optional[str]:
|
|
222
|
+
"""
|
|
223
|
+
请求预处理器
|
|
224
|
+
|
|
225
|
+
这是基于 Gemini CLI 官方 Extension 系统的原生实现。
|
|
226
|
+
使用 @extend('preprocessor') 装饰器等效功能。
|
|
227
|
+
"""
|
|
228
|
+
try:
|
|
229
|
+
self.extension_calls_count += 1
|
|
230
|
+
user_input = context.prompt
|
|
231
|
+
|
|
232
|
+
# 记录请求
|
|
233
|
+
self.processed_requests.append({
|
|
234
|
+
'extension_type': 'preprocessor',
|
|
235
|
+
'prompt': user_input,
|
|
236
|
+
'metadata': context.metadata,
|
|
237
|
+
'timestamp': datetime.now().isoformat()
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
# 检测跨CLI调用
|
|
241
|
+
cross_cli_intent = self._detect_cross_cli_intent(user_input)
|
|
242
|
+
if cross_cli_intent:
|
|
243
|
+
return await self._handle_cross_cli_call(cross_cli_intent, context.metadata)
|
|
244
|
+
|
|
245
|
+
# 不是跨CLI调用,让 Gemini 正常处理
|
|
246
|
+
return None
|
|
247
|
+
|
|
248
|
+
except Exception as e:
|
|
249
|
+
logger.error(f"Extension 预处理器失败: {e}")
|
|
250
|
+
self.error_count += 1
|
|
251
|
+
return None # 错误时让 Gemini 继续正常处理
|
|
252
|
+
|
|
253
|
+
async def initialize(self) -> bool:
|
|
254
|
+
"""初始化适配器"""
|
|
255
|
+
try:
|
|
256
|
+
# 检查 Gemini CLI 环境
|
|
257
|
+
if not self.is_available():
|
|
258
|
+
logger.warning("Gemini CLI 不可用")
|
|
259
|
+
return False
|
|
260
|
+
|
|
261
|
+
# 注册 Extension 到 Gemini CLI
|
|
262
|
+
await self._register_extension()
|
|
263
|
+
|
|
264
|
+
# 创建配置目录
|
|
265
|
+
os.makedirs(os.path.dirname(self.extensions_file), exist_ok=True)
|
|
266
|
+
|
|
267
|
+
self.extension_registered = True
|
|
268
|
+
logger.info("Gemini Extension 适配器初始化成功 - 独立模式")
|
|
269
|
+
return True
|
|
270
|
+
|
|
271
|
+
except Exception as e:
|
|
272
|
+
logger.error(f"适配器初始化失败: {e}")
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
async def _register_extension(self) -> bool:
|
|
276
|
+
"""注册 Extension 到 Gemini CLI"""
|
|
277
|
+
try:
|
|
278
|
+
# 读取现有 extensions 配置
|
|
279
|
+
extensions_config = self._load_extensions_config()
|
|
280
|
+
|
|
281
|
+
# 添加跨CLI Extension
|
|
282
|
+
cross_cli_extension = {
|
|
283
|
+
"name": "cross-cli-extension",
|
|
284
|
+
"version": "1.0.0",
|
|
285
|
+
"description": "跨CLI调用集成Extension系统",
|
|
286
|
+
"author": "Smart CLI Router",
|
|
287
|
+
"module": "src.adapters.gemini.standalone_gemini_adapter",
|
|
288
|
+
"class": "StandaloneGeminiAdapter",
|
|
289
|
+
"enabled": True,
|
|
290
|
+
"decorator": "@extend('preprocessor')",
|
|
291
|
+
"priority": 100,
|
|
292
|
+
"hooks": ["preprocessor"]
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
# 检查是否已存在
|
|
296
|
+
existing_extensions = extensions_config.get('extensions', [])
|
|
297
|
+
extension_exists = any(
|
|
298
|
+
ext['name'] == cross_cli_extension['name']
|
|
299
|
+
for ext in existing_extensions
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
if not extension_exists:
|
|
303
|
+
existing_extensions.append(cross_cli_extension)
|
|
304
|
+
extensions_config['extensions'] = existing_extensions
|
|
305
|
+
await self._save_extensions_config(extensions_config)
|
|
306
|
+
logger.info(f"注册 Extension: {cross_cli_extension['name']}")
|
|
307
|
+
else:
|
|
308
|
+
logger.info("Extension 已存在,跳过注册")
|
|
309
|
+
|
|
310
|
+
return True
|
|
311
|
+
|
|
312
|
+
except Exception as e:
|
|
313
|
+
logger.error(f"Extension 注册失败: {e}")
|
|
314
|
+
return False
|
|
315
|
+
|
|
316
|
+
def _load_extensions_config(self) -> Dict[str, Any]:
|
|
317
|
+
"""加载 Extensions 配置"""
|
|
318
|
+
if os.path.exists(self.extensions_file):
|
|
319
|
+
try:
|
|
320
|
+
with open(self.extensions_file, 'r', encoding='utf-8') as f:
|
|
321
|
+
return json.load(f)
|
|
322
|
+
except Exception as e:
|
|
323
|
+
logger.warning(f"加载 Extension 配置失败: {e}")
|
|
324
|
+
|
|
325
|
+
return {"version": "1.0", "extensions": []}
|
|
326
|
+
|
|
327
|
+
async def _save_extensions_config(self, config: Dict[str, Any]) -> bool:
|
|
328
|
+
"""保存 Extensions 配置"""
|
|
329
|
+
try:
|
|
330
|
+
with open(self.extensions_file, 'w', encoding='utf-8') as f:
|
|
331
|
+
json.dump(config, f, indent=2, ensure_ascii=False)
|
|
332
|
+
return True
|
|
333
|
+
except Exception as e:
|
|
334
|
+
logger.error(f"保存 Extension 配置失败: {e}")
|
|
335
|
+
return False
|
|
336
|
+
|
|
337
|
+
def get_statistics(self) -> Dict[str, Any]:
|
|
338
|
+
"""获取统计信息 - 直接实现"""
|
|
339
|
+
success_rate = ((self.execution_count - self.error_count) / self.execution_count) if self.execution_count > 0 else 1.0
|
|
340
|
+
|
|
341
|
+
return {
|
|
342
|
+
'cli_name': self.cli_name,
|
|
343
|
+
'version': self.version,
|
|
344
|
+
'extension_registered': self.extension_registered,
|
|
345
|
+
'execution_count': self.execution_count,
|
|
346
|
+
'extension_calls_count': self.extension_calls_count,
|
|
347
|
+
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
348
|
+
'error_count': self.error_count,
|
|
349
|
+
'success_rate': success_rate,
|
|
350
|
+
'last_execution': self.last_execution.isoformat() if self.last_execution else None,
|
|
351
|
+
'design': 'standalone_extension_native',
|
|
352
|
+
'no_abstraction': True,
|
|
353
|
+
'extensions_file': self.extensions_file
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
# 便捷函数 - 无抽象层
|
|
358
|
+
def get_standalone_gemini_adapter() -> StandaloneGeminiAdapter:
|
|
359
|
+
"""获取独立的 Gemini CLI 适配器实例"""
|
|
360
|
+
return StandaloneGeminiAdapter()
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# 保持向后兼容的函数名
|
|
364
|
+
def get_gemini_module_adapter() -> StandaloneGeminiAdapter:
|
|
365
|
+
"""获取 Gemini Module 适配器实例(向后兼容)"""
|
|
366
|
+
return get_standalone_gemini_adapter()
|