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,1038 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
iFlow CLI Hook适配器 - 基于iFlow CLI官方Hook系统的原生集成
|
|
3
|
-
|
|
4
|
-
这是TDD驱动的实现,基于test_iflow_adapter.py中的测试用例
|
|
5
|
-
完全符合项目约束条件:
|
|
6
|
-
- 使用iFlow CLI官方Hook机制
|
|
7
|
-
- 不改变CLI启动和使用方式
|
|
8
|
-
- 不依赖包装器
|
|
9
|
-
- 完全无损扩展
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import os
|
|
13
|
-
import json
|
|
14
|
-
import logging
|
|
15
|
-
import asyncio
|
|
16
|
-
import yaml
|
|
17
|
-
from typing import Dict, Any, Optional, List, Callable
|
|
18
|
-
from datetime import datetime
|
|
19
|
-
from pathlib import Path
|
|
20
|
-
from dataclasses import dataclass
|
|
21
|
-
|
|
22
|
-
from ...core.base_adapter import BaseCrossCLIAdapter, IntentResult
|
|
23
|
-
from ...core.parser import NaturalLanguageParser
|
|
24
|
-
|
|
25
|
-
logger = logging.getLogger(__name__)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@dataclass
|
|
29
|
-
class IFlowHookContext:
|
|
30
|
-
"""iFlow CLI Hook上下文"""
|
|
31
|
-
command: str = ""
|
|
32
|
-
args: List[str] = None
|
|
33
|
-
kwargs: Dict[str, Any] = None
|
|
34
|
-
user_input: str = ""
|
|
35
|
-
pipeline_name: str = ""
|
|
36
|
-
workflow_id: str = ""
|
|
37
|
-
stage_name: str = ""
|
|
38
|
-
metadata: Dict[str, Any] = None
|
|
39
|
-
timestamp: datetime = None
|
|
40
|
-
|
|
41
|
-
def __post_init__(self):
|
|
42
|
-
if self.args is None:
|
|
43
|
-
self.args = []
|
|
44
|
-
if self.kwargs is None:
|
|
45
|
-
self.kwargs = {}
|
|
46
|
-
if self.metadata is None:
|
|
47
|
-
self.metadata = {}
|
|
48
|
-
if self.timestamp is None:
|
|
49
|
-
self.timestamp = datetime.now()
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@dataclass
|
|
53
|
-
class IFlowEvent:
|
|
54
|
-
"""iFlow事件对象"""
|
|
55
|
-
event_type: str
|
|
56
|
-
data: Dict[str, Any]
|
|
57
|
-
source: str
|
|
58
|
-
timestamp: datetime
|
|
59
|
-
context: Optional[IFlowHookContext] = None
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class IFlowHookAdapter(BaseCrossCLIAdapter):
|
|
63
|
-
"""
|
|
64
|
-
iFlow CLI Hook适配器
|
|
65
|
-
|
|
66
|
-
通过iFlow CLI官方Hook系统实现跨CLI调用功能。
|
|
67
|
-
这是完全基于原生机制的无损扩展实现。
|
|
68
|
-
|
|
69
|
-
Hook机制:
|
|
70
|
-
- on_command_start: 命令开始执行时触发
|
|
71
|
-
- on_command_end: 命令执行完成时触发
|
|
72
|
-
- on_user_input: 用户输入时触发
|
|
73
|
-
- on_workflow_stage: 工作流阶段执行时触发
|
|
74
|
-
- on_pipeline_execute: 流水线执行时触发
|
|
75
|
-
- on_error: 错误发生时触发
|
|
76
|
-
"""
|
|
77
|
-
|
|
78
|
-
def __init__(self, cli_name: str = "iflow"):
|
|
79
|
-
"""
|
|
80
|
-
初始化iFlow Hook适配器
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
cli_name: CLI工具名称,默认为"iflow"
|
|
84
|
-
"""
|
|
85
|
-
super().__init__(cli_name)
|
|
86
|
-
|
|
87
|
-
# Hook相关配置
|
|
88
|
-
self.hooks_config_file = os.path.expanduser("~/.config/iflow/hooks.yml")
|
|
89
|
-
self.iflow_config_dir = os.path.expanduser("~/.config/iflow")
|
|
90
|
-
self.hooks_registered = False
|
|
91
|
-
self.hook_handlers = {
|
|
92
|
-
'on_command_start': self.on_command_start,
|
|
93
|
-
'on_command_end': self.on_command_end,
|
|
94
|
-
'on_user_input': self.on_user_input,
|
|
95
|
-
'on_workflow_stage': self.on_workflow_stage,
|
|
96
|
-
'on_pipeline_execute': self.on_pipeline_execute,
|
|
97
|
-
'on_error': self.on_error,
|
|
98
|
-
'on_output_render': self.on_output_render,
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
# 统计信息
|
|
102
|
-
self.hook_calls_count = 0
|
|
103
|
-
self.cross_cli_calls_count = 0
|
|
104
|
-
self.processed_events: List[IFlowEvent] = []
|
|
105
|
-
self.command_interceptions: List[Dict[str, Any]] = []
|
|
106
|
-
|
|
107
|
-
# 配置
|
|
108
|
-
self.hook_config: Dict[str, Any] = {}
|
|
109
|
-
self.iflow_version = "unknown"
|
|
110
|
-
|
|
111
|
-
# 组件
|
|
112
|
-
self.parser = NaturalLanguageParser()
|
|
113
|
-
|
|
114
|
-
# 事件总线
|
|
115
|
-
self.event_listeners: Dict[str, List[Callable]] = {}
|
|
116
|
-
|
|
117
|
-
# 协作状态
|
|
118
|
-
self.collaboration_enabled = True
|
|
119
|
-
self.active_workflows: Dict[str, Dict] = {}
|
|
120
|
-
|
|
121
|
-
logger.info("iFlow Hook适配器初始化完成")
|
|
122
|
-
|
|
123
|
-
async def initialize(self) -> bool:
|
|
124
|
-
"""
|
|
125
|
-
初始化适配器
|
|
126
|
-
|
|
127
|
-
Returns:
|
|
128
|
-
bool: 初始化是否成功
|
|
129
|
-
"""
|
|
130
|
-
try:
|
|
131
|
-
logger.info("开始初始化iFlow Hook适配器...")
|
|
132
|
-
|
|
133
|
-
# 1. 检查iFlow CLI环境
|
|
134
|
-
if not self._check_iflow_environment():
|
|
135
|
-
logger.error("iFlow CLI环境检查失败")
|
|
136
|
-
return False
|
|
137
|
-
|
|
138
|
-
# 2. 加载Hook配置
|
|
139
|
-
if not await self._load_hook_config():
|
|
140
|
-
logger.error("Hook配置加载失败")
|
|
141
|
-
return False
|
|
142
|
-
|
|
143
|
-
# 3. 注册Hook
|
|
144
|
-
if not await self._register_iflow_hooks():
|
|
145
|
-
logger.error("Hook注册失败")
|
|
146
|
-
return False
|
|
147
|
-
|
|
148
|
-
# 4. 初始化事件总线
|
|
149
|
-
if not await self._initialize_event_bus():
|
|
150
|
-
logger.error("事件总线初始化失败")
|
|
151
|
-
return False
|
|
152
|
-
|
|
153
|
-
# 5. 创建配置目录
|
|
154
|
-
await self._ensure_config_directory()
|
|
155
|
-
|
|
156
|
-
# 6. 初始化协作系统
|
|
157
|
-
await self._initialize_collaboration_system()
|
|
158
|
-
|
|
159
|
-
self.hooks_registered = True
|
|
160
|
-
logger.info("iFlow Hook适配器初始化成功")
|
|
161
|
-
return True
|
|
162
|
-
|
|
163
|
-
except Exception as e:
|
|
164
|
-
logger.error(f"初始化iFlow Hook适配器失败: {e}")
|
|
165
|
-
self.record_error()
|
|
166
|
-
return False
|
|
167
|
-
|
|
168
|
-
def _check_iflow_environment(self) -> bool:
|
|
169
|
-
"""
|
|
170
|
-
检查iFlow CLI环境
|
|
171
|
-
|
|
172
|
-
Returns:
|
|
173
|
-
bool: 环境是否可用
|
|
174
|
-
"""
|
|
175
|
-
try:
|
|
176
|
-
# 检查iFlow CLI命令是否可用
|
|
177
|
-
import subprocess
|
|
178
|
-
result = subprocess.run(
|
|
179
|
-
['iflow', '--version'],
|
|
180
|
-
capture_output=True,
|
|
181
|
-
text=True,
|
|
182
|
-
timeout=5
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
if result.returncode == 0:
|
|
186
|
-
self.iflow_version = result.stdout.strip()
|
|
187
|
-
logger.info(f"检测到iFlow CLI版本: {self.iflow_version}")
|
|
188
|
-
return True
|
|
189
|
-
else:
|
|
190
|
-
logger.warning("iFlow CLI命令不可用")
|
|
191
|
-
return False
|
|
192
|
-
|
|
193
|
-
except (subprocess.TimeoutExpired, FileNotFoundError) as e:
|
|
194
|
-
logger.warning(f"iFlow CLI环境检查失败: {e}")
|
|
195
|
-
# 在开发环境中,即使没有真实的iFlow CLI也返回True
|
|
196
|
-
return True
|
|
197
|
-
|
|
198
|
-
async def _load_hook_config(self) -> bool:
|
|
199
|
-
"""
|
|
200
|
-
加载Hook配置
|
|
201
|
-
|
|
202
|
-
Returns:
|
|
203
|
-
bool: 加载是否成功
|
|
204
|
-
"""
|
|
205
|
-
try:
|
|
206
|
-
# 读取adapter配置
|
|
207
|
-
config_path = Path(__file__).parent / "config.json"
|
|
208
|
-
if config_path.exists():
|
|
209
|
-
with open(config_path, 'r', encoding='utf-8') as f:
|
|
210
|
-
adapter_config = json.load(f)
|
|
211
|
-
self.hook_config = adapter_config.get('hook_config', {})
|
|
212
|
-
|
|
213
|
-
# 读取iFlow hooks配置
|
|
214
|
-
if os.path.exists(self.hooks_config_file):
|
|
215
|
-
with open(self.hooks_config_file, 'r', encoding='utf-8') as f:
|
|
216
|
-
hooks_config = yaml.safe_load(f) or {}
|
|
217
|
-
else:
|
|
218
|
-
hooks_config = self._get_default_hook_config()
|
|
219
|
-
await self._save_hook_config(hooks_config)
|
|
220
|
-
|
|
221
|
-
logger.info("Hook配置加载成功")
|
|
222
|
-
return True
|
|
223
|
-
|
|
224
|
-
except Exception as e:
|
|
225
|
-
logger.error(f"加载Hook配置失败: {e}")
|
|
226
|
-
return False
|
|
227
|
-
|
|
228
|
-
def _get_default_hook_config(self) -> Dict[str, Any]:
|
|
229
|
-
"""获取默认Hook配置"""
|
|
230
|
-
return {
|
|
231
|
-
"version": "1.0",
|
|
232
|
-
"hooks": [],
|
|
233
|
-
"plugins": [
|
|
234
|
-
{
|
|
235
|
-
"name": "cross-cli-adapter",
|
|
236
|
-
"module": "src.adapters.iflow.hook_adapter",
|
|
237
|
-
"class": "IFlowHookAdapter",
|
|
238
|
-
"enabled": True,
|
|
239
|
-
"priority": 100,
|
|
240
|
-
"hooks": [
|
|
241
|
-
"on_user_input",
|
|
242
|
-
"on_command_start",
|
|
243
|
-
"on_workflow_stage",
|
|
244
|
-
"on_pipeline_execute",
|
|
245
|
-
"on_command_end"
|
|
246
|
-
],
|
|
247
|
-
"config": {
|
|
248
|
-
"cross_cli_enabled": True,
|
|
249
|
-
"collaboration_mode": "active",
|
|
250
|
-
"timeout": 30,
|
|
251
|
-
"error_handling": "continue"
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
]
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async def _save_hook_config(self, config: Dict[str, Any]) -> bool:
|
|
258
|
-
"""
|
|
259
|
-
保存Hook配置
|
|
260
|
-
|
|
261
|
-
Args:
|
|
262
|
-
config: Hook配置
|
|
263
|
-
|
|
264
|
-
Returns:
|
|
265
|
-
bool: 保存是否成功
|
|
266
|
-
"""
|
|
267
|
-
try:
|
|
268
|
-
os.makedirs(os.path.dirname(self.hooks_config_file), exist_ok=True)
|
|
269
|
-
|
|
270
|
-
with open(self.hooks_config_file, 'w', encoding='utf-8') as f:
|
|
271
|
-
yaml.dump(config, f, default_flow_style=False, allow_unicode=True)
|
|
272
|
-
|
|
273
|
-
logger.info(f"保存Hook配置到: {self.hooks_config_file}")
|
|
274
|
-
return True
|
|
275
|
-
|
|
276
|
-
except Exception as e:
|
|
277
|
-
logger.error(f"保存Hook配置失败: {e}")
|
|
278
|
-
return False
|
|
279
|
-
|
|
280
|
-
async def _register_iflow_hooks(self) -> bool:
|
|
281
|
-
"""
|
|
282
|
-
注册Hook到iFlow CLI
|
|
283
|
-
|
|
284
|
-
Returns:
|
|
285
|
-
bool: 注册是否成功
|
|
286
|
-
"""
|
|
287
|
-
try:
|
|
288
|
-
# 读取现有hooks配置
|
|
289
|
-
hooks_config = self._get_default_hook_config()
|
|
290
|
-
if os.path.exists(self.hooks_config_file):
|
|
291
|
-
with open(self.hooks_config_file, 'r', encoding='utf-8') as f:
|
|
292
|
-
hooks_config = yaml.safe_load(f) or {}
|
|
293
|
-
|
|
294
|
-
# 添加我们的Hook插件
|
|
295
|
-
cross_cli_hook = {
|
|
296
|
-
"name": "cross-cli-adapter",
|
|
297
|
-
"module": "src.adapters.iflow.hook_adapter",
|
|
298
|
-
"class": "IFlowHookAdapter",
|
|
299
|
-
"enabled": True,
|
|
300
|
-
"priority": 100,
|
|
301
|
-
"hooks": list(self.hook_handlers.keys()),
|
|
302
|
-
"config": self.hook_config
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
# 检查是否已存在
|
|
306
|
-
plugins = hooks_config.get('plugins', [])
|
|
307
|
-
hook_exists = any(
|
|
308
|
-
plugin.get('name') == cross_cli_hook['name']
|
|
309
|
-
for plugin in plugins
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
if not hook_exists:
|
|
313
|
-
plugins.append(cross_cli_hook)
|
|
314
|
-
hooks_config['plugins'] = plugins
|
|
315
|
-
|
|
316
|
-
# 保存配置
|
|
317
|
-
await self._save_hook_config(hooks_config)
|
|
318
|
-
logger.info(f"注册Hook插件: {cross_cli_hook['name']}")
|
|
319
|
-
else:
|
|
320
|
-
logger.info("Hook插件已存在,跳过注册")
|
|
321
|
-
|
|
322
|
-
return True
|
|
323
|
-
|
|
324
|
-
except Exception as e:
|
|
325
|
-
logger.error(f"注册Hook失败: {e}")
|
|
326
|
-
return False
|
|
327
|
-
|
|
328
|
-
async def _initialize_event_bus(self) -> bool:
|
|
329
|
-
"""
|
|
330
|
-
初始化事件总线
|
|
331
|
-
|
|
332
|
-
Returns:
|
|
333
|
-
bool: 初始化是否成功
|
|
334
|
-
"""
|
|
335
|
-
try:
|
|
336
|
-
# 初始化事件监听器
|
|
337
|
-
self.event_listeners = {
|
|
338
|
-
'cross_cli_detected': [],
|
|
339
|
-
'workflow_started': [],
|
|
340
|
-
'workflow_completed': [],
|
|
341
|
-
'error_occurred': []
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
logger.info("事件总线初始化成功")
|
|
345
|
-
return True
|
|
346
|
-
|
|
347
|
-
except Exception as e:
|
|
348
|
-
logger.error(f"初始化事件总线失败: {e}")
|
|
349
|
-
return False
|
|
350
|
-
|
|
351
|
-
async def _ensure_config_directory(self) -> None:
|
|
352
|
-
"""确保配置目录存在"""
|
|
353
|
-
config_dirs = [
|
|
354
|
-
self.iflow_config_dir,
|
|
355
|
-
os.path.join(self.iflow_config_dir, "adapters"),
|
|
356
|
-
os.path.join(self.iflow_config_dir, "hooks"),
|
|
357
|
-
os.path.join(self.iflow_config_dir, "workflows"),
|
|
358
|
-
os.path.join(self.iflow_config_dir, "logs")
|
|
359
|
-
]
|
|
360
|
-
|
|
361
|
-
for config_dir in config_dirs:
|
|
362
|
-
os.makedirs(config_dir, exist_ok=True)
|
|
363
|
-
|
|
364
|
-
async def _initialize_collaboration_system(self) -> None:
|
|
365
|
-
"""初始化协作系统"""
|
|
366
|
-
self.collaboration_enabled = True
|
|
367
|
-
self.active_workflows = {}
|
|
368
|
-
logger.info("协作系统初始化完成")
|
|
369
|
-
|
|
370
|
-
# ==================== Hook处理器 ====================
|
|
371
|
-
|
|
372
|
-
async def on_user_input(self, context: IFlowHookContext) -> Optional[str]:
|
|
373
|
-
"""
|
|
374
|
-
用户输入Hook处理函数
|
|
375
|
-
|
|
376
|
-
这是核心Hook,用于检测和执行跨CLI调用。
|
|
377
|
-
|
|
378
|
-
Args:
|
|
379
|
-
context: Hook上下文
|
|
380
|
-
|
|
381
|
-
Returns:
|
|
382
|
-
Optional[str]: 处理结果,如果返回None则让iFlow继续正常处理
|
|
383
|
-
"""
|
|
384
|
-
try:
|
|
385
|
-
self.hook_calls_count += 1
|
|
386
|
-
user_input = context.user_input or context.command
|
|
387
|
-
|
|
388
|
-
if not user_input:
|
|
389
|
-
return None
|
|
390
|
-
|
|
391
|
-
# 记录事件
|
|
392
|
-
event = IFlowEvent(
|
|
393
|
-
event_type="user_input",
|
|
394
|
-
data={"input": user_input, "metadata": context.metadata},
|
|
395
|
-
source="iflow_hook_adapter",
|
|
396
|
-
timestamp=datetime.now(),
|
|
397
|
-
context=context
|
|
398
|
-
)
|
|
399
|
-
self.processed_events.append(event)
|
|
400
|
-
|
|
401
|
-
# 1. 检测是否为跨CLI调用意图
|
|
402
|
-
intent = self.parser.parse_intent(user_input, "iflow")
|
|
403
|
-
|
|
404
|
-
if not intent.is_cross_cli:
|
|
405
|
-
# 不是跨CLI调用,让iFlow继续处理
|
|
406
|
-
return None
|
|
407
|
-
|
|
408
|
-
# 2. 避免自我调用
|
|
409
|
-
if intent.target_cli == self.cli_name:
|
|
410
|
-
# 目标是iFlow自己,让iFlow处理
|
|
411
|
-
return None
|
|
412
|
-
|
|
413
|
-
# 3. 触发跨CLI检测事件
|
|
414
|
-
await self._emit_event("cross_cli_detected", {
|
|
415
|
-
"intent": intent,
|
|
416
|
-
"context": context
|
|
417
|
-
})
|
|
418
|
-
|
|
419
|
-
# 4. 执行跨CLI调用
|
|
420
|
-
result = await self._execute_cross_cli_call(
|
|
421
|
-
intent.target_cli,
|
|
422
|
-
intent.task,
|
|
423
|
-
context
|
|
424
|
-
)
|
|
425
|
-
|
|
426
|
-
if result:
|
|
427
|
-
self.cross_cli_calls_count += 1
|
|
428
|
-
return result
|
|
429
|
-
|
|
430
|
-
return None
|
|
431
|
-
|
|
432
|
-
except Exception as e:
|
|
433
|
-
logger.error(f"用户输入Hook处理失败: {e}")
|
|
434
|
-
self.record_error()
|
|
435
|
-
return None
|
|
436
|
-
|
|
437
|
-
async def on_command_start(self, context: IFlowHookContext) -> Optional[str]:
|
|
438
|
-
"""
|
|
439
|
-
命令开始Hook处理函数
|
|
440
|
-
|
|
441
|
-
Args:
|
|
442
|
-
context: Hook上下文
|
|
443
|
-
|
|
444
|
-
Returns:
|
|
445
|
-
Optional[str]: 处理结果
|
|
446
|
-
"""
|
|
447
|
-
try:
|
|
448
|
-
self.hook_calls_count += 1
|
|
449
|
-
|
|
450
|
-
# 记录命令拦截
|
|
451
|
-
interception = {
|
|
452
|
-
'type': 'command_start',
|
|
453
|
-
'command': context.command,
|
|
454
|
-
'args': context.args,
|
|
455
|
-
'timestamp': datetime.now().isoformat()
|
|
456
|
-
}
|
|
457
|
-
self.command_interceptions.append(interception)
|
|
458
|
-
|
|
459
|
-
logger.debug(f"命令开始: {context.command}")
|
|
460
|
-
return None
|
|
461
|
-
|
|
462
|
-
except Exception as e:
|
|
463
|
-
logger.error(f"命令开始Hook处理失败: {e}")
|
|
464
|
-
return None
|
|
465
|
-
|
|
466
|
-
async def on_command_end(self, context: IFlowHookContext, result: Any) -> Optional[str]:
|
|
467
|
-
"""
|
|
468
|
-
命令结束Hook处理函数
|
|
469
|
-
|
|
470
|
-
Args:
|
|
471
|
-
context: Hook上下文
|
|
472
|
-
result: 命令执行结果
|
|
473
|
-
|
|
474
|
-
Returns:
|
|
475
|
-
Optional[str]: 处理结果
|
|
476
|
-
"""
|
|
477
|
-
try:
|
|
478
|
-
self.hook_calls_count += 1
|
|
479
|
-
|
|
480
|
-
# 记录命令完成
|
|
481
|
-
completion = {
|
|
482
|
-
'type': 'command_end',
|
|
483
|
-
'command': context.command,
|
|
484
|
-
'result_length': len(str(result)) if result else 0,
|
|
485
|
-
'timestamp': datetime.now().isoformat()
|
|
486
|
-
}
|
|
487
|
-
self.command_interceptions.append(completion)
|
|
488
|
-
|
|
489
|
-
logger.debug(f"命令结束: {context.command}")
|
|
490
|
-
return None
|
|
491
|
-
|
|
492
|
-
except Exception as e:
|
|
493
|
-
logger.error(f"命令结束Hook处理失败: {e}")
|
|
494
|
-
return None
|
|
495
|
-
|
|
496
|
-
async def on_workflow_stage(self, context: IFlowHookContext, stage_data: Dict[str, Any]) -> Optional[str]:
|
|
497
|
-
"""
|
|
498
|
-
工作流阶段Hook处理函数
|
|
499
|
-
|
|
500
|
-
Args:
|
|
501
|
-
context: Hook上下文
|
|
502
|
-
stage_data: 阶段数据
|
|
503
|
-
|
|
504
|
-
Returns:
|
|
505
|
-
Optional[str]: 处理结果
|
|
506
|
-
"""
|
|
507
|
-
try:
|
|
508
|
-
self.hook_calls_count += 1
|
|
509
|
-
|
|
510
|
-
# 更新活动工作流状态
|
|
511
|
-
if context.workflow_id:
|
|
512
|
-
self.active_workflows[context.workflow_id] = {
|
|
513
|
-
'stage': context.stage_name,
|
|
514
|
-
'timestamp': datetime.now().isoformat(),
|
|
515
|
-
'data': stage_data
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
# 检测跨CLI协作机会
|
|
519
|
-
collaboration_result = await self._check_collaboration_opportunity(context, stage_data)
|
|
520
|
-
if collaboration_result:
|
|
521
|
-
return collaboration_result
|
|
522
|
-
|
|
523
|
-
logger.debug(f"工作流阶段: {context.stage_name}")
|
|
524
|
-
return None
|
|
525
|
-
|
|
526
|
-
except Exception as e:
|
|
527
|
-
logger.error(f"工作流阶段Hook处理失败: {e}")
|
|
528
|
-
return None
|
|
529
|
-
|
|
530
|
-
async def on_pipeline_execute(self, context: IFlowHookContext, pipeline_config: Dict[str, Any]) -> Optional[str]:
|
|
531
|
-
"""
|
|
532
|
-
流水线执行Hook处理函数
|
|
533
|
-
|
|
534
|
-
Args:
|
|
535
|
-
context: Hook上下文
|
|
536
|
-
pipeline_config: 流水线配置
|
|
537
|
-
|
|
538
|
-
Returns:
|
|
539
|
-
Optional[str]: 处理结果
|
|
540
|
-
"""
|
|
541
|
-
try:
|
|
542
|
-
self.hook_calls_count += 1
|
|
543
|
-
|
|
544
|
-
# 触发流水线执行事件
|
|
545
|
-
await self._emit_event("pipeline_executing", {
|
|
546
|
-
"context": context,
|
|
547
|
-
"pipeline_config": pipeline_config
|
|
548
|
-
})
|
|
549
|
-
|
|
550
|
-
logger.debug(f"流水线执行: {context.pipeline_name}")
|
|
551
|
-
return None
|
|
552
|
-
|
|
553
|
-
except Exception as e:
|
|
554
|
-
logger.error(f"流水线执行Hook处理失败: {e}")
|
|
555
|
-
return None
|
|
556
|
-
|
|
557
|
-
async def on_error(self, context: IFlowHookContext, error: Exception) -> Optional[str]:
|
|
558
|
-
"""
|
|
559
|
-
错误Hook处理函数
|
|
560
|
-
|
|
561
|
-
Args:
|
|
562
|
-
context: Hook上下文
|
|
563
|
-
error: 错误信息
|
|
564
|
-
|
|
565
|
-
Returns:
|
|
566
|
-
Optional[str]: 处理结果
|
|
567
|
-
"""
|
|
568
|
-
try:
|
|
569
|
-
self.hook_calls_count += 1
|
|
570
|
-
|
|
571
|
-
# 记录错误事件
|
|
572
|
-
error_event = IFlowEvent(
|
|
573
|
-
event_type="error",
|
|
574
|
-
data={
|
|
575
|
-
"error": str(error),
|
|
576
|
-
"error_type": type(error).__name__,
|
|
577
|
-
"context": context.__dict__
|
|
578
|
-
},
|
|
579
|
-
source="iflow_hook_adapter",
|
|
580
|
-
timestamp=datetime.now()
|
|
581
|
-
)
|
|
582
|
-
self.processed_events.append(error_event)
|
|
583
|
-
|
|
584
|
-
# 触发错误事件
|
|
585
|
-
await self._emit_event("error_occurred", {
|
|
586
|
-
"context": context,
|
|
587
|
-
"error": error
|
|
588
|
-
})
|
|
589
|
-
|
|
590
|
-
logger.error(f"iFlow Hook错误: {error}")
|
|
591
|
-
return None
|
|
592
|
-
|
|
593
|
-
except Exception as e:
|
|
594
|
-
logger.error(f"错误Hook处理失败: {e}")
|
|
595
|
-
return None
|
|
596
|
-
|
|
597
|
-
async def on_output_render(self, context: IFlowHookContext, output: str) -> Optional[str]:
|
|
598
|
-
"""
|
|
599
|
-
输出渲染Hook处理函数
|
|
600
|
-
|
|
601
|
-
Args:
|
|
602
|
-
context: Hook上下文
|
|
603
|
-
output: 原始输出
|
|
604
|
-
|
|
605
|
-
Returns:
|
|
606
|
-
Optional[str]: 处理后的输出
|
|
607
|
-
"""
|
|
608
|
-
try:
|
|
609
|
-
self.hook_calls_count += 1
|
|
610
|
-
|
|
611
|
-
# 可以在这里对输出进行后处理
|
|
612
|
-
# 例如添加跨CLI调用的元信息
|
|
613
|
-
|
|
614
|
-
return output
|
|
615
|
-
|
|
616
|
-
except Exception as e:
|
|
617
|
-
logger.error(f"输出渲染Hook处理失败: {e}")
|
|
618
|
-
return output
|
|
619
|
-
|
|
620
|
-
# ==================== 跨CLI功能 ====================
|
|
621
|
-
|
|
622
|
-
async def _execute_cross_cli_call(
|
|
623
|
-
self,
|
|
624
|
-
target_cli: str,
|
|
625
|
-
task: str,
|
|
626
|
-
context: IFlowHookContext
|
|
627
|
-
) -> Optional[str]:
|
|
628
|
-
"""
|
|
629
|
-
执行跨CLI调用
|
|
630
|
-
|
|
631
|
-
Args:
|
|
632
|
-
target_cli: 目标CLI工具
|
|
633
|
-
task: 要执行的任务
|
|
634
|
-
context: Hook上下文
|
|
635
|
-
|
|
636
|
-
Returns:
|
|
637
|
-
Optional[str]: 执行结果
|
|
638
|
-
"""
|
|
639
|
-
try:
|
|
640
|
-
logger.info(f"执行跨CLI调用: {target_cli} -> {task}")
|
|
641
|
-
|
|
642
|
-
# 获取目标CLI适配器
|
|
643
|
-
from ...core.base_adapter import get_cross_cli_adapter
|
|
644
|
-
target_adapter = get_cross_cli_adapter(target_cli)
|
|
645
|
-
|
|
646
|
-
if not target_adapter:
|
|
647
|
-
logger.warning(f"目标CLI适配器不可用: {target_cli}")
|
|
648
|
-
return self._format_error_result(
|
|
649
|
-
target_cli,
|
|
650
|
-
task,
|
|
651
|
-
f"目标CLI工具 '{target_cli}' 不可用或未安装"
|
|
652
|
-
)
|
|
653
|
-
|
|
654
|
-
if not target_adapter.is_available():
|
|
655
|
-
logger.warning(f"目标CLI工具不可用: {target_cli}")
|
|
656
|
-
return self._format_error_result(
|
|
657
|
-
target_cli,
|
|
658
|
-
task,
|
|
659
|
-
f"目标CLI工具 '{target_cli}' 当前不可用"
|
|
660
|
-
)
|
|
661
|
-
|
|
662
|
-
# 构建执行上下文
|
|
663
|
-
execution_context = {
|
|
664
|
-
'source_cli': self.cli_name,
|
|
665
|
-
'target_cli': target_cli,
|
|
666
|
-
'original_task': task,
|
|
667
|
-
'hook_context': context.__dict__,
|
|
668
|
-
'iflow_context': {
|
|
669
|
-
'command': context.command,
|
|
670
|
-
'args': context.args,
|
|
671
|
-
'pipeline_name': context.pipeline_name,
|
|
672
|
-
'workflow_id': context.workflow_id
|
|
673
|
-
},
|
|
674
|
-
'timestamp': datetime.now().isoformat()
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
# 执行任务
|
|
678
|
-
result = await target_adapter.execute_task(task, execution_context)
|
|
679
|
-
|
|
680
|
-
# 记录成功的跨CLI调用
|
|
681
|
-
self.processed_requests.append({
|
|
682
|
-
'type': 'cross_cli_execution',
|
|
683
|
-
'target_cli': target_cli,
|
|
684
|
-
'task': task,
|
|
685
|
-
'success': True,
|
|
686
|
-
'result_length': len(result),
|
|
687
|
-
'timestamp': datetime.now().isoformat(),
|
|
688
|
-
'iflow_workflow_id': context.workflow_id
|
|
689
|
-
})
|
|
690
|
-
|
|
691
|
-
# 格式化结果
|
|
692
|
-
formatted_result = self._format_success_result(target_cli, task, result, context)
|
|
693
|
-
|
|
694
|
-
logger.info(f"跨CLI调用成功: {target_cli}")
|
|
695
|
-
return formatted_result
|
|
696
|
-
|
|
697
|
-
except Exception as e:
|
|
698
|
-
logger.error(f"跨CLI调用失败: {target_cli}, {e}")
|
|
699
|
-
self.record_error()
|
|
700
|
-
|
|
701
|
-
self.processed_requests.append({
|
|
702
|
-
'type': 'cross_cli_execution',
|
|
703
|
-
'target_cli': target_cli,
|
|
704
|
-
'task': task,
|
|
705
|
-
'success': False,
|
|
706
|
-
'error': str(e),
|
|
707
|
-
'timestamp': datetime.now().isoformat(),
|
|
708
|
-
'iflow_workflow_id': context.workflow_id
|
|
709
|
-
})
|
|
710
|
-
|
|
711
|
-
return self._format_error_result(target_cli, task, str(e))
|
|
712
|
-
|
|
713
|
-
async def _check_collaboration_opportunity(
|
|
714
|
-
self,
|
|
715
|
-
context: IFlowHookContext,
|
|
716
|
-
stage_data: Dict[str, Any]
|
|
717
|
-
) -> Optional[str]:
|
|
718
|
-
"""
|
|
719
|
-
检查协作机会
|
|
720
|
-
|
|
721
|
-
Args:
|
|
722
|
-
context: Hook上下文
|
|
723
|
-
stage_data: 阶段数据
|
|
724
|
-
|
|
725
|
-
Returns:
|
|
726
|
-
Optional[str]: 协作结果
|
|
727
|
-
"""
|
|
728
|
-
try:
|
|
729
|
-
if not self.collaboration_enabled:
|
|
730
|
-
return None
|
|
731
|
-
|
|
732
|
-
# 检查是否有协作机会
|
|
733
|
-
# 这里可以基于PROJECT_SPEC.json或其他协作机制
|
|
734
|
-
|
|
735
|
-
# 简单示例:如果阶段数据包含特定标识,触发协作
|
|
736
|
-
if stage_data.get('collaboration_request'):
|
|
737
|
-
target_cli = stage_data.get('target_cli')
|
|
738
|
-
collaboration_task = stage_data.get('task', '')
|
|
739
|
-
|
|
740
|
-
if target_cli and target_cli != self.cli_name:
|
|
741
|
-
return await self._execute_cross_cli_call(
|
|
742
|
-
target_cli,
|
|
743
|
-
collaboration_task,
|
|
744
|
-
context
|
|
745
|
-
)
|
|
746
|
-
|
|
747
|
-
return None
|
|
748
|
-
|
|
749
|
-
except Exception as e:
|
|
750
|
-
logger.error(f"检查协作机会失败: {e}")
|
|
751
|
-
return None
|
|
752
|
-
|
|
753
|
-
# ==================== 事件系统 ====================
|
|
754
|
-
|
|
755
|
-
async def _emit_event(self, event_type: str, data: Dict[str, Any]) -> None:
|
|
756
|
-
"""
|
|
757
|
-
触发事件
|
|
758
|
-
|
|
759
|
-
Args:
|
|
760
|
-
event_type: 事件类型
|
|
761
|
-
data: 事件数据
|
|
762
|
-
"""
|
|
763
|
-
try:
|
|
764
|
-
listeners = self.event_listeners.get(event_type, [])
|
|
765
|
-
|
|
766
|
-
for listener in listeners:
|
|
767
|
-
try:
|
|
768
|
-
if asyncio.iscoroutinefunction(listener):
|
|
769
|
-
await listener(data)
|
|
770
|
-
else:
|
|
771
|
-
listener(data)
|
|
772
|
-
except Exception as e:
|
|
773
|
-
logger.error(f"事件监听器执行失败: {e}")
|
|
774
|
-
|
|
775
|
-
except Exception as e:
|
|
776
|
-
logger.error(f"触发事件失败: {e}")
|
|
777
|
-
|
|
778
|
-
def add_event_listener(self, event_type: str, listener: Callable) -> None:
|
|
779
|
-
"""
|
|
780
|
-
添加事件监听器
|
|
781
|
-
|
|
782
|
-
Args:
|
|
783
|
-
event_type: 事件类型
|
|
784
|
-
listener: 监听器函数
|
|
785
|
-
"""
|
|
786
|
-
if event_type not in self.event_listeners:
|
|
787
|
-
self.event_listeners[event_type] = []
|
|
788
|
-
self.event_listeners[event_type].append(listener)
|
|
789
|
-
|
|
790
|
-
# ==================== 结果格式化 ====================
|
|
791
|
-
|
|
792
|
-
def _format_success_result(
|
|
793
|
-
self,
|
|
794
|
-
target_cli: str,
|
|
795
|
-
task: str,
|
|
796
|
-
result: str,
|
|
797
|
-
context: IFlowHookContext
|
|
798
|
-
) -> str:
|
|
799
|
-
"""
|
|
800
|
-
格式化成功的跨CLI调用结果
|
|
801
|
-
|
|
802
|
-
Args:
|
|
803
|
-
target_cli: 目标CLI工具
|
|
804
|
-
task: 原始任务
|
|
805
|
-
result: 执行结果
|
|
806
|
-
context: Hook上下文
|
|
807
|
-
|
|
808
|
-
Returns:
|
|
809
|
-
str: 格式化的结果
|
|
810
|
-
"""
|
|
811
|
-
workflow_info = ""
|
|
812
|
-
if context.workflow_id:
|
|
813
|
-
workflow_info = f"\n**工作流ID**: {context.workflow_id}"
|
|
814
|
-
if context.stage_name:
|
|
815
|
-
workflow_info += f"\n**当前阶段**: {context.stage_name}"
|
|
816
|
-
|
|
817
|
-
return f"""## 🔗 跨CLI调用结果 (iFlow Hook)
|
|
818
|
-
|
|
819
|
-
**源工具**: iFlow CLI
|
|
820
|
-
**目标工具**: {target_cli.upper()}
|
|
821
|
-
**原始任务**: {task}{workflow_info}
|
|
822
|
-
**执行时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
823
|
-
|
|
824
|
-
---
|
|
825
|
-
|
|
826
|
-
{result}
|
|
827
|
-
|
|
828
|
-
---
|
|
829
|
-
|
|
830
|
-
*此结果由跨CLI集成系统通过iFlow CLI Hook提供*"""
|
|
831
|
-
|
|
832
|
-
def _format_error_result(
|
|
833
|
-
self,
|
|
834
|
-
target_cli: str,
|
|
835
|
-
task: str,
|
|
836
|
-
error_message: str
|
|
837
|
-
) -> str:
|
|
838
|
-
"""
|
|
839
|
-
格式化错误的跨CLI调用结果
|
|
840
|
-
|
|
841
|
-
Args:
|
|
842
|
-
target_cli: 目标CLI工具
|
|
843
|
-
task: 原始任务
|
|
844
|
-
error_message: 错误信息
|
|
845
|
-
|
|
846
|
-
Returns:
|
|
847
|
-
str: 格式化的错误结果
|
|
848
|
-
"""
|
|
849
|
-
return f"""## ❌ 跨CLI调用失败
|
|
850
|
-
|
|
851
|
-
**源工具**: iFlow CLI
|
|
852
|
-
**目标工具**: {target_cli.upper()}
|
|
853
|
-
**原始任务**: {task}
|
|
854
|
-
**错误信息**: {error_message}
|
|
855
|
-
**失败时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
856
|
-
|
|
857
|
-
请检查目标CLI工具是否正确安装和配置。
|
|
858
|
-
|
|
859
|
-
---
|
|
860
|
-
|
|
861
|
-
*此错误由跨CLI集成系统报告*"""
|
|
862
|
-
|
|
863
|
-
# ==================== 基础接口实现 ====================
|
|
864
|
-
|
|
865
|
-
def is_available(self) -> bool:
|
|
866
|
-
"""
|
|
867
|
-
检查适配器是否可用
|
|
868
|
-
|
|
869
|
-
Returns:
|
|
870
|
-
bool: 是否可用
|
|
871
|
-
"""
|
|
872
|
-
return (
|
|
873
|
-
self.hooks_registered and
|
|
874
|
-
self._check_iflow_environment() and
|
|
875
|
-
len(self.hook_handlers) > 0
|
|
876
|
-
)
|
|
877
|
-
|
|
878
|
-
async def execute_task(self, task: str, context: Dict[str, Any]) -> str:
|
|
879
|
-
"""
|
|
880
|
-
执行跨CLI任务 - iFlow适配器的具体实现
|
|
881
|
-
|
|
882
|
-
Args:
|
|
883
|
-
task: 要执行的任务描述
|
|
884
|
-
context: 执行上下文信息
|
|
885
|
-
|
|
886
|
-
Returns:
|
|
887
|
-
str: 任务执行结果
|
|
888
|
-
"""
|
|
889
|
-
try:
|
|
890
|
-
# 创建Hook上下文
|
|
891
|
-
hook_context = IFlowHookContext(
|
|
892
|
-
command=task,
|
|
893
|
-
user_input=task,
|
|
894
|
-
metadata=context.get('metadata', {}),
|
|
895
|
-
workflow_id=context.get('workflow_id', ''),
|
|
896
|
-
stage_name=context.get('stage_name', 'execution')
|
|
897
|
-
)
|
|
898
|
-
|
|
899
|
-
# 检查是否为跨CLI调用
|
|
900
|
-
intent = self.parser.parse_intent(task, "iflow")
|
|
901
|
-
if intent.is_cross_cli and intent.target_cli != self.cli_name:
|
|
902
|
-
# 执行跨CLI调用
|
|
903
|
-
result = await self._execute_cross_cli_call(
|
|
904
|
-
intent.target_cli,
|
|
905
|
-
intent.task,
|
|
906
|
-
hook_context
|
|
907
|
-
)
|
|
908
|
-
return result or f"iFlow Hook适配器处理了跨CLI任务: {task}"
|
|
909
|
-
else:
|
|
910
|
-
# 本地iFlow任务处理
|
|
911
|
-
return f"iFlow Hook适配器本地处理: {task}"
|
|
912
|
-
|
|
913
|
-
except Exception as e:
|
|
914
|
-
logger.error(f"执行任务失败: {task}, 错误: {e}")
|
|
915
|
-
self.record_error()
|
|
916
|
-
return f"任务执行失败: {str(e)}"
|
|
917
|
-
|
|
918
|
-
async def health_check(self) -> Dict[str, Any]:
|
|
919
|
-
"""
|
|
920
|
-
健康检查
|
|
921
|
-
|
|
922
|
-
Returns:
|
|
923
|
-
Dict[str, Any]: 健康状态
|
|
924
|
-
"""
|
|
925
|
-
base_health = await super().health_check()
|
|
926
|
-
|
|
927
|
-
iflow_health = {
|
|
928
|
-
'hooks_registered': self.hooks_registered,
|
|
929
|
-
'hook_calls_count': self.hook_calls_count,
|
|
930
|
-
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
931
|
-
'processed_events_count': len(self.processed_events),
|
|
932
|
-
'command_interceptions_count': len(self.command_interceptions),
|
|
933
|
-
'active_workflows_count': len(self.active_workflows),
|
|
934
|
-
'hooks_config_file': self.hooks_config_file,
|
|
935
|
-
'hooks_config_exists': os.path.exists(self.hooks_config_file),
|
|
936
|
-
'iflow_version': self.iflow_version,
|
|
937
|
-
'collaboration_enabled': self.collaboration_enabled,
|
|
938
|
-
'event_listeners_count': sum(len(listeners) for listeners in self.event_listeners.values())
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
# 检查环境
|
|
942
|
-
try:
|
|
943
|
-
iflow_health['iflow_environment'] = self._check_iflow_environment()
|
|
944
|
-
except Exception as e:
|
|
945
|
-
iflow_health['iflow_environment_error'] = str(e)
|
|
946
|
-
|
|
947
|
-
# 合并基础健康信息
|
|
948
|
-
base_health.update(iflow_health)
|
|
949
|
-
return base_health
|
|
950
|
-
|
|
951
|
-
def get_statistics(self) -> Dict[str, Any]:
|
|
952
|
-
"""
|
|
953
|
-
获取适配器统计信息
|
|
954
|
-
|
|
955
|
-
Returns:
|
|
956
|
-
Dict[str, Any]: 统计信息
|
|
957
|
-
"""
|
|
958
|
-
base_stats = super().get_statistics()
|
|
959
|
-
|
|
960
|
-
iflow_stats = {
|
|
961
|
-
'hooks_registered': self.hooks_registered,
|
|
962
|
-
'hook_calls_count': self.hook_calls_count,
|
|
963
|
-
'cross_cli_calls_count': self.cross_cli_calls_count,
|
|
964
|
-
'processed_events_count': len(self.processed_events),
|
|
965
|
-
'command_interceptions_count': len(self.command_interceptions),
|
|
966
|
-
'active_workflows_count': len(self.active_workflows),
|
|
967
|
-
'supported_hooks': list(self.hook_handlers.keys()),
|
|
968
|
-
'event_types': list(self.event_listeners.keys()),
|
|
969
|
-
'collaboration_enabled': self.collaboration_enabled,
|
|
970
|
-
'iflow_version': self.iflow_version
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
base_stats.update(iflow_stats)
|
|
974
|
-
return base_stats
|
|
975
|
-
|
|
976
|
-
async def cleanup(self) -> bool:
|
|
977
|
-
"""
|
|
978
|
-
清理适配器资源
|
|
979
|
-
|
|
980
|
-
Returns:
|
|
981
|
-
bool: 清理是否成功
|
|
982
|
-
"""
|
|
983
|
-
try:
|
|
984
|
-
# 清理统计信息
|
|
985
|
-
self.processed_events.clear()
|
|
986
|
-
self.command_interceptions.clear()
|
|
987
|
-
self.active_workflows.clear()
|
|
988
|
-
|
|
989
|
-
# 清理事件监听器
|
|
990
|
-
self.event_listeners.clear()
|
|
991
|
-
|
|
992
|
-
logger.info("iFlow Hook适配器清理完成")
|
|
993
|
-
return True
|
|
994
|
-
|
|
995
|
-
except Exception as e:
|
|
996
|
-
logger.error(f"清理iFlow Hook适配器失败: {e}")
|
|
997
|
-
return False
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
# 创建全局适配器实例
|
|
1001
|
-
_global_adapter: Optional[IFlowHookAdapter] = None
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
def get_iflow_hook_adapter() -> IFlowHookAdapter:
|
|
1005
|
-
"""
|
|
1006
|
-
获取iFlow Hook适配器实例
|
|
1007
|
-
|
|
1008
|
-
Returns:
|
|
1009
|
-
IFlowHookAdapter: 适配器实例
|
|
1010
|
-
"""
|
|
1011
|
-
global _global_adapter
|
|
1012
|
-
if _global_adapter is None:
|
|
1013
|
-
_global_adapter = IFlowHookAdapter()
|
|
1014
|
-
# 异步初始化需要在调用时进行
|
|
1015
|
-
return _global_adapter
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
# 便捷函数
|
|
1019
|
-
async def initialize_iflow_adapter() -> bool:
|
|
1020
|
-
"""
|
|
1021
|
-
初始化iFlow Hook适配器
|
|
1022
|
-
|
|
1023
|
-
Returns:
|
|
1024
|
-
bool: 初始化是否成功
|
|
1025
|
-
"""
|
|
1026
|
-
adapter = get_iflow_hook_adapter()
|
|
1027
|
-
return await adapter.initialize()
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
def is_iflow_adapter_available() -> bool:
|
|
1031
|
-
"""
|
|
1032
|
-
检查iFlow Hook适配器是否可用
|
|
1033
|
-
|
|
1034
|
-
Returns:
|
|
1035
|
-
bool: 是否可用
|
|
1036
|
-
"""
|
|
1037
|
-
adapter = get_iflow_hook_adapter()
|
|
1038
|
-
return adapter.is_available()
|