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.
Files changed (102) hide show
  1. package/README.en.md +306 -300
  2. package/README.md +469 -301
  3. package/package.json +97 -81
  4. package/scripts/publish.js +268 -0
  5. package/scripts/simple-publish.js +59 -0
  6. package/src/index.js +12 -0
  7. package/test/enhanced-main-alignment.test.js +298 -0
  8. package/test/hook-system-integration-test.js +307 -0
  9. package/test/natural-language-skills-test.js +320 -0
  10. package/test/nl-integration-test.js +179 -0
  11. package/test/parameter-parsing-test.js +143 -0
  12. package/test/real-test.js +435 -0
  13. package/test/system-compatibility-test.js +447 -0
  14. package/test/tdd-fixes-test.js +211 -0
  15. package/test/third-party-skills-test.js +321 -0
  16. package/test/tool-selection-integration-test.js +157 -0
  17. package/test/unit/cli-scanner.test.js +291 -0
  18. package/test/unit/cross-cli-executor.test.js +399 -0
  19. package/src/adapters/claude/__init__.py +0 -13
  20. package/src/adapters/claude/claude_skills_integration.py +0 -609
  21. package/src/adapters/claude/hook_adapter.py +0 -663
  22. package/src/adapters/claude/install_claude_integration.py +0 -265
  23. package/src/adapters/claude/skills_hook_adapter.py +0 -841
  24. package/src/adapters/claude/standalone_claude_adapter.py +0 -384
  25. package/src/adapters/cline/__init__.py +0 -20
  26. package/src/adapters/cline/config.py +0 -108
  27. package/src/adapters/cline/install_cline_integration.py +0 -617
  28. package/src/adapters/cline/mcp_server.py +0 -713
  29. package/src/adapters/cline/standalone_cline_adapter.py +0 -459
  30. package/src/adapters/codebuddy/__init__.py +0 -13
  31. package/src/adapters/codebuddy/buddy_adapter.py +0 -1125
  32. package/src/adapters/codebuddy/install_codebuddy_integration.py +0 -279
  33. package/src/adapters/codebuddy/skills_hook_adapter.py +0 -672
  34. package/src/adapters/codebuddy/skills_integration.py +0 -395
  35. package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +0 -403
  36. package/src/adapters/codex/__init__.py +0 -11
  37. package/src/adapters/codex/base.py +0 -46
  38. package/src/adapters/codex/install_codex_integration.py +0 -311
  39. package/src/adapters/codex/mcp_server.py +0 -493
  40. package/src/adapters/codex/natural_language_parser.py +0 -82
  41. package/src/adapters/codex/slash_command_adapter.py +0 -326
  42. package/src/adapters/codex/standalone_codex_adapter.py +0 -362
  43. package/src/adapters/copilot/__init__.py +0 -13
  44. package/src/adapters/copilot/install_copilot_integration.py +0 -564
  45. package/src/adapters/copilot/mcp_adapter.py +0 -772
  46. package/src/adapters/copilot/mcp_server.py +0 -168
  47. package/src/adapters/copilot/standalone_copilot_adapter.py +0 -114
  48. package/src/adapters/gemini/__init__.py +0 -13
  49. package/src/adapters/gemini/extension_adapter.py +0 -690
  50. package/src/adapters/gemini/install_gemini_integration.py +0 -257
  51. package/src/adapters/gemini/standalone_gemini_adapter.py +0 -366
  52. package/src/adapters/iflow/__init__.py +0 -7
  53. package/src/adapters/iflow/hook_adapter.py +0 -1038
  54. package/src/adapters/iflow/hook_installer.py +0 -536
  55. package/src/adapters/iflow/install_iflow_integration.py +0 -271
  56. package/src/adapters/iflow/official_hook_adapter.py +0 -1272
  57. package/src/adapters/iflow/standalone_iflow_adapter.py +0 -48
  58. package/src/adapters/iflow/workflow_adapter.py +0 -793
  59. package/src/adapters/qoder/hook_installer.py +0 -732
  60. package/src/adapters/qoder/install_qoder_integration.py +0 -265
  61. package/src/adapters/qoder/notification_hook_adapter.py +0 -863
  62. package/src/adapters/qoder/standalone_qoder_adapter.py +0 -48
  63. package/src/adapters/qwen/__init__.py +0 -17
  64. package/src/adapters/qwencode/__init__.py +0 -13
  65. package/src/adapters/qwencode/inheritance_adapter.py +0 -818
  66. package/src/adapters/qwencode/install_qwencode_integration.py +0 -276
  67. package/src/adapters/qwencode/standalone_qwencode_adapter.py +0 -399
  68. package/src/atomic_collaboration_handler.py +0 -461
  69. package/src/cli_collaboration_agent.py +0 -697
  70. package/src/collaboration/hooks.py +0 -315
  71. package/src/core/__init__.py +0 -21
  72. package/src/core/ai_environment_scanner.py +0 -331
  73. package/src/core/base_adapter.py +0 -220
  74. package/src/core/cli_hook_integration.py +0 -406
  75. package/src/core/cross_cli_executor.py +0 -713
  76. package/src/core/cross_cli_mapping.py +0 -1165
  77. package/src/core/cross_platform_encoding.py +0 -365
  78. package/src/core/cross_platform_safe_cli.py +0 -894
  79. package/src/core/direct_cli_executor.py +0 -805
  80. package/src/core/direct_cli_hook_system.py +0 -958
  81. package/src/core/enhanced_init_processor.py +0 -467
  82. package/src/core/graceful_cli_executor.py +0 -912
  83. package/src/core/md_enhancer.py +0 -342
  84. package/src/core/md_generator.py +0 -619
  85. package/src/core/models.py +0 -218
  86. package/src/core/parser.py +0 -108
  87. package/src/core/real_cli_hook_system.py +0 -852
  88. package/src/core/real_cross_cli_system.py +0 -925
  89. package/src/core/verified_cross_cli_system.py +0 -961
  90. package/src/deploy.js +0 -737
  91. package/src/enhanced-main.js +0 -626
  92. package/src/enhanced_deploy.js +0 -303
  93. package/src/enhanced_universal_cli_setup.py +0 -930
  94. package/src/kimi_wrapper.py +0 -104
  95. package/src/main.js +0 -1309
  96. package/src/shell_integration.py +0 -398
  97. package/src/simple-main.js +0 -315
  98. package/src/smart_router_creator.py +0 -323
  99. package/src/universal_cli_setup.py +0 -1289
  100. package/src/utils/__init__.py +0 -12
  101. package/src/utils/cli_detector.py +0 -445
  102. 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()