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,818 +0,0 @@
1
- """
2
- QwenCode CLI Class Inheritance适配器 - 基于QwenCode官方Class Inheritance系统的原生集成
3
-
4
- 这是TDD驱动的实现,基于test_qwencode_adapter.py中的测试用例
5
- 完全符合项目约束条件:
6
- - 使用QwenCode CLI官方Class Inheritance机制
7
- - 不改变CLI启动和使用方式
8
- - 不依赖包装器
9
- - 完全无损扩展
10
- """
11
-
12
- import os
13
- import json
14
- import logging
15
- import asyncio
16
- import importlib
17
- import sys
18
- from typing import Dict, Any, Optional, List, Type
19
- from datetime import datetime
20
- from pathlib import Path
21
-
22
- from ...core.base_adapter import BaseCrossCLIAdapter, IntentResult
23
- from ...core.parser import NaturalLanguageParser
24
-
25
- logger = logging.getLogger(__name__)
26
-
27
-
28
- class PluginContext:
29
- """QwenCode CLI Plugin上下文模拟类"""
30
-
31
- def __init__(self, prompt: str = "", metadata: Optional[Dict] = None):
32
- self.prompt = prompt
33
- self.metadata = metadata or {}
34
- self.session_id = self.metadata.get('session_id', 'unknown')
35
- self.user_id = self.metadata.get('user_id', 'unknown')
36
- self.plugin_name = "cross-cli-adapter"
37
- self.version = "1.0.0"
38
- self.class_name = "CrossCLIAdapterPlugin"
39
- self.timestamp = datetime.now()
40
-
41
-
42
- class QwenCodeInheritanceAdapter(BaseCrossCLIAdapter):
43
- """
44
- QwenCode CLI Class Inheritance适配器
45
-
46
- 通过QwenCode CLI官方Class Inheritance系统实现跨CLI调用功能。
47
- 这是完全基于原生机制的无损扩展实现。
48
-
49
- Inheritance机制:
50
- - 继承BaseQwenCodePlugin类
51
- - 重写关键方法实现跨CLI功能
52
- - Plugin生命周期管理
53
- - 配置文件驱动
54
- """
55
-
56
- def __init__(self, cli_name: str = "qwencode"):
57
- """
58
- 初始化QwenCode Inheritance适配器
59
-
60
- Args:
61
- cli_name: CLI工具名称,默认为"qwencode"
62
- """
63
- super().__init__(cli_name)
64
-
65
- # Inheritance相关配置
66
- self.config_file = os.path.expanduser("~/.config/qwencode/config.yml")
67
- self.plugins_loaded = False
68
- self.plugin_handlers = {
69
- 'on_before_execute': self.on_before_execute,
70
- 'on_after_execute': self.on_after_execute,
71
- 'on_prompt_received': self.on_prompt_received,
72
- 'on_code_generated': self.on_code_generated,
73
- 'on_error_occurred': self.on_error_occurred,
74
- 'on_file_created': self.on_file_created,
75
- 'on_before_save': self.on_before_save,
76
- }
77
-
78
- # 统计信息
79
- self.plugin_calls_count = 0
80
- self.cross_cli_calls_count = 0
81
- self.processed_requests: List[Dict[str, Any]] = []
82
-
83
- # 解析器
84
- self.parser = NaturalLanguageParser()
85
-
86
- # 跨CLI适配器工厂
87
- from ...core.base_adapter import get_cross_cli_adapter
88
- self.get_adapter = get_cross_cli_adapter
89
-
90
- # Inheritance系统状态
91
- self.base_class = None
92
- self.plugin_module = None
93
- self.inheritance_setup_complete = False
94
-
95
- async def initialize(self) -> bool:
96
- """
97
- 初始化适配器
98
-
99
- Returns:
100
- bool: 初始化是否成功
101
- """
102
- try:
103
- # 1. 检查QwenCode CLI环境
104
- if not self._check_qwencode_environment():
105
- logger.error("QwenCode CLI环境检查失败")
106
- return False
107
-
108
- # 2. 设置Class Inheritance系统
109
- if not await self._setup_inheritance_system():
110
- logger.error("Class Inheritance系统设置失败")
111
- return False
112
-
113
- # 3. 加载插件
114
- if not await self._load_plugins():
115
- logger.error("插件加载失败")
116
- return False
117
-
118
- # 4. 创建配置目录
119
- await self._ensure_config_directory()
120
-
121
- self.plugins_loaded = True
122
- logger.info("QwenCode Class Inheritance适配器初始化成功")
123
- return True
124
-
125
- except Exception as e:
126
- logger.error(f"初始化QwenCode Class Inheritance适配器失败: {e}")
127
- self.record_error()
128
- return False
129
-
130
- async def _setup_inheritance_system(self) -> bool:
131
- """
132
- 设置Class Inheritance系统
133
-
134
- Returns:
135
- bool: 设置是否成功
136
- """
137
- try:
138
- # 尝试导入QwenCode的基础Plugin类
139
- try:
140
- # 这里模拟导入QwenCode的基础类
141
- # 实际实现中需要根据QwenCode的实际API调整
142
- base_class_path = "qwencode.plugins.base"
143
-
144
- # 创建模拟的基础类用于测试
145
- class MockBaseQwenCodePlugin:
146
- def __init__(self):
147
- self.name = "BasePlugin"
148
- self.version = "1.0.0"
149
- self.enabled = True
150
-
151
- def execute(self, prompt: str, **kwargs):
152
- return f"Mock execution: {prompt}"
153
-
154
- def validate_input(self, prompt: str) -> bool:
155
- return bool(prompt and prompt.strip())
156
-
157
- def format_output(self, result: str) -> str:
158
- return result
159
-
160
- self.base_class = MockBaseQwenCodePlugin
161
- logger.info("QwenCode基础Plugin类导入成功")
162
-
163
- except ImportError as e:
164
- logger.warning(f"无法导入QwenCode基础类,使用模拟类: {e}")
165
- # 创建模拟基础类
166
- class MockBaseQwenCodePlugin:
167
- def __init__(self):
168
- self.name = "BasePlugin"
169
- self.version = "1.0.0"
170
- self.enabled = True
171
-
172
- def execute(self, prompt: str, **kwargs):
173
- return f"Mock execution: {prompt}"
174
-
175
- def validate_input(self, prompt: str) -> bool:
176
- return bool(prompt and prompt.strip())
177
-
178
- def format_output(self, result: str) -> str:
179
- return result
180
-
181
- self.base_class = MockBaseQwenCodePlugin
182
-
183
- # 创建插件模块
184
- plugin_module_path = f"qwencode.plugins.{self.plugin_name.lower()}"
185
- self.plugin_module = type('PluginModule', (), {})
186
-
187
- self.inheritance_setup_complete = True
188
- return True
189
-
190
- except Exception as e:
191
- logger.error(f"设置Class Inheritance系统失败: {e}")
192
- return False
193
-
194
- async def _load_plugins(self) -> bool:
195
- """
196
- 加载插件
197
-
198
- Returns:
199
- bool: 加载是否成功
200
- """
201
- try:
202
- # 读取现有配置
203
- config = self._load_config()
204
-
205
- # 添加我们的插件配置
206
- cross_cli_plugin = {
207
- "name": "CrossCLIAdapterPlugin",
208
- "class": "CrossCLIAdapterPlugin",
209
- "enabled": True,
210
- "priority": 85,
211
- "base_class": "BaseQwenCodePlugin",
212
- "handlers": [
213
- "on_prompt_received",
214
- "on_code_generated",
215
- "on_error_occurred"
216
- ],
217
- "config": {
218
- "cross_cli_enabled": True,
219
- "supported_clis": ["claude", "gemini", "iflow", "qoder", "codebuddy", "codex"],
220
- "auto_detect": True
221
- }
222
- }
223
-
224
- # 检查是否已存在
225
- existing_plugins = config.get('plugins', [])
226
- plugin_exists = any(
227
- plugin['name'] == cross_cli_plugin['name']
228
- for plugin in existing_plugins
229
- )
230
-
231
- if not plugin_exists:
232
- existing_plugins.append(cross_cli_plugin)
233
- config['plugins'] = existing_plugins
234
-
235
- # 保存配置
236
- await self._save_config(config)
237
- logger.info(f"加载Plugin: {cross_cli_plugin['name']}")
238
- else:
239
- logger.info("Plugin已存在,跳过加载")
240
-
241
- return True
242
-
243
- except Exception as e:
244
- logger.error(f"加载Plugin失败: {e}")
245
- return False
246
-
247
- def _load_config(self) -> Dict[str, Any]:
248
- """
249
- 加载配置
250
-
251
- Returns:
252
- Dict[str, Any]: 配置
253
- """
254
- if os.path.exists(self.config_file):
255
- try:
256
- import yaml
257
- with open(self.config_file, 'r', encoding='utf-8') as f:
258
- return yaml.safe_load(f) or {}
259
- except Exception as e:
260
- logger.warning(f"加载配置失败,使用默认配置: {e}")
261
-
262
- # 返回默认配置
263
- return {
264
- "version": "1.0",
265
- "plugins": []
266
- }
267
-
268
- async def _save_config(self, config: Dict[str, Any]) -> bool:
269
- """
270
- 保存配置
271
-
272
- Args:
273
- config: 配置
274
-
275
- Returns:
276
- bool: 保存是否成功
277
- """
278
- try:
279
- import yaml
280
- os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
281
-
282
- with open(self.config_file, 'w', encoding='utf-8') as f:
283
- yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
284
-
285
- logger.info(f"保存配置到: {self.config_file}")
286
- return True
287
-
288
- except Exception as e:
289
- logger.error(f"保存配置失败: {e}")
290
- return False
291
-
292
- async def _ensure_config_directory(self) -> bool:
293
- """
294
- 确保配置目录存在
295
-
296
- Returns:
297
- bool: 创建是否成功
298
- """
299
- try:
300
- config_dir = os.path.expanduser("~/.config/qwencode")
301
- os.makedirs(config_dir, exist_ok=True)
302
-
303
- # 创建适配器配置目录
304
- adapter_dir = os.path.join(config_dir, "adapters")
305
- os.makedirs(adapter_dir, exist_ok=True)
306
-
307
- logger.info(f"配置目录已准备: {config_dir}")
308
- return True
309
-
310
- except Exception as e:
311
- logger.error(f"创建配置目录失败: {e}")
312
- return False
313
-
314
- def _check_qwencode_environment(self) -> bool:
315
- """
316
- 检查QwenCode CLI环境
317
-
318
- Returns:
319
- bool: 环境是否可用
320
- """
321
- # 这里应该检查QwenCode CLI是否可用
322
- # 暂时返回True,实际实现中需要检查CLI命令和配置
323
- return True
324
-
325
- async def on_prompt_received(self, context: PluginContext) -> Optional[str]:
326
- """
327
- 接收到提示时的Plugin处理函数
328
-
329
- 这是核心Plugin,用于检测和执行跨CLI调用。
330
-
331
- Args:
332
- context: Plugin上下文
333
-
334
- Returns:
335
- Optional[str]: 处理结果,如果返回None则让QwenCode继续正常处理
336
- """
337
- try:
338
- self.plugin_calls_count += 1
339
- user_input = context.prompt
340
-
341
- # 记录请求
342
- request_record = {
343
- 'plugin_type': 'on_prompt_received',
344
- 'prompt': user_input,
345
- 'metadata': context.metadata,
346
- 'timestamp': datetime.now().isoformat()
347
- }
348
- self.processed_requests.append(request_record)
349
-
350
- # 1. 检测是否为跨CLI调用意图
351
- intent = self.parser.parse_intent(user_input, "qwencode")
352
-
353
- if not intent.is_cross_cli:
354
- # 不是跨CLI调用,让QwenCode继续处理
355
- return None
356
-
357
- # 2. 避免自我调用
358
- if intent.target_cli == self.cli_name:
359
- # 目标是QwenCode自己,让QwenCode处理
360
- return None
361
-
362
- # 3. 执行跨CLI调用
363
- result = await self._execute_cross_cli_call(
364
- intent.target_cli,
365
- intent.task,
366
- context
367
- )
368
-
369
- if result:
370
- self.cross_cli_calls_count += 1
371
- return result
372
-
373
- return None
374
-
375
- except Exception as e:
376
- logger.error(f"接收到提示Plugin处理失败: {e}")
377
- self.record_error()
378
- return None
379
-
380
- def _parse_cross_cli_intent(self, user_input: str) -> tuple:
381
- """
382
- 解析跨CLI调用意图(测试兼容方法)
383
-
384
- Args:
385
- user_input: 用户输入
386
-
387
- Returns:
388
- tuple: (target_cli, task)
389
- """
390
- try:
391
- intent = self.parser.parse_intent(user_input, "qwencode")
392
- if intent.is_cross_cli:
393
- return intent.target_cli, intent.task
394
- return None, None
395
- except Exception:
396
- return None, None
397
-
398
- async def execute_cross_cli_call(self, target_cli: str, task: str, context: PluginContext) -> str:
399
- """
400
- 执行跨CLI调用(测试兼容方法)
401
-
402
- Args:
403
- target_cli: 目标CLI工具
404
- task: 要执行的任务
405
- context: Plugin上下文
406
-
407
- Returns:
408
- str: 执行结果
409
- """
410
- result = await self._execute_cross_cli_call(target_cli, task, context)
411
- if result:
412
- return result
413
- return f"跨CLI调用失败: {target_cli} -> {task}"
414
-
415
- async def on_before_execute(self, context: PluginContext) -> Optional[str]:
416
- """
417
- 执行前Plugin处理函数
418
-
419
- Args:
420
- context: Plugin上下文
421
-
422
- Returns:
423
- Optional[str]: 处理结果
424
- """
425
- # 可以在这里预处理执行前的逻辑
426
- return None
427
-
428
- async def on_after_execute(self, context: PluginContext) -> Optional[str]:
429
- """
430
- 执行后Plugin处理函数
431
-
432
- Args:
433
- context: Plugin上下文
434
-
435
- Returns:
436
- Optional[str]: 处理结果
437
- """
438
- # 可以在这里后处理执行后的结果
439
- return None
440
-
441
- async def on_code_generated(self, context: PluginContext) -> Optional[str]:
442
- """
443
- 代码生成Plugin处理函数
444
-
445
- Args:
446
- context: Plugin上下文
447
-
448
- Returns:
449
- Optional[str]: 处理结果
450
- """
451
- # 可以在这里处理代码生成相关的跨CLI功能
452
- return None
453
-
454
- async def on_error_occurred(self, context: PluginContext) -> Optional[str]:
455
- """
456
- 错误发生Plugin处理函数
457
-
458
- Args:
459
- context: Plugin上下文
460
-
461
- Returns:
462
- Optional[str]: 处理结果
463
- """
464
- # 可以在这里处理错误恢复逻辑
465
- return None
466
-
467
- async def on_file_created(self, context: PluginContext) -> Optional[str]:
468
- """
469
- 文件创建Plugin处理函数
470
-
471
- Args:
472
- context: Plugin上下文
473
-
474
- Returns:
475
- Optional[str]: 处理结果
476
- """
477
- return None
478
-
479
- async def on_before_save(self, context: PluginContext) -> Optional[str]:
480
- """
481
- 保存前Plugin处理函数
482
-
483
- Args:
484
- context: Plugin上下文
485
-
486
- Returns:
487
- Optional[str]: 处理结果
488
- """
489
- return None
490
-
491
- async def _execute_cross_cli_call(
492
- self,
493
- target_cli: str,
494
- task: str,
495
- context: PluginContext
496
- ) -> Optional[str]:
497
- """
498
- 执行跨CLI调用
499
-
500
- Args:
501
- target_cli: 目标CLI工具
502
- task: 要执行的任务
503
- context: Plugin上下文
504
-
505
- Returns:
506
- Optional[str]: 执行结果
507
- """
508
- try:
509
- logger.info(f"执行跨CLI调用: {target_cli} -> {task}")
510
-
511
- # 获取目标CLI适配器
512
- target_adapter = self.get_adapter(target_cli)
513
-
514
- if not target_adapter:
515
- logger.warning(f"目标CLI适配器不可用: {target_cli}")
516
- return self._format_error_result(
517
- target_cli,
518
- f"目标CLI工具 '{target_cli}' 不可用或未安装"
519
- )
520
-
521
- if not target_adapter.is_available():
522
- logger.warning(f"目标CLI工具不可用: {target_cli}")
523
- return self._format_error_result(
524
- target_cli,
525
- f"目标CLI工具 '{target_cli}' 当前不可用"
526
- )
527
-
528
- # 构建执行上下文
529
- execution_context = {
530
- 'source_cli': self.cli_name,
531
- 'target_cli': target_cli,
532
- 'original_task': task,
533
- 'plugin_context': context.__dict__,
534
- 'timestamp': datetime.now().isoformat()
535
- }
536
-
537
- # 执行任务
538
- result = await target_adapter.execute_task(task, execution_context)
539
-
540
- # 记录成功的跨CLI调用
541
- self.processed_requests.append({
542
- 'type': 'cross_cli_execution',
543
- 'target_cli': target_cli,
544
- 'task': task,
545
- 'success': True,
546
- 'result_length': len(result),
547
- 'timestamp': datetime.now().isoformat()
548
- })
549
-
550
- # 格式化结果
551
- formatted_result = self._format_result(target_cli, result)
552
-
553
- logger.info(f"跨CLI调用成功: {target_cli}")
554
- return formatted_result
555
-
556
- except Exception as e:
557
- logger.error(f"跨CLI调用失败: {target_cli}, {e}")
558
- self.record_error()
559
-
560
- self.processed_requests.append({
561
- 'type': 'cross_cli_execution',
562
- 'target_cli': target_cli,
563
- 'task': task,
564
- 'success': False,
565
- 'error': str(e),
566
- 'timestamp': datetime.now().isoformat()
567
- })
568
-
569
- return self._format_error_result(target_cli, str(e))
570
-
571
- def _format_result(
572
- self,
573
- target_cli: str,
574
- result: str
575
- ) -> str:
576
- """
577
- 格式化成功的跨CLI调用结果
578
-
579
- Args:
580
- target_cli: 目标CLI工具
581
- result: 执行结果
582
-
583
- Returns:
584
- str: 格式化的结果
585
- """
586
- return f"""## 🔗 跨CLI调用结果
587
-
588
- **源工具**: QwenCode CLI
589
- **目标工具**: {target_cli.upper()}
590
- **执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
591
-
592
- ---
593
-
594
- {result}
595
-
596
- ---
597
-
598
- *此结果由跨CLI集成系统通过QwenCode Class Inheritance提供*"""
599
-
600
- def _format_error_result(
601
- self,
602
- target_cli: str,
603
- error_message: str
604
- ) -> str:
605
- """
606
- 格式化错误的跨CLI调用结果
607
-
608
- Args:
609
- target_cli: 目标CLI工具
610
- error_message: 错误信息
611
-
612
- Returns:
613
- str: 格式化的错误结果
614
- """
615
- return f"""## ❌ 跨CLI调用失败
616
-
617
- **源工具**: QwenCode CLI
618
- **目标工具**: {target_cli.upper()}
619
- **错误信息**: {error_message}
620
- **失败时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
621
-
622
- 请检查目标CLI工具是否正确安装和配置。
623
-
624
- ---
625
-
626
- *此错误由跨CLI集成系统报告*"""
627
-
628
- def is_available(self) -> bool:
629
- """
630
- 检查适配器是否可用
631
-
632
- Returns:
633
- bool: 是否可用
634
- """
635
- return self.plugins_loaded and self._check_qwencode_environment()
636
-
637
- async def health_check(self) -> Dict[str, Any]:
638
- """
639
- 健康检查
640
-
641
- Returns:
642
- Dict[str, Any]: 健康状态
643
- """
644
- base_health = await super().health_check()
645
-
646
- qwencode_health = {
647
- 'plugins_loaded': self.plugins_loaded,
648
- 'plugin_calls_count': self.plugin_calls_count,
649
- 'cross_cli_calls_count': self.cross_cli_calls_count,
650
- 'processed_requests_count': len(self.processed_requests),
651
- 'config_file': self.config_file,
652
- 'config_exists': os.path.exists(self.config_file),
653
- 'plugin_handlers': list(self.plugin_handlers.keys()),
654
- 'inheritance_setup_complete': self.inheritance_setup_complete,
655
- 'base_class_loaded': self.base_class is not None
656
- }
657
-
658
- # 检查环境
659
- try:
660
- qwencode_health['qwencode_environment'] = self._check_qwencode_environment()
661
- except Exception as e:
662
- qwencode_health['qwencode_environment_error'] = str(e)
663
-
664
- # 合并基础健康信息
665
- base_health.update(qwencode_health)
666
- return base_health
667
-
668
- def get_statistics(self) -> Dict[str, Any]:
669
- """
670
- 获取适配器统计信息
671
-
672
- Returns:
673
- Dict[str, Any]: 统计信息
674
- """
675
- base_stats = super().get_statistics()
676
-
677
- qwencode_stats = {
678
- 'plugins_loaded': self.plugins_loaded,
679
- 'plugin_calls_count': self.plugin_calls_count,
680
- 'cross_cli_calls_count': self.cross_cli_calls_count,
681
- 'success_rate': self._calculate_success_rate(),
682
- 'last_activity': self._get_last_activity(),
683
- 'supported_plugins': list(self.plugin_handlers.keys())
684
- }
685
-
686
- base_stats.update(qwencode_stats)
687
- return base_stats
688
-
689
- def _calculate_success_rate(self) -> float:
690
- """
691
- 计算成功率
692
-
693
- Returns:
694
- float: 成功率 (0.0 - 1.0)
695
- """
696
- total_cross_cli = self.cross_cli_calls_count
697
-
698
- if total_cross_cli == 0:
699
- return 1.0
700
-
701
- successful_calls = sum(
702
- 1 for req in self.processed_requests
703
- if req.get('type') == 'cross_cli_execution' and req.get('success')
704
- )
705
-
706
- return successful_calls / total_cross_cli
707
-
708
- def _get_last_activity(self) -> Optional[str]:
709
- """
710
- 获取最后活动时间
711
-
712
- Returns:
713
- Optional[str]: 最后活动时间戳
714
- """
715
- if not self.processed_requests:
716
- return None
717
-
718
- return max(req['timestamp'] for req in self.processed_requests)
719
-
720
- async def execute_task(self, task: str, context: Dict[str, Any]) -> str:
721
- """
722
- 执行跨CLI任务 - QwenCode适配器的具体实现
723
-
724
- Args:
725
- task: 要执行的任务描述
726
- context: 执行上下文信息
727
-
728
- Returns:
729
- str: 任务执行结果
730
- """
731
- try:
732
- # QwenCode适配器的任务执行主要是通过Plugin系统
733
- # 这里创建一个模拟的Plugin上下文来处理任务
734
- plugin_context = PluginContext(
735
- prompt=task,
736
- metadata=context.get('metadata', {})
737
- )
738
-
739
- # 检查是否为跨CLI调用
740
- intent = self.parser.parse_intent(task, "qwencode")
741
- if intent.is_cross_cli and intent.target_cli != self.cli_name:
742
- # 执行跨CLI调用
743
- result = await self._execute_cross_cli_call(
744
- intent.target_cli,
745
- intent.task,
746
- plugin_context
747
- )
748
- return result or f"QwenCode Inheritance适配器处理了任务: {task}"
749
- else:
750
- # 本地QwenCode任务处理
751
- return f"QwenCode Inheritance适配器本地处理: {task}"
752
-
753
- except Exception as e:
754
- logger.error(f"执行任务失败: {task}, 错误: {e}")
755
- self.record_error()
756
- return f"任务执行失败: {str(e)}"
757
-
758
- async def cleanup(self) -> bool:
759
- """
760
- 清理适配器资源
761
-
762
- Returns:
763
- bool: 清理是否成功
764
- """
765
- try:
766
- # 清理统计信息
767
- self.processed_requests.clear()
768
-
769
- # 清理插件(如果需要)
770
- # 这里可以实现插件卸载逻辑
771
-
772
- logger.info("QwenCode Class Inheritance适配器清理完成")
773
- return True
774
-
775
- except Exception as e:
776
- logger.error(f"清理QwenCode Class Inheritance适配器失败: {e}")
777
- return False
778
-
779
-
780
- # 创建全局适配器实例
781
- _global_adapter: Optional[QwenCodeInheritanceAdapter] = None
782
-
783
-
784
- def get_qwencode_inheritance_adapter() -> QwenCodeInheritanceAdapter:
785
- """
786
- 获取QwenCode Inheritance适配器实例
787
-
788
- Returns:
789
- QwenCodeInheritanceAdapter: 适配器实例
790
- """
791
- global _global_adapter
792
- if _global_adapter is None:
793
- _global_adapter = QwenCodeInheritanceAdapter()
794
- # 异步初始化需要在调用时进行
795
- return _global_adapter
796
-
797
-
798
- # 便捷函数
799
- async def initialize_qwencode_adapter() -> bool:
800
- """
801
- 初始化QwenCode Inheritance适配器
802
-
803
- Returns:
804
- bool: 初始化是否成功
805
- """
806
- adapter = get_qwencode_inheritance_adapter()
807
- return await adapter.initialize()
808
-
809
-
810
- def is_qwencode_adapter_available() -> bool:
811
- """
812
- 检查QwenCode Inheritance适配器是否可用
813
-
814
- Returns:
815
- bool: 是否可用
816
- """
817
- adapter = get_qwencode_inheritance_adapter()
818
- return adapter.is_available()