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,841 +0,0 @@
1
- """
2
- Claude CLI Skills-based Hook Adapter
3
- 基于Claude技能系统的钩子适配器,实现技能与钩子的冗余跨CLI协同
4
- """
5
-
6
- import asyncio
7
- import json
8
- import logging
9
- import os
10
- import subprocess
11
- import sys
12
- import time
13
- from typing import Dict, List, Optional, Any, Callable
14
- from pathlib import Path
15
- from dataclasses import dataclass
16
- from enum import Enum
17
-
18
- from ..base_adapter import BaseAdapter
19
- from ..core.unified_intent_parser import UnifiedIntentParser
20
- from ...core.config_manager import ConfigManager
21
-
22
- logger = logging.getLogger(__name__)
23
-
24
-
25
- class HookType(Enum):
26
- """Claude Hook类型"""
27
- USER_PROMPT_SUBMIT = "user_prompt_submit"
28
- TOOL_USE_PRE = "tool_use_pre"
29
- TOOL_USE_POST = "tool_use_post"
30
- RESPONSE_GENERATED = "response_generated"
31
- SESSION_START = "session_start"
32
- SESSION_END = "session_end"
33
- SKILL_REGISTER = "skill_register"
34
- CROSS_CLI_REQUEST = "cross_cli_request"
35
- ERROR_HANDLING = "error_handling"
36
-
37
-
38
- @dataclass
39
- class HookEvent:
40
- """Hook事件数据"""
41
- hook_type: HookType
42
- prompt: str = ""
43
- session_id: str = ""
44
- user_id: str = ""
45
- metadata: Dict[str, Any] = None
46
- timestamp: float = None
47
-
48
- def __post_init__(self):
49
- if self.metadata is None:
50
- self.metadata = {}
51
- if self.timestamp is None:
52
- self.timestamp = time.time()
53
-
54
-
55
- @dataclass
56
- class SkillConfig:
57
- """技能配置"""
58
- name: str
59
- description: str = ""
60
- capabilities: List[str] = None
61
- priority: int = 50
62
- protocols: List[str] = None
63
- hooks: List[HookType] = None
64
- enabled: bool = True
65
- category: str = ""
66
- author: str = ""
67
-
68
- def __post_init__(self):
69
- if self.capabilities is None:
70
- self.capabilities = []
71
- if self.protocols is None:
72
- self.protocols = ["chinese", "english"]
73
- if self.hooks is None:
74
- self.hooks = []
75
-
76
-
77
- class ClaudeSkill:
78
- """Claude技能基类"""
79
- def __init__(self, config: SkillConfig):
80
- self.config = config
81
- self.registered_hooks = {}
82
- self.active = False
83
- self.usage_count = 0
84
- self.success_count = 0
85
-
86
- def register_hook(self, hook_type: HookType, handler: Callable):
87
- """注册钩子处理器"""
88
- self.registered_hooks[hook_type] = handler
89
- logger.debug(f"Claude技能 {self.config.name} 注册钩子: {hook_type.value}")
90
-
91
- async def trigger_hook(self, event: HookEvent) -> Any:
92
- """触发钩子"""
93
- handler = self.registered_hooks.get(event.hook_type)
94
- if handler:
95
- try:
96
- self.usage_count += 1
97
- result = await handler(event)
98
- if result:
99
- self.success_count += 1
100
- return result
101
- except Exception as e:
102
- logger.error(f"Claude技能钩子处理失败 {event.hook_type.value}: {e}")
103
- return None
104
- return None
105
-
106
- async def activate(self):
107
- """激活技能"""
108
- self.active = True
109
- logger.info(f"Claude技能 {self.config.name} 已激活")
110
-
111
- async def deactivate(self):
112
- """停用技能"""
113
- self.active = False
114
- logger.info(f"Claude技能 {self.config.name} 已停用")
115
-
116
- def get_stats(self) -> Dict[str, Any]:
117
- """获取技能统计"""
118
- return {
119
- "usage_count": self.usage_count,
120
- "success_count": self.success_count,
121
- "success_rate": self.success_count / max(self.usage_count, 1),
122
- "active": self.active
123
- }
124
-
125
-
126
- class ClaudeSkillsHookAdapter(BaseAdapter):
127
- """
128
- Claude CLI Skills-based Hook Adapter
129
- 基于Claude技能和钩子的冗余跨CLI协同适配器
130
- """
131
-
132
- def __init__(self, config_manager: ConfigManager):
133
- super().__init__("claude", config_manager)
134
- self.parser = UnifiedIntentParser()
135
-
136
- # Claude特定配置
137
- self.hooks_config_file = os.path.expanduser("~/.config/claude/hooks.json")
138
- self.claude_config_dir = os.path.expanduser("~/.config/claude")
139
- self.adapter_config_dir = os.path.join(self.claude_config_dir, "adapters")
140
-
141
- # 技能系统
142
- self.skills = {}
143
- self.skill_configs = {}
144
- self.hook_registry = {hook_type: [] for hook_type in HookType}
145
-
146
- # 钩子系统
147
- self.hooks_enabled = True
148
- self.hook_fallback_enabled = True
149
- self.hooks_registered = False
150
-
151
- # 跨CLI协同
152
- self.cross_cli_skills = {}
153
- self.active_collaborations = {}
154
-
155
- # 会话管理
156
- self.session_hooks = {}
157
-
158
- # 统计信息
159
- self.hook_calls_count = 0
160
- self.cross_cli_calls_count = 0
161
- self.processed_requests = []
162
-
163
- # 配置
164
- self._load_config()
165
- self._setup_builtin_skills()
166
- self._setup_hook_system()
167
-
168
- logger.info("Claude Skills-Hook Adapter 初始化完成")
169
-
170
- def _load_config(self):
171
- """加载配置"""
172
- try:
173
- config_path = Path(__file__).parent / "config.json"
174
- if config_path.exists():
175
- with open(config_path, 'r', encoding='utf-8') as f:
176
- config = json.load(f)
177
-
178
- self.hooks_enabled = config.get("hooks", {}).get("enabled", True)
179
- self.hook_fallback_enabled = config.get("hooks", {}).get("fallback_enabled", True)
180
-
181
- # 加载技能配置
182
- for skill_config in config.get("skills", []):
183
- skill_obj = SkillConfig(**skill_config)
184
- self.skill_configs[skill_obj.name] = skill_obj
185
-
186
- except Exception as e:
187
- logger.warning(f"加载Claude配置失败: {e}")
188
-
189
- def _setup_builtin_skills(self):
190
- """设置内置技能"""
191
- # 技能1: Claude跨CLI协调器
192
- cross_cli_config = SkillConfig(
193
- name="claude_cross_cli_coordinator",
194
- description="Claude跨CLI协调器 - 通过技能和钩子系统协调不同AI CLI工具",
195
- capabilities=["跨CLI调用协调", "智能路由", "Claude原生集成", "冗余处理"],
196
- priority=100,
197
- hooks=[HookType.USER_PROMPT_SUBMIT, HookType.CROSS_CLI_REQUEST, HookType.TOOL_USE_PRE],
198
- protocols=["chinese", "english"],
199
- category="coordination",
200
- author="Smart CLI Router"
201
- )
202
-
203
- cross_cli_skill = ClaudeSkill(cross_cli_config)
204
-
205
- # 注册钩子处理器
206
- async def handle_user_prompt_submit(event: HookEvent):
207
- """处理用户提示提交钩子 - Claude核心Hook"""
208
- return await self._handle_claude_user_prompt_submit(event)
209
-
210
- async def handle_cross_cli_request(event: HookEvent):
211
- """处理跨CLI请求钩子"""
212
- return await self._handle_cross_cli_request(event)
213
-
214
- async def handle_tool_use_pre(event: HookEvent):
215
- """处理工具使用前钩子 - 冗余检测"""
216
- return await self._redundant_cross_cli_detection(event)
217
-
218
- cross_cli_skill.register_hook(HookType.USER_PROMPT_SUBMIT, handle_user_prompt_submit)
219
- cross_cli_skill.register_hook(HookType.CROSS_CLI_REQUEST, handle_cross_cli_request)
220
- cross_cli_skill.register_hook(HookType.TOOL_USE_PRE, handle_tool_use_pre)
221
-
222
- self.skills[cross_cli_config.name] = cross_cli_skill
223
- self.cross_cli_skills[cross_cli_config.name] = cross_cli_skill
224
-
225
- # 技能2: Claude智能代理
226
- intelligent_agent_config = SkillConfig(
227
- name="claude_intelligent_agent",
228
- description="Claude智能代理 - 基于Claude能力的智能任务代理",
229
- capabilities=["智能分析", "任务理解", "结果优化", "上下文管理"],
230
- priority=90,
231
- hooks=[HookType.RESPONSE_GENERATED, HookType.TOOL_USE_POST],
232
- protocols=["chinese", "english"],
233
- category="intelligence",
234
- author="Smart CLI Router"
235
- )
236
-
237
- intelligent_agent_skill = ClaudeSkill(intelligent_agent_config)
238
-
239
- async def handle_response_generated(event: HookEvent):
240
- """处理响应生成钩子 - 智能优化"""
241
- return await self._intelligent_response_optimization(event)
242
-
243
- async def handle_tool_use_post(event: HookEvent):
244
- """处理工具使用后钩子 - 结果验证"""
245
- return await self._intelligent_result_verification(event)
246
-
247
- intelligent_agent_skill.register_hook(HookType.RESPONSE_GENERATED, handle_response_generated)
248
- intelligent_agent_skill.register_hook(HookType.TOOL_USE_POST, handle_tool_use_post)
249
-
250
- self.skills[intelligent_agent_config.name] = intelligent_agent_skill
251
-
252
- # 技能3: Claude错误恢复专家
253
- error_recovery_config = SkillConfig(
254
- name="claude_error_recovery_expert",
255
- description="Claude错误恢复专家 - 利用Claude智能处理跨CLI调用失败",
256
- capabilities=["错误智能分析", "自动恢复", "智能回退", "学习优化"],
257
- priority=95,
258
- hooks=[HookType.ERROR_HANDLING, HookType.SESSION_END],
259
- protocols=["chinese", "english"],
260
- category="recovery",
261
- author="Smart CLI Router"
262
- )
263
-
264
- error_recovery_skill = ClaudeSkill(error_recovery_config)
265
-
266
- async def handle_error(event: HookEvent):
267
- """处理错误钩子 - 智能错误分析"""
268
- return await self._intelligent_error_analysis(event)
269
-
270
- async def handle_session_end(event: HookEvent):
271
- """处理会话结束钩子 - 学习总结"""
272
- return await self._learning_summary(event)
273
-
274
- error_recovery_skill.register_hook(HookType.ERROR_HANDLING, handle_error)
275
- error_recovery_skill.register_hook(HookType.SESSION_END, handle_session_end)
276
-
277
- self.skills[error_recovery_config.name] = error_recovery_skill
278
-
279
- # 技能4: Claude会话管理器
280
- session_manager_config = SkillConfig(
281
- name="claude_session_manager",
282
- description="Claude会话管理器 - 管理Claude跨CLI会话生命周期",
283
- capabilities=["会话智能管理", "状态跟踪", "上下文保持", "个性化配置"],
284
- priority=85,
285
- hooks=[HookType.SESSION_START, HookType.SESSION_END, HookType.SKILL_REGISTER],
286
- protocols=["chinese", "english"],
287
- category="session",
288
- author="Smart CLI Router"
289
- )
290
-
291
- session_manager_skill = ClaudeSkill(session_manager_config)
292
-
293
- async def handle_session_start(event: HookEvent):
294
- """处理会话开始钩子"""
295
- return await self._setup_claude_session(event)
296
-
297
- async def handle_skill_register(event: HookEvent):
298
- """处理技能注册钩子"""
299
- return await self._register_claude_skill(event)
300
-
301
- session_manager_skill.register_hook(HookType.SESSION_START, handle_session_start)
302
- session_manager_skill.register_hook(HookType.SESSION_END, handle_session_end) # 复用会话结束处理
303
- session_manager_skill.register_hook(HookType.SKILL_REGISTER, handle_skill_register)
304
-
305
- self.skills[session_manager_config.name] = session_manager_skill
306
-
307
- # 激活所有技能
308
- for skill in self.skills.values():
309
- asyncio.create_task(skill.activate())
310
-
311
- def _setup_hook_system(self):
312
- """设置钩子系统"""
313
- # 注册钩子到全局钩子注册表
314
- for skill in self.skills.values():
315
- for hook_type in skill.config.hooks:
316
- if hook_type in skill.registered_hooks:
317
- self.hook_registry[hook_type].append(skill)
318
-
319
- logger.info(f"Claude钩子系统设置完成,注册钩子: {list(self.hook_registry.keys())}")
320
-
321
- async def trigger_hooks(self, hook_type: HookType, event: HookEvent) -> List[Any]:
322
- """触发所有相关钩子"""
323
- if not self.hooks_enabled:
324
- return []
325
-
326
- results = []
327
- skills = self.hook_registry.get(hook_type, [])
328
-
329
- # 按优先级排序
330
- skills.sort(key=lambda s: s.config.priority, reverse=True)
331
-
332
- for skill in skills:
333
- if skill.active:
334
- try:
335
- result = await skill.trigger_hook(event)
336
- if result is not None:
337
- results.append(result)
338
- except Exception as e:
339
- logger.error(f"Claude技能 {skill.config.name} 钩子执行失败: {e}")
340
-
341
- return results
342
-
343
- async def _handle_claude_user_prompt_submit(self, event: HookEvent) -> Optional[str]:
344
- """处理Claude用户提示提交钩子 - 核心Hook"""
345
- try:
346
- self.hook_calls_count += 1
347
- user_input = event.prompt
348
-
349
- # 记录请求
350
- request_record = {
351
- 'hook_type': 'user_prompt_submit',
352
- 'prompt': user_input,
353
- 'metadata': event.metadata,
354
- 'timestamp': time.time()
355
- }
356
- self.processed_requests.append(request_record)
357
-
358
- # 1. Claude原生跨CLI检测
359
- intent = self.parser.parse_intent(user_input, "claude")
360
-
361
- if not intent.is_cross_cli:
362
- # 不是跨CLI调用,让Claude继续处理
363
- return None
364
-
365
- # 2. 避免自我调用
366
- if intent.target_cli == self.cli_name:
367
- return None
368
-
369
- # 3. 技能处理方式
370
- result1 = await self._execute_cross_cli_via_skills(intent, event)
371
-
372
- # 4. 钩子处理方式(冗余)
373
- result2 = await self._execute_cross_cli_via_hooks(intent, event)
374
-
375
- # 5. 选择最佳结果
376
- best_result = self._select_best_result(result1, result2)
377
-
378
- if best_result:
379
- self.cross_cli_calls_count += 1
380
-
381
- # 记录成功的跨CLI调用
382
- self.processed_requests.append({
383
- 'type': 'cross_cli_execution',
384
- 'target_cli': intent.target_cli,
385
- 'task': intent.task,
386
- 'success': True,
387
- 'result_length': len(best_result),
388
- 'timestamp': time.time()
389
- })
390
-
391
- return best_result
392
-
393
- return None
394
-
395
- except Exception as e:
396
- logger.error(f"处理Claude用户提示钩子失败: {e}")
397
- return None
398
-
399
- async def _handle_cross_cli_request(self, event: HookEvent) -> Optional[str]:
400
- """处理跨CLI请求钩子"""
401
- try:
402
- command = event.prompt
403
- user_prompt = command
404
-
405
- logger.info(f"跨CLI请求钩子触发: {user_prompt}")
406
-
407
- # 解析跨CLI意图
408
- intent = self.parser.parse_intent(user_prompt, "claude")
409
-
410
- if intent.is_cross_cli and intent.target_cli != self.cli_name:
411
- # Claude技能处理方式
412
- result1 = await self._execute_cross_cli_via_skills(intent, event)
413
-
414
- # Claude钩子处理方式(冗余)
415
- result2 = await self._execute_cross_cli_via_hooks(intent, event)
416
-
417
- # 选择最佳结果
418
- return self._select_best_result(result1, result2)
419
-
420
- except Exception as e:
421
- logger.error(f"处理跨CLI请求钩子失败: {e}")
422
- return None
423
-
424
- async def _execute_cross_cli_via_skills(self, intent, event: HookEvent) -> Optional[str]:
425
- """通过Claude技能系统执行跨CLI调用"""
426
- try:
427
- # 触发跨CLI技能
428
- cross_cli_event = HookEvent(
429
- hook_type=HookType.CROSS_CLI_REQUEST,
430
- prompt=f"call {intent.target_cli} for {intent.task}",
431
- session_id=event.session_id,
432
- metadata={"intent": intent.__dict__}
433
- )
434
-
435
- results = await self.trigger_hooks(HookType.CROSS_CLI_REQUEST, cross_cli_event)
436
-
437
- if results:
438
- return results[0] # 返回第一个有效结果
439
-
440
- except Exception as e:
441
- logger.error(f"Claude技能系统跨CLI调用失败: {e}")
442
-
443
- return None
444
-
445
- async def _execute_cross_cli_via_hooks(self, intent, event: HookEvent) -> Optional[str]:
446
- """通过Claude钩子系统执行跨CLI调用"""
447
- try:
448
- # 创建临时钩子事件
449
- hook_event = HookEvent(
450
- hook_type=HookType.TOOL_USE_PRE,
451
- prompt=f"use {intent.target_cli} to {intent.task}",
452
- session_id=event.session_id,
453
- metadata={"original_event": event.__dict__}
454
- )
455
-
456
- results = await self.trigger_hooks(HookType.TOOL_USE_PRE, hook_event)
457
-
458
- if results:
459
- return results[0]
460
-
461
- except Exception as e:
462
- logger.error(f"Claude钩子系统跨CLI调用失败: {e}")
463
-
464
- return None
465
-
466
- def _select_best_result(self, result1: Optional[str], result2: Optional[str]) -> Optional[str]:
467
- """选择最佳结果 - Claude智能选择"""
468
- # Claude特定的结果选择逻辑
469
- if result1 and result2:
470
- # 优先选择包含Claude智能分析的结果
471
- claude_indicators = ["Claude分析", "智能", "优化", "[OK]", "成功"]
472
- if any(indicator in result1 for indicator in claude_indicators):
473
- return result1
474
- elif any(indicator in result2 for indicator in claude_indicators):
475
- return result2
476
-
477
- # 选择长度更长且质量更高的结果
478
- return result1 if len(result1) > len(result2) else result2
479
- elif result1:
480
- return result1
481
- elif result2:
482
- return result2
483
- return None
484
-
485
- async def _redundant_cross_cli_detection(self, event: HookEvent) -> Optional[str]:
486
- """冗余跨CLI检测 - Claude增强版"""
487
- try:
488
- prompt = event.prompt
489
-
490
- # Claude增强的检测方式
491
- detection_methods = [
492
- self._detect_via_claude_patterns(prompt),
493
- self._detect_via_semantic_analysis(prompt),
494
- self._detect_via_context_clues(event)
495
- ]
496
-
497
- # 如果任一方法检测到跨CLI意图
498
- for detected_intent in detection_methods:
499
- if detected_intent:
500
- logger.info(f"Claude冗余检测到跨CLI意图: {detected_intent}")
501
-
502
- # 创建跨CLI事件
503
- cross_cli_event = HookEvent(
504
- hook_type=HookType.CROSS_CLI_REQUEST,
505
- prompt=detected_intent["command"],
506
- session_id=event.session_id,
507
- metadata={"detection_method": detected_intent["method"]}
508
- )
509
-
510
- results = await self.trigger_hooks(HookType.CROSS_CLI_REQUEST, cross_cli_event)
511
- if results:
512
- return results[0]
513
-
514
- except Exception as e:
515
- logger.error(f"Claude冗余跨CLI检测失败: {e}")
516
-
517
- return None
518
-
519
- def _detect_via_claude_patterns(self, prompt: str) -> Optional[Dict]:
520
- """通过Claude增强模式检测"""
521
- patterns = [
522
- r"请用(.*)帮我(.*)",
523
- r"call (.*) to (.*)",
524
- r"让(.*)处理(.*)",
525
- r"use (.*) for (.*)",
526
- r"通过(.*)执行(.*)",
527
- r"借助(.*)完成(.*)"
528
- ]
529
-
530
- import re
531
- for pattern in patterns:
532
- match = re.search(pattern, prompt, re.IGNORECASE)
533
- if match:
534
- cli, task = match.groups()
535
- supported_clis = ["claude", "gemini", "qwencode", "iflow", "qoder", "codebuddy", "codex"]
536
- if cli.lower() in supported_clis:
537
- return {
538
- "command": prompt,
539
- "target_cli": cli.lower(),
540
- "task": task,
541
- "method": "claude_pattern_detection"
542
- }
543
- return None
544
-
545
- def _detect_via_semantic_analysis(self, prompt: str) -> Optional[Dict]:
546
- """通过语义分析检测"""
547
- # 模拟Claude的语义分析能力
548
- semantic_keywords = {
549
- "claude": ["claude", "克劳德", "anthropic"],
550
- "gemini": ["gemini", "杰米尼", "google"],
551
- "qwencode": ["qwencode", "qwen", "通义"],
552
- "iflow": ["iflow", "ai流程"],
553
- "qoder": ["qoder", "代码助手"],
554
- "codebuddy": ["codebuddy", "代码伙伴"],
555
- "codex": ["codex", "openai", "gpt"]
556
- }
557
-
558
- prompt_lower = prompt.lower()
559
- for cli, keywords in semantic_keywords.items():
560
- for keyword in keywords:
561
- if keyword in prompt_lower:
562
- # 提取任务内容
563
- task = prompt.replace(keyword, "").strip()
564
- return {
565
- "command": prompt,
566
- "target_cli": cli,
567
- "task": task,
568
- "method": "semantic_analysis"
569
- }
570
- return None
571
-
572
- def _detect_via_context_clues(self, event: HookEvent) -> Optional[Dict]:
573
- """通过上下文线索检测"""
574
- # 分析事件元数据中的线索
575
- metadata = event.metadata or {}
576
-
577
- # 检查是否包含工具调用信息
578
- if "tool_calls" in metadata:
579
- for tool_call in metadata["tool_calls"]:
580
- if "function" in tool_call:
581
- function_name = tool_call["function"].get("name", "")
582
- # 检查是否为跨CLI工具调用
583
- for cli in ["gemini", "qwencode", "iflow", "qoder", "codebuddy", "codex"]:
584
- if cli in function_name.lower():
585
- return {
586
- "command": event.prompt,
587
- "target_cli": cli,
588
- "task": tool_call["function"].get("arguments", ""),
589
- "method": "context_analysis"
590
- }
591
-
592
- return None
593
-
594
- async def _intelligent_response_optimization(self, event: HookEvent) -> Optional[str]:
595
- """智能响应优化"""
596
- try:
597
- response = event.metadata.get("response", "")
598
- if response and self._is_cross_cli_result(response):
599
- # Claude智能优化结果
600
- optimized_response = self._optimize_response_with_claude(response)
601
- return f"🧠 Claude智能优化:\n{optimized_response}"
602
- except Exception as e:
603
- logger.error(f"智能响应优化失败: {e}")
604
- return None
605
-
606
- async def _intelligent_result_verification(self, event: HookEvent) -> Optional[str]:
607
- """智能结果验证"""
608
- try:
609
- result = event.metadata.get("result", "")
610
- if result and self._is_cross_cli_result(result):
611
- # Claude智能验证结果
612
- verification_result = self._verify_result_with_claude(result)
613
- if verification_result:
614
- return f"[OK] Claude智能验证: {verification_result}"
615
- except Exception as e:
616
- logger.error(f"智能结果验证失败: {e}")
617
- return None
618
-
619
- def _optimize_response_with_claude(self, response: str) -> str:
620
- """使用Claude智能优化响应"""
621
- # 模拟Claude的智能优化
622
- optimizations = []
623
-
624
- # 1. 结构优化
625
- if not response.startswith("#") and not response.startswith("##"):
626
- optimizations.append("添加结构化标题")
627
-
628
- # 2. 内容优化
629
- if len(response) < 50:
630
- optimizations.append("内容过于简短,建议扩充")
631
-
632
- # 3. 格式优化
633
- if "**" not in response and "*" not in response:
634
- optimizations.append("建议添加格式化标记")
635
-
636
- if optimizations:
637
- return f"已优化: {', '.join(optimizations)}"
638
- else:
639
- return "响应质量良好,无需优化"
640
-
641
- def _verify_result_with_claude(self, result: str) -> str:
642
- """使用Claude智能验证结果"""
643
- # 模拟Claude的智能验证
644
- quality_score = 0
645
- issues = []
646
-
647
- # 检查完整性
648
- if len(result) < 10:
649
- issues.append("结果过短")
650
- else:
651
- quality_score += 25
652
-
653
- # 检查错误标记
654
- error_indicators = ["错误", "error", "失败", "failed", "❌"]
655
- if any(indicator in result.lower() for indicator in error_indicators):
656
- issues.append("包含错误指示")
657
- else:
658
- quality_score += 25
659
-
660
- # 检查成功标记
661
- success_indicators = ["成功", "success", "完成", "completed", "[OK]"]
662
- if any(indicator in result.lower() for indicator in success_indicators):
663
- quality_score += 25
664
-
665
- # 检查结构
666
- if any(marker in result for marker in ["#", "##", "**", "*"]):
667
- quality_score += 25
668
-
669
- if quality_score >= 75:
670
- return f"质量优秀 (评分: {quality_score}/100)"
671
- elif quality_score >= 50:
672
- return f"质量良好 (评分: {quality_score}/100)"
673
- else:
674
- return f"质量待改进 (评分: {quality_score}/100), 问题: {', '.join(issues)}"
675
-
676
- async def _intelligent_error_analysis(self, event: HookEvent) -> Optional[str]:
677
- """智能错误分析"""
678
- try:
679
- error_info = event.metadata.get("error", "")
680
- if error_info:
681
- # Claude智能分析错误
682
- analysis = self._analyze_error_with_claude(error_info)
683
- recovery_suggestion = self._suggest_recovery_with_claude(error_info)
684
- return f"🧠 Claude错误分析:\n{analysis}\n💡 恢复建议: {recovery_suggestion}"
685
- except Exception as e:
686
- logger.error(f"智能错误分析失败: {e}")
687
- return None
688
-
689
- def _analyze_error_with_claude(self, error_info: str) -> str:
690
- """使用Claude智能分析错误"""
691
- # 模拟Claude的错误分析
692
- error_patterns = {
693
- "网络": ["network", "connection", "timeout"],
694
- "权限": ["permission", "access", "unauthorized"],
695
- "配置": ["config", "not found", "missing"],
696
- "执行": ["failed", "error", "exception"]
697
- }
698
-
699
- error_lower = error_info.lower()
700
- for category, keywords in error_patterns.items():
701
- if any(keyword in error_lower for keyword in keywords):
702
- return f"错误类型: {category}类错误"
703
-
704
- return "错误类型: 未知类型错误"
705
-
706
- def _suggest_recovery_with_claude(self, error_info: str) -> str:
707
- """使用Claude智能建议恢复方案"""
708
- # 模拟Claude的恢复建议
709
- if "network" in error_info.lower():
710
- return "检查网络连接,稍后重试"
711
- elif "permission" in error_info.lower():
712
- return "检查权限设置,确保有足够的访问权限"
713
- elif "not found" in error_info.lower():
714
- return "检查目标CLI工具是否正确安装和配置"
715
- else:
716
- return "尝试使用其他CLI工具或简化任务要求"
717
-
718
- async def _learning_summary(self, event: HookEvent) -> Optional[str]:
719
- """学习总结"""
720
- try:
721
- session_id = event.session_id
722
- if session_id in self.session_hooks:
723
- session_info = self.session_hooks[session_id]
724
-
725
- # Claude智能学习总结
726
- summary = self._generate_learning_summary(session_info)
727
- return f"🧠 Claude学习总结:\n{summary}"
728
- except Exception as e:
729
- logger.error(f"学习总结失败: {e}")
730
- return None
731
-
732
- def _generate_learning_summary(self, session_info: Dict) -> str:
733
- """生成学习总结"""
734
- total_hooks = session_info.get("hooks_triggered", 0)
735
- cross_cli_calls = session_info.get("cross_cli_calls", 0)
736
- success_rate = (cross_cli_calls / max(total_hooks, 1)) * 100
737
-
738
- summary_points = []
739
- if success_rate > 80:
740
- summary_points.append("跨CLI协作表现优秀")
741
- elif success_rate > 60:
742
- summary_points.append("跨CLI协作表现良好")
743
- else:
744
- summary_points.append("跨CLI协作有待改进")
745
-
746
- if cross_cli_calls > 5:
747
- summary_points.append("频繁使用跨CLI功能")
748
-
749
- return "; ".join(summary_points)
750
-
751
- async def _setup_claude_session(self, event: HookEvent) -> Optional[str]:
752
- """设置Claude会话"""
753
- session_id = event.session_id or f"claude_session_{int(time.time())}"
754
- self.session_hooks[session_id] = {
755
- "start_time": time.time(),
756
- "hooks_triggered": 0,
757
- "cross_cli_calls": 0,
758
- "claude_features_used": []
759
- }
760
- return f"Claude会话 {session_id} 设置完成"
761
-
762
- async def _register_claude_skill(self, event: HookEvent) -> Optional[str]:
763
- """注册Claude技能"""
764
- try:
765
- skill_info = event.metadata.get("skill_info")
766
- if skill_info:
767
- # 处理Claude技能注册
768
- return f"Claude技能 {skill_info.get('name')} 注册完成"
769
- except Exception as e:
770
- logger.error(f"注册Claude技能失败: {e}")
771
- return None
772
-
773
- def _is_cross_cli_result(self, result: str) -> bool:
774
- """判断是否为跨CLI结果"""
775
- indicators = ["调用", "called", "执行", "executed", "via", "通过", "跨CLI", "cross-cli"]
776
- return any(indicator in result for indicator in indicators)
777
-
778
- async def register_external_skill(self, skill_name: str, skill_config: Dict[str, Any]) -> bool:
779
- """注册外部Claude技能"""
780
- try:
781
- config = SkillConfig(name=skill_name, **skill_config)
782
- skill = ClaudeSkill(config)
783
-
784
- # 激活技能
785
- await skill.activate()
786
-
787
- # 注册到系统
788
- self.skills[skill_name] = skill
789
-
790
- # 更新钩子注册表
791
- for hook_type in config.hooks:
792
- self.hook_registry[hook_type].append(skill)
793
-
794
- # 触发技能注册钩子
795
- event = HookEvent(
796
- hook_type=HookType.SKILL_REGISTER,
797
- metadata={"skill_info": {"name": skill_name, "config": skill_config}}
798
- )
799
-
800
- await self.trigger_hooks(HookType.SKILL_REGISTER, event)
801
-
802
- logger.info(f"外部Claude技能 {skill_name} 注册成功")
803
- return True
804
-
805
- except Exception as e:
806
- logger.error(f"注册外部Claude技能失败: {e}")
807
- return False
808
-
809
- def get_system_status(self) -> Dict[str, Any]:
810
- """获取系统状态"""
811
- active_skills = [name for name, skill in self.skills.items() if skill.active]
812
- skill_stats = {name: skill.get_stats() for name, skill in self.skills.items()}
813
- hook_counts = {hook_type.value: len(skills) for hook_type, skills in self.hook_registry.items()}
814
-
815
- return {
816
- "adapter_type": "Claude Skills-Hook",
817
- "active_skills": active_skills,
818
- "total_skills": len(self.skills),
819
- "skill_stats": skill_stats,
820
- "hook_counts": hook_counts,
821
- "hooks_enabled": self.hooks_enabled,
822
- "hooks_registered": self.hooks_registered,
823
- "hook_calls_count": self.hook_calls_count,
824
- "cross_cli_calls_count": self.cross_cli_calls_count,
825
- "active_sessions": len(self.session_hooks),
826
- "claude_features": ["智能分析", "语义检测", "上下文理解", "学习优化"]
827
- }
828
-
829
- async def cleanup(self):
830
- """清理资源"""
831
- # 停用所有技能
832
- for skill in self.skills.values():
833
- await skill.deactivate()
834
-
835
- # 清理会话钩子
836
- self.session_hooks.clear()
837
-
838
- # 清理请求记录
839
- self.processed_requests.clear()
840
-
841
- logger.info("Claude Skills-Hook Adapter 资源清理完成")