stigmergy 1.0.68 → 1.0.70
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/README.en.md +306 -300
- package/README.md +469 -301
- package/package.json +97 -81
- package/scripts/publish.js +268 -0
- package/scripts/simple-publish.js +59 -0
- package/src/index.js +12 -0
- package/test/enhanced-main-alignment.test.js +298 -0
- package/test/hook-system-integration-test.js +307 -0
- package/test/natural-language-skills-test.js +320 -0
- package/test/nl-integration-test.js +179 -0
- package/test/parameter-parsing-test.js +143 -0
- package/test/real-test.js +435 -0
- package/test/system-compatibility-test.js +447 -0
- package/test/tdd-fixes-test.js +211 -0
- package/test/third-party-skills-test.js +321 -0
- package/test/tool-selection-integration-test.js +157 -0
- package/test/unit/cli-scanner.test.js +291 -0
- package/test/unit/cross-cli-executor.test.js +399 -0
- package/src/adapters/claude/__init__.py +0 -13
- package/src/adapters/claude/claude_skills_integration.py +0 -609
- package/src/adapters/claude/hook_adapter.py +0 -663
- package/src/adapters/claude/install_claude_integration.py +0 -265
- package/src/adapters/claude/skills_hook_adapter.py +0 -841
- package/src/adapters/claude/standalone_claude_adapter.py +0 -384
- package/src/adapters/cline/__init__.py +0 -20
- package/src/adapters/cline/config.py +0 -108
- package/src/adapters/cline/install_cline_integration.py +0 -617
- package/src/adapters/cline/mcp_server.py +0 -713
- package/src/adapters/cline/standalone_cline_adapter.py +0 -459
- package/src/adapters/codebuddy/__init__.py +0 -13
- package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
- package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
- package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
- package/src/adapters/codebuddy/skills_integration.py +0 -395
- package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
- package/src/adapters/codex/__init__.py +0 -11
- package/src/adapters/codex/base.py +0 -46
- package/src/adapters/codex/install_codex_integration.py +0 -311
- package/src/adapters/codex/mcp_server.py +0 -493
- package/src/adapters/codex/natural_language_parser.py +0 -82
- package/src/adapters/codex/slash_command_adapter.py +0 -326
- package/src/adapters/codex/standalone_codex_adapter.py +0 -362
- package/src/adapters/copilot/__init__.py +0 -13
- package/src/adapters/copilot/install_copilot_integration.py +0 -564
- package/src/adapters/copilot/mcp_adapter.py +0 -772
- package/src/adapters/copilot/mcp_server.py +0 -168
- package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
- package/src/adapters/gemini/__init__.py +0 -13
- package/src/adapters/gemini/extension_adapter.py +0 -690
- package/src/adapters/gemini/install_gemini_integration.py +0 -257
- package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
- package/src/adapters/iflow/__init__.py +0 -7
- package/src/adapters/iflow/hook_adapter.py +0 -1038
- package/src/adapters/iflow/hook_installer.py +0 -536
- package/src/adapters/iflow/install_iflow_integration.py +0 -271
- package/src/adapters/iflow/official_hook_adapter.py +0 -1272
- package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
- package/src/adapters/iflow/workflow_adapter.py +0 -793
- package/src/adapters/qoder/hook_installer.py +0 -732
- package/src/adapters/qoder/install_qoder_integration.py +0 -265
- package/src/adapters/qoder/notification_hook_adapter.py +0 -863
- package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
- package/src/adapters/qwen/__init__.py +0 -17
- package/src/adapters/qwencode/__init__.py +0 -13
- package/src/adapters/qwencode/inheritance_adapter.py +0 -818
- package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
- package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
- package/src/atomic_collaboration_handler.py +0 -461
- package/src/cli_collaboration_agent.py +0 -697
- package/src/collaboration/hooks.py +0 -315
- package/src/core/__init__.py +0 -21
- package/src/core/ai_environment_scanner.py +0 -331
- package/src/core/base_adapter.py +0 -220
- package/src/core/cli_hook_integration.py +0 -406
- package/src/core/cross_cli_executor.py +0 -713
- package/src/core/cross_cli_mapping.py +0 -1165
- package/src/core/cross_platform_encoding.py +0 -365
- package/src/core/cross_platform_safe_cli.py +0 -894
- package/src/core/direct_cli_executor.py +0 -805
- package/src/core/direct_cli_hook_system.py +0 -958
- package/src/core/enhanced_init_processor.py +0 -467
- package/src/core/graceful_cli_executor.py +0 -912
- package/src/core/md_enhancer.py +0 -342
- package/src/core/md_generator.py +0 -619
- package/src/core/models.py +0 -218
- package/src/core/parser.py +0 -108
- package/src/core/real_cli_hook_system.py +0 -852
- package/src/core/real_cross_cli_system.py +0 -925
- package/src/core/verified_cross_cli_system.py +0 -961
- package/src/deploy.js +0 -737
- package/src/enhanced-main.js +0 -626
- package/src/enhanced_deploy.js +0 -303
- package/src/enhanced_universal_cli_setup.py +0 -930
- package/src/kimi_wrapper.py +0 -104
- package/src/main.js +0 -1309
- package/src/shell_integration.py +0 -398
- package/src/simple-main.js +0 -315
- package/src/smart_router_creator.py +0 -323
- package/src/universal_cli_setup.py +0 -1289
- package/src/utils/__init__.py +0 -12
- package/src/utils/cli_detector.py +0 -445
- package/src/utils/file_utils.py +0 -246
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
QwenCode CLI Inheritance集成安装脚本
|
|
3
|
-
为QwenCode CLI安装跨CLI协作感知能力
|
|
4
|
-
|
|
5
|
-
使用方法:
|
|
6
|
-
python install_qwencode_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
|
-
# QwenCode CLI配置路径
|
|
22
|
-
QWENCODE_CONFIG_DIR = os.path.expanduser("~/.config/qwencode")
|
|
23
|
-
QWENCODE_CONFIG_FILE = os.path.join(QWENCODE_CONFIG_DIR, "config.yml")
|
|
24
|
-
|
|
25
|
-
def create_qwencode_config_directory():
|
|
26
|
-
"""创建QwenCode配置目录"""
|
|
27
|
-
os.makedirs(QWENCODE_CONFIG_DIR, exist_ok=True)
|
|
28
|
-
print(f"[OK] 创建QwenCode配置目录: {QWENCODE_CONFIG_DIR}")
|
|
29
|
-
|
|
30
|
-
def install_qwencode_plugins():
|
|
31
|
-
"""安装QwenCode Plugin配置"""
|
|
32
|
-
# 读取现有config配置
|
|
33
|
-
existing_config = {}
|
|
34
|
-
if os.path.exists(QWENCODE_CONFIG_FILE):
|
|
35
|
-
try:
|
|
36
|
-
import yaml
|
|
37
|
-
with open(QWENCODE_CONFIG_FILE, 'r', encoding='utf-8') as f:
|
|
38
|
-
existing_config = yaml.safe_load(f) or {}
|
|
39
|
-
except Exception as e:
|
|
40
|
-
print(f"⚠️ 读取现有config配置失败: {e}")
|
|
41
|
-
existing_config = {}
|
|
42
|
-
|
|
43
|
-
# 定义跨CLI协作的Plugin配置
|
|
44
|
-
cross_cli_plugins = {
|
|
45
|
-
"cross_cli_inheritance_adapter": {
|
|
46
|
-
"name": "CrossCLIAdapterPlugin",
|
|
47
|
-
"module": "src.adapters.qwencode.inheritance_adapter",
|
|
48
|
-
"class": "QwenCodeInheritanceAdapter",
|
|
49
|
-
"enabled": True,
|
|
50
|
-
"priority": 100,
|
|
51
|
-
"base_class": "BaseQwenCodePlugin",
|
|
52
|
-
"handlers": [
|
|
53
|
-
"on_prompt_received",
|
|
54
|
-
"on_code_generated",
|
|
55
|
-
"on_error_occurred",
|
|
56
|
-
"on_file_created",
|
|
57
|
-
"on_before_save"
|
|
58
|
-
],
|
|
59
|
-
"config": {
|
|
60
|
-
"cross_cli_enabled": True,
|
|
61
|
-
"supported_clis": ["claude", "gemini", "iflow", "qoder", "codebuddy", "copilot"],
|
|
62
|
-
"auto_detect": True,
|
|
63
|
-
"timeout": 30,
|
|
64
|
-
"error_handling": "continue",
|
|
65
|
-
"collaboration_mode": "active"
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
# 合并配置(保留现有配置,添加协作功能)
|
|
71
|
-
merged_config = existing_config.copy()
|
|
72
|
-
if 'plugins' not in merged_config:
|
|
73
|
-
merged_config['plugins'] = []
|
|
74
|
-
|
|
75
|
-
# 检查是否已存在跨CLI插件
|
|
76
|
-
existing_plugins = merged_config.get('plugins', [])
|
|
77
|
-
cross_cli_plugin_exists = any(
|
|
78
|
-
plugin.get('name') == 'CrossCLIAdapterPlugin'
|
|
79
|
-
for plugin in existing_plugins
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
if not cross_cli_plugin_exists:
|
|
83
|
-
merged_config['plugins'].append(cross_cli_plugins['cross_cli_inheritance_adapter'])
|
|
84
|
-
|
|
85
|
-
# 写入config配置文件
|
|
86
|
-
try:
|
|
87
|
-
import yaml
|
|
88
|
-
with open(QWENCODE_CONFIG_FILE, 'w', encoding='utf-8') as f:
|
|
89
|
-
yaml.dump(merged_config, f, default_flow_style=False, allow_unicode=True)
|
|
90
|
-
|
|
91
|
-
print(f"[OK] QwenCode配置已安装: {QWENCODE_CONFIG_FILE}")
|
|
92
|
-
print("🔗 已安装的Plugin:")
|
|
93
|
-
for plugin in merged_config.get('plugins', []):
|
|
94
|
-
if plugin.get('name') == 'CrossCLIAdapterPlugin':
|
|
95
|
-
print(f" - {plugin['name']}: [OK] 跨CLI协作感知")
|
|
96
|
-
|
|
97
|
-
return True
|
|
98
|
-
except Exception as e:
|
|
99
|
-
print(f"❌ 安装QwenCode配置失败: {e}")
|
|
100
|
-
return False
|
|
101
|
-
|
|
102
|
-
def copy_adapter_file():
|
|
103
|
-
"""复制适配器文件到QwenCode配置目录"""
|
|
104
|
-
try:
|
|
105
|
-
# 创建适配器目录
|
|
106
|
-
adapter_dir = os.path.join(QWENCODE_CONFIG_DIR, "plugins")
|
|
107
|
-
os.makedirs(adapter_dir, exist_ok=True)
|
|
108
|
-
|
|
109
|
-
# 复制适配器文件
|
|
110
|
-
adapter_files = [
|
|
111
|
-
"inheritance_adapter.py",
|
|
112
|
-
"standalone_qwencode_adapter.py"
|
|
113
|
-
]
|
|
114
|
-
|
|
115
|
-
for file_name in adapter_files:
|
|
116
|
-
src_file = current_dir / file_name
|
|
117
|
-
dst_file = os.path.join(adapter_dir, file_name)
|
|
118
|
-
|
|
119
|
-
if src_file.exists():
|
|
120
|
-
shutil.copy2(src_file, dst_file)
|
|
121
|
-
print(f"[OK] 复制适配器文件: {file_name}")
|
|
122
|
-
else:
|
|
123
|
-
print(f"⚠️ 适配器文件不存在: {file_name}")
|
|
124
|
-
|
|
125
|
-
return True
|
|
126
|
-
except Exception as e:
|
|
127
|
-
print(f"❌ 复制适配器文件失败: {e}")
|
|
128
|
-
return False
|
|
129
|
-
|
|
130
|
-
def verify_installation():
|
|
131
|
-
"""验证安装是否成功"""
|
|
132
|
-
print("\n🔍 验证QwenCode CLI集成安装...")
|
|
133
|
-
|
|
134
|
-
# 检查配置目录
|
|
135
|
-
if not os.path.exists(QWENCODE_CONFIG_DIR):
|
|
136
|
-
print(f"❌ 配置目录不存在: {QWENCODE_CONFIG_DIR}")
|
|
137
|
-
return False
|
|
138
|
-
|
|
139
|
-
# 检查配置文件
|
|
140
|
-
if not os.path.exists(QWENCODE_CONFIG_FILE):
|
|
141
|
-
print(f"❌ 配置文件不存在: {QWENCODE_CONFIG_FILE}")
|
|
142
|
-
return False
|
|
143
|
-
|
|
144
|
-
# 检查适配器目录
|
|
145
|
-
adapter_dir = os.path.join(QWENCODE_CONFIG_DIR, "plugins")
|
|
146
|
-
if not os.path.exists(adapter_dir):
|
|
147
|
-
print(f"❌ 适配器目录不存在: {adapter_dir}")
|
|
148
|
-
return False
|
|
149
|
-
|
|
150
|
-
# 读取并验证配置
|
|
151
|
-
try:
|
|
152
|
-
import yaml
|
|
153
|
-
with open(QWENCODE_CONFIG_FILE, 'r', encoding='utf-8') as f:
|
|
154
|
-
config = yaml.safe_load(f) or {}
|
|
155
|
-
|
|
156
|
-
plugins = config.get('plugins', [])
|
|
157
|
-
cross_cli_plugin = None
|
|
158
|
-
|
|
159
|
-
for plugin in plugins:
|
|
160
|
-
if plugin.get('name') == 'CrossCLIAdapterPlugin':
|
|
161
|
-
cross_cli_plugin = plugin
|
|
162
|
-
break
|
|
163
|
-
|
|
164
|
-
if cross_cli_plugin:
|
|
165
|
-
plugin_config = cross_cli_plugin.get('config', {})
|
|
166
|
-
if plugin_config.get('cross_cli_enabled'):
|
|
167
|
-
print("[SUCCESS] 跨CLI协作插件: 已启用")
|
|
168
|
-
print("[SUCCESS] 支持的CLI工具:")
|
|
169
|
-
supported_clis = plugin_config.get('supported_clis', [])
|
|
170
|
-
for cli in supported_clis:
|
|
171
|
-
print(f" - {cli}")
|
|
172
|
-
print("[SUCCESS] 自动检测: 已启用")
|
|
173
|
-
return True
|
|
174
|
-
else:
|
|
175
|
-
print("[WARNING] 跨CLI协作插件: 未启用")
|
|
176
|
-
return False
|
|
177
|
-
else:
|
|
178
|
-
print("❌ 跨CLI协作插件: 未找到")
|
|
179
|
-
return False
|
|
180
|
-
|
|
181
|
-
except Exception as e:
|
|
182
|
-
print(f"❌ 验证配置失败: {e}")
|
|
183
|
-
return False
|
|
184
|
-
|
|
185
|
-
def uninstall_qwencode_integration():
|
|
186
|
-
"""卸载QwenCode集成"""
|
|
187
|
-
try:
|
|
188
|
-
# 备份现有配置
|
|
189
|
-
if os.path.exists(QWENCODE_CONFIG_FILE):
|
|
190
|
-
backup_file = f"{QWENCODE_CONFIG_FILE}.backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|
191
|
-
shutil.copy2(QWENCODE_CONFIG_FILE, backup_file)
|
|
192
|
-
print(f"📦 已备份现有配置: {backup_file}")
|
|
193
|
-
|
|
194
|
-
# 移除适配器目录
|
|
195
|
-
adapter_dir = os.path.join(QWENCODE_CONFIG_DIR, "plugins")
|
|
196
|
-
if os.path.exists(adapter_dir):
|
|
197
|
-
shutil.rmtree(adapter_dir)
|
|
198
|
-
print(f"🗑️ 已删除适配器目录: {adapter_dir}")
|
|
199
|
-
|
|
200
|
-
print("[OK] QwenCode集成已卸载")
|
|
201
|
-
return True
|
|
202
|
-
except Exception as e:
|
|
203
|
-
print(f"❌ 卸载失败: {e}")
|
|
204
|
-
return False
|
|
205
|
-
|
|
206
|
-
def main():
|
|
207
|
-
parser = argparse.ArgumentParser(
|
|
208
|
-
description="QwenCode CLI跨CLI协作集成安装脚本",
|
|
209
|
-
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
parser.add_argument(
|
|
213
|
-
"--install",
|
|
214
|
-
action="store_true",
|
|
215
|
-
help="安装QwenCode CLI跨CLI协作集成"
|
|
216
|
-
)
|
|
217
|
-
|
|
218
|
-
parser.add_argument(
|
|
219
|
-
"--verify",
|
|
220
|
-
action="store_true",
|
|
221
|
-
help="验证QwenCode CLI集成安装"
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
parser.add_argument(
|
|
225
|
-
"--uninstall",
|
|
226
|
-
action="store_true",
|
|
227
|
-
help="卸载QwenCode CLI跨CLI协作集成"
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
args = parser.parse_args()
|
|
231
|
-
|
|
232
|
-
print("[INSTALL] QwenCode CLI跨CLI协作集成安装器")
|
|
233
|
-
print("=" * 60)
|
|
234
|
-
|
|
235
|
-
if args.uninstall:
|
|
236
|
-
print("[UNINSTALL] 卸载模式...")
|
|
237
|
-
success = uninstall_qwencode_integration()
|
|
238
|
-
elif args.verify:
|
|
239
|
-
print("[VERIFY] 验证模式...")
|
|
240
|
-
success = verify_installation()
|
|
241
|
-
elif args.install or len(sys.argv) == 1:
|
|
242
|
-
print("[INSTALL] 安装模式...")
|
|
243
|
-
|
|
244
|
-
# 1. 创建配置目录
|
|
245
|
-
print("Step 1. 创建配置目录...")
|
|
246
|
-
create_qwencode_config_directory()
|
|
247
|
-
|
|
248
|
-
# 2. 安装插件配置
|
|
249
|
-
print("Step 2. 安装插件配置...")
|
|
250
|
-
config_success = install_qwencode_plugins()
|
|
251
|
-
|
|
252
|
-
# 3. 复制适配器文件
|
|
253
|
-
print("Step 3. 复制适配器文件...")
|
|
254
|
-
adapter_success = copy_adapter_file()
|
|
255
|
-
|
|
256
|
-
success = config_success and adapter_success
|
|
257
|
-
|
|
258
|
-
if success:
|
|
259
|
-
print("\n[SUCCESS] QwenCode CLI集成安装成功!")
|
|
260
|
-
print("\n[INFO] 安装摘要:")
|
|
261
|
-
print(f" [SUCCESS] 配置目录: {QWENCODE_CONFIG_DIR}")
|
|
262
|
-
print(f" [SUCCESS] 配置文件: {QWENCODE_CONFIG_FILE}")
|
|
263
|
-
print(f" [SUCCESS] 适配器目录: {os.path.join(QWENCODE_CONFIG_DIR, 'plugins')}")
|
|
264
|
-
print(" [SUCCESS] 跨CLI协作: 已启用")
|
|
265
|
-
|
|
266
|
-
print("\n[INFO] 下一步:")
|
|
267
|
-
print(" 1. 安装其他CLI工具的集成: ai-cli-router deploy --all")
|
|
268
|
-
print(" 2. 初始化项目: ai-cli-router init")
|
|
269
|
-
print(" 3. 开始协作: qwencode-cli '请用gemini帮我分析代码'")
|
|
270
|
-
else:
|
|
271
|
-
print("\n❌ QwenCode CLI集成安装失败,请检查错误信息")
|
|
272
|
-
else:
|
|
273
|
-
parser.print_help()
|
|
274
|
-
|
|
275
|
-
if __name__ == "__main__":
|
|
276
|
-
main()
|
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
独立 QwenCode CLI 适配器 - 完全无抽象层
|
|
3
|
-
|
|
4
|
-
基于 QwenCode CLI 官方 Class Inheritance 系统的原生集成:
|
|
5
|
-
- 使用 QwenCode CLI 官方 Class Inheritance 机制
|
|
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 QwenCodePluginContext:
|
|
23
|
-
"""QwenCode CLI Plugin 上下文 - 独立实现"""
|
|
24
|
-
|
|
25
|
-
def __init__(self, command: str = "", args: List[str] = None, metadata: Optional[Dict] = None):
|
|
26
|
-
self.command = command
|
|
27
|
-
self.args = args or []
|
|
28
|
-
self.metadata = metadata or {}
|
|
29
|
-
self.session_id = self.metadata.get('session_id', 'unknown')
|
|
30
|
-
self.user_id = self.metadata.get('user_id', 'unknown')
|
|
31
|
-
self.timestamp = datetime.now()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class StandaloneQwenCodeAdapter:
|
|
35
|
-
"""
|
|
36
|
-
独立的 QwenCode CLI Class Inheritance 适配器
|
|
37
|
-
|
|
38
|
-
直接基于 QwenCode CLI 官方 Class Inheritance 系统,无任何抽象层:
|
|
39
|
-
- 继承 BaseQwenCodePlugin 类
|
|
40
|
-
- 重写 process_command() 和 process_request() 方法
|
|
41
|
-
- 保持所有原始功能
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
def __init__(self):
|
|
45
|
-
"""初始化 - 纯实现,无抽象"""
|
|
46
|
-
self.cli_name = "qwencode"
|
|
47
|
-
self.version = "1.0.0"
|
|
48
|
-
self.class_name = "CrossCLIPlugin"
|
|
49
|
-
|
|
50
|
-
# Plugin 配置
|
|
51
|
-
self.plugin_config_file = os.path.expanduser("~/.config/qwencode/plugins.json")
|
|
52
|
-
self.plugin_registered = False
|
|
53
|
-
|
|
54
|
-
# 统计信息
|
|
55
|
-
self.execution_count = 0
|
|
56
|
-
self.error_count = 0
|
|
57
|
-
self.plugin_calls_count = 0
|
|
58
|
-
self.cross_cli_calls_count = 0
|
|
59
|
-
self.processed_commands: List[Dict[str, Any]] = []
|
|
60
|
-
self.last_execution: Optional[datetime] = None
|
|
61
|
-
|
|
62
|
-
# 直接跨CLI处理器 - 无Factory
|
|
63
|
-
self._cli_handlers = {}
|
|
64
|
-
self._init_cli_handlers()
|
|
65
|
-
|
|
66
|
-
# 配置
|
|
67
|
-
self.config = self._load_config()
|
|
68
|
-
|
|
69
|
-
logger.info("独立 QwenCode CLI Class Inheritance 适配器初始化完成")
|
|
70
|
-
|
|
71
|
-
def _load_config(self) -> Dict[str, Any]:
|
|
72
|
-
"""加载配置"""
|
|
73
|
-
config_file = os.path.join(os.path.dirname(__file__), "config.json")
|
|
74
|
-
try:
|
|
75
|
-
with open(config_file, 'r', encoding='utf-8') as f:
|
|
76
|
-
return json.load(f)
|
|
77
|
-
except Exception as e:
|
|
78
|
-
logger.warning(f"配置加载失败: {e}")
|
|
79
|
-
return {"plugins": [], "integration_settings": {"enable_cross_cli": True}}
|
|
80
|
-
|
|
81
|
-
def _init_cli_handlers(self):
|
|
82
|
-
"""初始化跨CLI处理器 - 直接导入,无Factory"""
|
|
83
|
-
try:
|
|
84
|
-
# 可以直接添加其他CLI处理器
|
|
85
|
-
# from ..claude.standalone_claude_adapter import get_standalone_claude_adapter
|
|
86
|
-
# self._cli_handlers['claude'] = get_standalone_claude_adapter()
|
|
87
|
-
logger.info("跨CLI处理器初始化完成")
|
|
88
|
-
except Exception as e:
|
|
89
|
-
logger.warning(f"跨CLI处理器初始化失败: {e}")
|
|
90
|
-
|
|
91
|
-
def is_available(self) -> bool:
|
|
92
|
-
"""检查是否可用 - 直接检查 QwenCode CLI"""
|
|
93
|
-
try:
|
|
94
|
-
# 检查QwenCode CLI是否可用
|
|
95
|
-
import subprocess
|
|
96
|
-
result = subprocess.run(['qwencode', '--version'], capture_output=True, text=True, timeout=10)
|
|
97
|
-
return result.returncode == 0
|
|
98
|
-
except Exception:
|
|
99
|
-
return False
|
|
100
|
-
|
|
101
|
-
async def execute_task(self, task: str, context: Dict[str, Any] = None) -> str:
|
|
102
|
-
"""
|
|
103
|
-
执行任务 - 纯实现,无抽象层
|
|
104
|
-
|
|
105
|
-
Args:
|
|
106
|
-
task: 任务内容
|
|
107
|
-
context: 执行上下文
|
|
108
|
-
|
|
109
|
-
Returns:
|
|
110
|
-
str: 执行结果
|
|
111
|
-
"""
|
|
112
|
-
if context is None:
|
|
113
|
-
context = {}
|
|
114
|
-
|
|
115
|
-
try:
|
|
116
|
-
self.execution_count += 1
|
|
117
|
-
self.last_execution = datetime.now()
|
|
118
|
-
|
|
119
|
-
# 创建 Plugin 上下文
|
|
120
|
-
plugin_context = QwenCodePluginContext(
|
|
121
|
-
command=task,
|
|
122
|
-
metadata=context.get('metadata', {})
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
# 通过 Plugin 处理命令
|
|
126
|
-
result = await self.process_command(task, plugin_context)
|
|
127
|
-
|
|
128
|
-
# 如果 Plugin 没有特殊处理,则本地处理
|
|
129
|
-
if not result or result == task:
|
|
130
|
-
# 检测跨CLI调用
|
|
131
|
-
cross_cli_intent = self._detect_cross_cli_intent(task)
|
|
132
|
-
if cross_cli_intent:
|
|
133
|
-
return await self._handle_cross_cli_call(cross_cli_intent, context)
|
|
134
|
-
|
|
135
|
-
# 本地 QwenCode 处理
|
|
136
|
-
result = f"[QwenCode CLI 本地处理] {task}"
|
|
137
|
-
|
|
138
|
-
return result
|
|
139
|
-
|
|
140
|
-
except Exception as e:
|
|
141
|
-
self.error_count += 1
|
|
142
|
-
logger.error(f"任务执行失败: {task}, 错误: {e}")
|
|
143
|
-
return f"[错误] {task} 执行失败: {str(e)}"
|
|
144
|
-
|
|
145
|
-
def _detect_cross_cli_intent(self, text: str) -> Optional[str]:
|
|
146
|
-
"""检测跨CLI调用意图 - 简单实现,无抽象"""
|
|
147
|
-
# 中文模式
|
|
148
|
-
cn_patterns = [
|
|
149
|
-
r'请用(\w+)\s*帮我?([^。!?\n]*)',
|
|
150
|
-
r'调用(\w+)\s*来([^。!?\n]*)',
|
|
151
|
-
r'用(\w+)\s*帮我?([^。!?\n]*)'
|
|
152
|
-
]
|
|
153
|
-
|
|
154
|
-
for pattern in cn_patterns:
|
|
155
|
-
match = re.search(pattern, text, re.IGNORECASE)
|
|
156
|
-
if match:
|
|
157
|
-
cli_name = match.group(1).lower()
|
|
158
|
-
task = match.group(2).strip()
|
|
159
|
-
if cli_name != self.cli_name: # 避免自我调用
|
|
160
|
-
return f"{cli_name} {task}"
|
|
161
|
-
|
|
162
|
-
# 英文模式
|
|
163
|
-
en_patterns = [
|
|
164
|
-
r'use\s+(\w+)\s+to\s+([^.\n!?]*)',
|
|
165
|
-
r'call\s+(\w+)\s+to\s+([^.\n!?]*)',
|
|
166
|
-
r'ask\s+(\w+)\s+for\s+([^.\n!?]*)'
|
|
167
|
-
]
|
|
168
|
-
|
|
169
|
-
for pattern in en_patterns:
|
|
170
|
-
match = re.search(pattern, text, re.IGNORECASE)
|
|
171
|
-
if match:
|
|
172
|
-
cli_name = match.group(1).lower()
|
|
173
|
-
task = match.group(2).strip()
|
|
174
|
-
if cli_name != self.cli_name: # 避免自我调用
|
|
175
|
-
return f"{cli_name} {task}"
|
|
176
|
-
|
|
177
|
-
return None
|
|
178
|
-
|
|
179
|
-
async def _handle_cross_cli_call(self, command: str, context: Dict[str, Any]) -> str:
|
|
180
|
-
"""处理跨CLI调用 - 直接实现,无抽象层"""
|
|
181
|
-
if ' ' not in command:
|
|
182
|
-
return "跨CLI命令格式错误,请使用: <CLI> <任务>"
|
|
183
|
-
|
|
184
|
-
cli_name, task = command.split(' ', 1)
|
|
185
|
-
cli_name = cli_name.lower()
|
|
186
|
-
|
|
187
|
-
try:
|
|
188
|
-
self.cross_cli_calls_count += 1
|
|
189
|
-
|
|
190
|
-
# 直接调用目标CLI - 无抽象层
|
|
191
|
-
if cli_name in self._cli_handlers:
|
|
192
|
-
handler = self._cli_handlers[cli_name]
|
|
193
|
-
if hasattr(handler, 'execute_task'):
|
|
194
|
-
result = await handler.execute_task(task, {'source_cli': 'qwencode'})
|
|
195
|
-
return self._format_cross_cli_result(cli_name, task, result)
|
|
196
|
-
|
|
197
|
-
# 模拟跨CLI调用结果
|
|
198
|
-
result = f"[{cli_name.upper()} CLI 处理结果] {task}"
|
|
199
|
-
return self._format_cross_cli_result(cli_name, task, result)
|
|
200
|
-
|
|
201
|
-
except Exception as e:
|
|
202
|
-
logger.error(f"跨CLI调用失败: {cli_name}, {e}")
|
|
203
|
-
return f"跨CLI调用失败: {cli_name} - {str(e)}"
|
|
204
|
-
|
|
205
|
-
def _format_cross_cli_result(self, target_cli: str, task: str, result: str) -> str:
|
|
206
|
-
"""格式化跨CLI调用结果"""
|
|
207
|
-
return f"""## 🔗 跨CLI调用结果
|
|
208
|
-
|
|
209
|
-
**源工具**: QwenCode CLI (Class Inheritance 系统)
|
|
210
|
-
**目标工具**: {target_cli.upper()}
|
|
211
|
-
**任务**: {task}
|
|
212
|
-
**执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
{result}
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
*QwenCode Class Inheritance 系统原生集成 - 无抽象层*"""
|
|
221
|
-
|
|
222
|
-
# Plugin 方法 - 基于 QwenCode CLI 官方 Class Inheritance 机制
|
|
223
|
-
async def process_command(self, command: str, context: QwenCodePluginContext) -> str:
|
|
224
|
-
"""
|
|
225
|
-
处理命令 - 重写父类方法
|
|
226
|
-
|
|
227
|
-
这是基于 QwenCode CLI 官方 Class Inheritance 系统的原生实现。
|
|
228
|
-
等效于继承 BaseQwenCodePlugin 并重写 process_command()。
|
|
229
|
-
"""
|
|
230
|
-
try:
|
|
231
|
-
self.plugin_calls_count += 1
|
|
232
|
-
|
|
233
|
-
# 记录命令处理
|
|
234
|
-
self.processed_commands.append({
|
|
235
|
-
'plugin_type': 'process_command',
|
|
236
|
-
'command': command,
|
|
237
|
-
'context': context.__dict__,
|
|
238
|
-
'timestamp': datetime.now().isoformat()
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
# 检测跨CLI调用
|
|
242
|
-
cross_cli_intent = self._detect_cross_cli_intent(command)
|
|
243
|
-
if cross_cli_intent:
|
|
244
|
-
# 异步处理跨CLI调用
|
|
245
|
-
result = await self._handle_cross_cli_call(cross_cli_intent, context.metadata)
|
|
246
|
-
return result
|
|
247
|
-
|
|
248
|
-
# 不是跨CLI调用,让 QwenCode 正常处理
|
|
249
|
-
return command # 返回原命令让系统继续处理
|
|
250
|
-
|
|
251
|
-
except Exception as e:
|
|
252
|
-
logger.error(f"Plugin 命令处理失败: {e}")
|
|
253
|
-
self.error_count += 1
|
|
254
|
-
return command # 错误时返回原命令让系统继续处理
|
|
255
|
-
|
|
256
|
-
async def process_request(self, request: str, context: QwenCodePluginContext) -> str:
|
|
257
|
-
"""
|
|
258
|
-
处理请求 - 重写父类方法
|
|
259
|
-
|
|
260
|
-
基于 QwenCode CLI 官方 Class Inheritance 系统的原生实现。
|
|
261
|
-
"""
|
|
262
|
-
try:
|
|
263
|
-
# 记录请求处理
|
|
264
|
-
self.processed_commands.append({
|
|
265
|
-
'plugin_type': 'process_request',
|
|
266
|
-
'request': request,
|
|
267
|
-
'context': context.__dict__,
|
|
268
|
-
'timestamp': datetime.now().isoformat()
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
# 检测跨CLI调用
|
|
272
|
-
cross_cli_intent = self._detect_cross_cli_intent(request)
|
|
273
|
-
if cross_cli_intent:
|
|
274
|
-
result = await self._handle_cross_cli_call(cross_cli_intent, context.metadata)
|
|
275
|
-
return result
|
|
276
|
-
|
|
277
|
-
# 不是跨CLI调用,让 QwenCode 正常处理
|
|
278
|
-
return request
|
|
279
|
-
|
|
280
|
-
except Exception as e:
|
|
281
|
-
logger.error(f"Plugin 请求处理失败: {e}")
|
|
282
|
-
self.error_count += 1
|
|
283
|
-
return request
|
|
284
|
-
|
|
285
|
-
async def initialize(self) -> bool:
|
|
286
|
-
"""初始化适配器"""
|
|
287
|
-
try:
|
|
288
|
-
# 检查 QwenCode CLI 环境
|
|
289
|
-
if not self.is_available():
|
|
290
|
-
logger.warning("QwenCode CLI 不可用")
|
|
291
|
-
return False
|
|
292
|
-
|
|
293
|
-
# 注册 Plugin 到 QwenCode CLI
|
|
294
|
-
await self._register_plugin()
|
|
295
|
-
|
|
296
|
-
# 创建配置目录
|
|
297
|
-
os.makedirs(os.path.dirname(self.plugin_config_file), exist_ok=True)
|
|
298
|
-
|
|
299
|
-
self.plugin_registered = True
|
|
300
|
-
logger.info("QwenCode Class Inheritance 适配器初始化成功 - 独立模式")
|
|
301
|
-
return True
|
|
302
|
-
|
|
303
|
-
except Exception as e:
|
|
304
|
-
logger.error(f"适配器初始化失败: {e}")
|
|
305
|
-
return False
|
|
306
|
-
|
|
307
|
-
async def _register_plugin(self) -> bool:
|
|
308
|
-
"""注册 Plugin 到 QwenCode CLI"""
|
|
309
|
-
try:
|
|
310
|
-
# 读取现有 plugins 配置
|
|
311
|
-
plugins_config = self._load_plugins_config()
|
|
312
|
-
|
|
313
|
-
# 添加跨CLI Plugin
|
|
314
|
-
cross_cli_plugin = {
|
|
315
|
-
"name": "CrossCLIPlugin",
|
|
316
|
-
"version": "1.0.0",
|
|
317
|
-
"description": "跨CLI调用集成Plugin系统",
|
|
318
|
-
"author": "Smart CLI Router",
|
|
319
|
-
"module": "src.adapters.qwencode.standalone_qwencode_adapter",
|
|
320
|
-
"class": "StandaloneQwenCodeAdapter",
|
|
321
|
-
"enabled": True,
|
|
322
|
-
"base_class": "BaseQwenCodePlugin",
|
|
323
|
-
"priority": 100,
|
|
324
|
-
"methods": ["process_command", "process_request"]
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
# 检查是否已存在
|
|
328
|
-
existing_plugins = plugins_config.get('plugins', [])
|
|
329
|
-
plugin_exists = any(
|
|
330
|
-
plugin['name'] == cross_cli_plugin['name']
|
|
331
|
-
for plugin in existing_plugins
|
|
332
|
-
)
|
|
333
|
-
|
|
334
|
-
if not plugin_exists:
|
|
335
|
-
existing_plugins.append(cross_cli_plugin)
|
|
336
|
-
plugins_config['plugins'] = existing_plugins
|
|
337
|
-
await self._save_plugins_config(plugins_config)
|
|
338
|
-
logger.info(f"注册 Plugin: {cross_cli_plugin['name']}")
|
|
339
|
-
else:
|
|
340
|
-
logger.info("Plugin 已存在,跳过注册")
|
|
341
|
-
|
|
342
|
-
return True
|
|
343
|
-
|
|
344
|
-
except Exception as e:
|
|
345
|
-
logger.error(f"Plugin 注册失败: {e}")
|
|
346
|
-
return False
|
|
347
|
-
|
|
348
|
-
def _load_plugins_config(self) -> Dict[str, Any]:
|
|
349
|
-
"""加载 Plugins 配置"""
|
|
350
|
-
if os.path.exists(self.plugin_config_file):
|
|
351
|
-
try:
|
|
352
|
-
with open(self.plugin_config_file, 'r', encoding='utf-8') as f:
|
|
353
|
-
return json.load(f)
|
|
354
|
-
except Exception as e:
|
|
355
|
-
logger.warning(f"加载 Plugin 配置失败: {e}")
|
|
356
|
-
|
|
357
|
-
return {"version": "1.0", "plugins": []}
|
|
358
|
-
|
|
359
|
-
async def _save_plugins_config(self, config: Dict[str, Any]) -> bool:
|
|
360
|
-
"""保存 Plugins 配置"""
|
|
361
|
-
try:
|
|
362
|
-
with open(self.plugin_config_file, 'w', encoding='utf-8') as f:
|
|
363
|
-
json.dump(config, f, indent=2, ensure_ascii=False)
|
|
364
|
-
return True
|
|
365
|
-
except Exception as e:
|
|
366
|
-
logger.error(f"保存 Plugin 配置失败: {e}")
|
|
367
|
-
return False
|
|
368
|
-
|
|
369
|
-
def get_statistics(self) -> Dict[str, Any]:
|
|
370
|
-
"""获取统计信息 - 直接实现"""
|
|
371
|
-
success_rate = ((self.execution_count - self.error_count) / self.execution_count) if self.execution_count > 0 else 1.0
|
|
372
|
-
|
|
373
|
-
return {
|
|
374
|
-
'cli_name': self.cli_name,
|
|
375
|
-
'version': self.version,
|
|
376
|
-
'class_name': self.class_name,
|
|
377
|
-
'plugin_registered': self.plugin_registered,
|
|
378
|
-
'execution_count': self.execution_count,
|
|
379
|
-
'plugin_calls_count': self.plugin_calls_count,
|
|
380
|
-
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
381
|
-
'error_count': self.error_count,
|
|
382
|
-
'success_rate': success_rate,
|
|
383
|
-
'last_execution': self.last_execution.isoformat() if self.last_execution else None,
|
|
384
|
-
'design': 'standalone_inheritance_native',
|
|
385
|
-
'no_abstraction': True,
|
|
386
|
-
'plugin_config_file': self.plugin_config_file
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
# 便捷函数 - 无抽象层
|
|
391
|
-
def get_standalone_qwencode_adapter() -> StandaloneQwenCodeAdapter:
|
|
392
|
-
"""获取独立的 QwenCode CLI 适配器实例"""
|
|
393
|
-
return StandaloneQwenCodeAdapter()
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
# 保持向后兼容的函数名
|
|
397
|
-
def get_qwencode_cross_adapter() -> StandaloneQwenCodeAdapter:
|
|
398
|
-
"""获取 QwenCode Cross 适配器实例(向后兼容)"""
|
|
399
|
-
return get_standalone_qwencode_adapter()
|