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,467 +0,0 @@
1
- """
2
- Enhanced Init Processor - 增强的初始化处理器
3
- 处理新老两种项目的 /init 指令,集成AI环境感知
4
- """
5
- import os
6
- import asyncio
7
- from pathlib import Path
8
- from datetime import datetime
9
- from typing import Dict, List, Optional, Any
10
-
11
- from .models import (
12
- ProjectStatus, InitResult, EnhancementResult, GeneratedDocument,
13
- AIEnvironmentInfo, CLI_CONFIG_MAPPING
14
- )
15
- from .ai_environment_scanner import AIEnvironmentScanner
16
- from .md_enhancer import MDDocumentEnhancer
17
- from .md_generator import MDDocumentGenerator
18
-
19
- import logging
20
- logger = logging.getLogger(__name__)
21
-
22
-
23
- class EnhancedInitProcessor:
24
- """增强的初始化处理器 - 处理新老两种项目情况"""
25
-
26
- def __init__(self, current_cli: str):
27
- self.current_cli = current_cli
28
- self.ai_environment_scanner = AIEnvironmentScanner(current_cli)
29
- self.md_enhancer = MDDocumentEnhancer()
30
- self.md_generator = MDDocumentGenerator()
31
-
32
- async def process_init_command(self, project_path: str) -> InitResult:
33
- """处理 /init 指令,自动检测新老项目"""
34
- start_time = datetime.now()
35
-
36
- try:
37
- logger.info(f"开始处理 /init 指令,当前CLI: {self.current_cli},项目路径: {project_path}")
38
-
39
- # 1. 检测项目类型(新老项目)
40
- logger.info("检测项目状态...")
41
- project_status = await self._detect_project_status(project_path)
42
-
43
- # 2. 扫描AI环境
44
- logger.info("扫描AI环境...")
45
- ai_environment = await self.ai_environment_scanner.scan_ai_environment(project_path)
46
-
47
- # 3. 根据项目类型处理
48
- if project_status.is_existing_project:
49
- # 老项目:增强现有MD文档
50
- logger.info("检测到现有项目,开始增强现有MD文档...")
51
- result = await self._enhance_existing_project(project_path, ai_environment)
52
- result.project_type = "existing_project"
53
- else:
54
- # 新项目:生成完整MD文档
55
- logger.info("检测到新项目,开始生成完整MD文档...")
56
- result = await self._initialize_new_project(project_path, ai_environment)
57
- result.project_type = "new_project"
58
-
59
- # 4. 计算处理时间
60
- processing_time = (datetime.now() - start_time).total_seconds()
61
- result.processing_time = processing_time
62
-
63
- logger.info(f"/init 指令处理完成,耗时: {processing_time:.2f}秒")
64
- return result
65
-
66
- except Exception as e:
67
- logger.error(f"处理 /init 指令失败: {e}")
68
- # 返回错误结果,但不抛出异常
69
- return InitResult(
70
- project_type="error",
71
- ai_environment=None,
72
- message=f"❌ 处理失败: {str(e)}",
73
- processing_time=(datetime.now() - start_time).total_seconds()
74
- )
75
-
76
- async def _detect_project_status(self, project_path: str) -> ProjectStatus:
77
- """检测项目状态"""
78
- existing_md_files = []
79
- existing_md_files_lower = set() # 用于追踪已找到的文档(不区分大小写)
80
- project_path_obj = Path(project_path)
81
-
82
- # 检查是否存在CLI工具的MD文档
83
- cli_tools = list(CLI_CONFIG_MAPPING.keys())
84
-
85
- for cli in cli_tools:
86
- md_file = project_path_obj / f"{cli}.md"
87
- if md_file.exists() and md_file.is_file():
88
- # 规范化工具名称为小写进行重复检查
89
- normalized_name = cli.lower()
90
-
91
- # 如果这个名称已经记录过(不区分大小写),则跳过
92
- if normalized_name in existing_md_files_lower:
93
- logger.warning(f"检测到重复的CLI文档(不区分大小写): {cli}.md,跳过记录")
94
- continue
95
-
96
- existing_md_files.append(cli)
97
- existing_md_files_lower.add(normalized_name)
98
- logger.debug(f"发现现有文档: {cli}.md")
99
-
100
- is_existing = len(existing_md_files) > 0
101
-
102
- logger.info(f"项目状态检测结果: {'现有项目' if is_existing else '新项目'}")
103
- logger.info(f"现有MD文档: {existing_md_files}")
104
-
105
- return ProjectStatus(
106
- is_existing_project=is_existing,
107
- existing_md_files=existing_md_files,
108
- total_expected=len(cli_tools),
109
- project_path=project_path
110
- )
111
-
112
- async def _enhance_existing_project(self,
113
- project_path: str,
114
- ai_environment: AIEnvironmentInfo) -> InitResult:
115
- """老项目:增强现有MD文档"""
116
- enhancement_results = {}
117
- enhanced_count = 0
118
-
119
- try:
120
- # 增强所有现有的MD文档(不仅仅是当前CLI的文档)
121
- # 创建一个集合来跟踪已经处理的文档名称(不区分大小写)
122
- processed_names = set()
123
-
124
- for cli_name in ai_environment.available_clis:
125
- # 规范化工具名称为小写进行重复检查
126
- normalized_name = cli_name.lower()
127
-
128
- # 如果这个名称已经处理过(不区分大小写),则跳过
129
- if normalized_name in processed_names:
130
- logger.warning(f"检测到重复的CLI工具名(不区分大小写)在增强过程中: {cli_name},跳过处理")
131
- continue
132
-
133
- md_path = Path(project_path) / f"{cli_name}.md"
134
-
135
- if md_path.exists():
136
- logger.info(f"增强现有文档: {cli_name}.md")
137
-
138
- try:
139
- # 读取现有文档
140
- existing_content = await self._read_md_file(md_path)
141
-
142
- # 生成协作感知内容
143
- collaboration_content = await self.md_enhancer.generate_collaboration_section(
144
- cli_name, ai_environment, current_cli=self.current_cli
145
- )
146
-
147
- # 增强现有文档
148
- enhanced_content = await self.md_enhancer.enhance_existing_md(
149
- existing_content, collaboration_content, cli_name
150
- )
151
-
152
- # 写回文件
153
- await self._write_md_file(md_path, enhanced_content)
154
-
155
- # 创建备份(可选)
156
- await self._create_backup(md_path, existing_content)
157
-
158
- enhancement_results[cli_name] = EnhancementResult(
159
- enhanced=True,
160
- added_collaboration_section=True,
161
- original_sections=len(self._count_sections(existing_content)),
162
- new_sections=len(self._count_sections(enhanced_content)),
163
- enhancement_time=datetime.now()
164
- )
165
-
166
- # 添加到已处理集合中
167
- processed_names.add(normalized_name)
168
- enhanced_count += 1
169
- logger.info(f"成功增强 {cli_name}.md")
170
-
171
- except Exception as e:
172
- logger.error(f"增强文档 {cli_name}.md 失败: {e}")
173
- enhancement_results[cli_name] = EnhancementResult(
174
- enhanced=False,
175
- added_collaboration_section=False,
176
- original_sections=0,
177
- new_sections=0,
178
- enhancement_time=datetime.now()
179
- )
180
-
181
- # 生成项目配置文件
182
- await self._ensure_project_config(project_path, ai_environment)
183
-
184
- message = f"✅ 已增强 {enhanced_count} 个CLI文档的协作感知"
185
- if enhanced_count < len(ai_environment.available_clis):
186
- missing_count = len(ai_environment.available_clis) - enhanced_count
187
- message += f",{missing_count} 个文档增强失败"
188
- if missing_count > 0:
189
- logger.warning(f"有 {missing_count} 个CLI工具由于重复名称等原因未被增强")
190
-
191
- return InitResult(
192
- project_type="existing_project",
193
- enhanced_documents=enhancement_results,
194
- ai_environment=ai_environment,
195
- message=message
196
- )
197
-
198
- except Exception as e:
199
- logger.error(f"增强现有项目失败: {e}")
200
- raise
201
-
202
- async def _initialize_new_project(self,
203
- project_path: str,
204
- ai_environment: AIEnvironmentInfo) -> InitResult:
205
- """新项目:生成完整MD文档"""
206
- generated_documents = {}
207
- generated_count = 0
208
-
209
- try:
210
- # 为每个可用的CLI工具生成完整的MD文档
211
- # 创建一个集合来跟踪已经生成的文档名称(不区分大小写)
212
- generated_names = set()
213
-
214
- for cli_name, cli_info in ai_environment.available_clis.items():
215
- # 规范化工具名称为小写进行重复检查
216
- normalized_name = cli_name.lower()
217
-
218
- # 如果这个名称已经处理过(不区分大小写),则跳过
219
- if normalized_name in generated_names:
220
- logger.warning(f"检测到重复的CLI工具名(不区分大小写): {cli_name},跳过生成")
221
- continue
222
-
223
- logger.info(f"生成文档: {cli_name}.md")
224
-
225
- try:
226
- # 生成完整MD文档
227
- md_content = await self.md_generator.generate_complete_md(
228
- cli_name, cli_info, ai_environment, current_cli=self.current_cli
229
- )
230
-
231
- md_path = Path(project_path) / f"{cli_name}.md"
232
- await self._write_md_file(md_path, md_content)
233
-
234
- generated_documents[cli_name] = GeneratedDocument(
235
- file_path=str(md_path),
236
- sections_count=self._count_sections(md_content),
237
- includes_collaboration=True,
238
- generation_time=datetime.now()
239
- )
240
-
241
- # 添加到已生成集合中
242
- generated_names.add(normalized_name)
243
- generated_count += 1
244
- logger.info(f"成功生成 {cli_name}.md")
245
-
246
- except Exception as e:
247
- logger.error(f"生成文档 {cli_name}.md 失败: {e}")
248
-
249
- # 创建项目配置目录和文件
250
- await self._create_project_config(project_path, ai_environment)
251
-
252
- # 创建 .ai-cli-project 目录
253
- await self._create_ai_cli_project_dir(project_path, ai_environment)
254
-
255
- message = f"✅ 已生成 {generated_count} 个完整CLI文档,包含协作感知"
256
- if generated_count < len(ai_environment.available_clis):
257
- missing_count = len(ai_environment.available_clis) - generated_count
258
- message += f",{missing_count} 个文档生成失败"
259
- if missing_count > 0:
260
- logger.warning(f"有 {missing_count} 个CLI工具由于重复名称等原因未生成文档")
261
-
262
- return InitResult(
263
- project_type="new_project",
264
- generated_documents=generated_documents,
265
- ai_environment=ai_environment,
266
- message=message
267
- )
268
-
269
- except Exception as e:
270
- logger.error(f"初始化新项目失败: {e}")
271
- raise
272
-
273
- async def _read_md_file(self, file_path: Path) -> str:
274
- """读取MD文件"""
275
- try:
276
- with open(file_path, 'r', encoding='utf-8') as f:
277
- return f.read()
278
- except Exception as e:
279
- logger.error(f"读取文件失败 {file_path}: {e}")
280
- raise
281
-
282
- async def _write_md_file(self, file_path: Path, content: str) -> None:
283
- """写入MD文件"""
284
- try:
285
- # 确保目录存在
286
- file_path.parent.mkdir(parents=True, exist_ok=True)
287
-
288
- with open(file_path, 'w', encoding='utf-8') as f:
289
- f.write(content)
290
-
291
- except Exception as e:
292
- logger.error(f"写入文件失败 {file_path}: {e}")
293
- raise
294
-
295
- async def _create_backup(self, file_path: Path, original_content: str) -> None:
296
- """创建文件备份"""
297
- try:
298
- backup_dir = file_path.parent / ".ai-cli-backups"
299
- backup_dir.mkdir(exist_ok=True)
300
-
301
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
302
- backup_filename = f"{file_path.stem}_{timestamp}{file_path.suffix}"
303
- backup_path = backup_dir / backup_filename
304
-
305
- with open(backup_path, 'w', encoding='utf-8') as f:
306
- f.write(original_content)
307
-
308
- logger.debug(f"创建备份: {backup_path}")
309
-
310
- except Exception as e:
311
- logger.warning(f"创建备份失败: {e}")
312
-
313
- def _count_sections(self, content: str) -> int:
314
- """统计文档中的章节数量"""
315
- sections = []
316
- lines = content.split('\n')
317
-
318
- for line in lines:
319
- if line.strip().startswith('#'):
320
- sections.append(line.strip())
321
-
322
- return len(sections)
323
-
324
- async def _ensure_project_config(self, project_path: str, ai_environment: AIEnvironmentInfo) -> None:
325
- """确保项目配置文件存在"""
326
- try:
327
- config_dir = Path(project_path) / ".ai-cli-project"
328
- config_dir.mkdir(exist_ok=True)
329
-
330
- # 创建基础项目配置
331
- config_file = config_dir / "project-config.json"
332
- if not config_file.exists():
333
- import json
334
- project_config = {
335
- "project_type": "enhanced_existing",
336
- "last_update": datetime.now().isoformat(),
337
- "available_tools": list(ai_environment.available_clis.keys()),
338
- "current_cli": self.current_cli,
339
- "collaboration_enabled": True,
340
- "auto_scan": True
341
- }
342
-
343
- with open(config_file, 'w', encoding='utf-8') as f:
344
- json.dump(project_config, f, indent=2, ensure_ascii=False)
345
-
346
- logger.info(f"创建项目配置文件: {config_file}")
347
-
348
- except Exception as e:
349
- logger.warning(f"创建项目配置失败: {e}")
350
-
351
- async def _create_project_config(self, project_path: str, ai_environment: AIEnvironmentInfo) -> None:
352
- """为新项目创建配置文件"""
353
- try:
354
- config_dir = Path(project_path) / ".ai-cli-project"
355
- config_dir.mkdir(exist_ok=True)
356
-
357
- # 创建项目配置文件
358
- import json
359
- project_config = {
360
- "project_type": "new_initialized",
361
- "created_at": datetime.now().isoformat(),
362
- "last_update": datetime.now().isoformat(),
363
- "initiated_by": self.current_cli,
364
- "available_tools": {
365
- cli_name: {
366
- "name": cli_info.display_name,
367
- "version": cli_info.version,
368
- "status": cli_info.status.value,
369
- "enabled": True
370
- }
371
- for cli_name, cli_info in ai_environment.available_clis.items()
372
- },
373
- "collaboration": {
374
- "enabled": True,
375
- "auto_detect": True,
376
- "protocols": ai_environment.collaboration_guide.protocols
377
- },
378
- "preferences": {
379
- "primary_tool": self.current_cli,
380
- "language": "mixed", # 支持中英文混合
381
- "auto_backup": True
382
- }
383
- }
384
-
385
- config_file = config_dir / "project-config.json"
386
- with open(config_file, 'w', encoding='utf-8') as f:
387
- json.dump(project_config, f, indent=2, ensure_ascii=False)
388
-
389
- logger.info(f"创建新项目配置文件: {config_file}")
390
-
391
- except Exception as e:
392
- logger.warning(f"创建新项目配置失败: {e}")
393
-
394
- async def _create_ai_cli_project_dir(self, project_path: str, ai_environment: AIEnvironmentInfo) -> None:
395
- """创建 .ai-cli-project 目录结构"""
396
- try:
397
- ai_cli_dir = Path(project_path) / ".ai-cli-project"
398
- ai_cli_dir.mkdir(exist_ok=True)
399
-
400
- # 创建子目录
401
- subdirs = ["logs", "backups", "cache", "templates"]
402
- for subdir in subdirs:
403
- (ai_cli_dir / subdir).mkdir(exist_ok=True)
404
-
405
- # 创建 .gitignore
406
- gitignore_path = ai_cli_dir / ".gitignore"
407
- if not gitignore_path.exists():
408
- gitignore_content = """# AI CLI Router generated files
409
- logs/
410
- backups/
411
- cache/
412
- *.log
413
- *.tmp
414
- .DS_Store
415
- """
416
- with open(gitignore_path, 'w', encoding='utf-8') as f:
417
- f.write(gitignore_content)
418
-
419
- # 创建 README.md
420
- readme_path = ai_cli_dir / "README.md"
421
- if not readme_path.exists():
422
- readme_content = f"""# AI CLI Router 项目配置
423
-
424
- 此目录包含 AI CLI Router 的项目特定配置文件。
425
-
426
- ## 📁 目录结构
427
-
428
- - `project-config.json` - 项目AI配置
429
- - `logs/` - AI CLI操作日志
430
- - `backups/` - 配置文件备份
431
- - `cache/` - 临时缓存文件
432
- - `templates/` - 自定义模板
433
-
434
- ## 🤖 可用AI工具
435
-
436
- {chr(10).join(f"- **{info.display_name}** v{info.version}" for info in ai_environment.available_clis.values())}
437
-
438
- ## 📅 初始化信息
439
-
440
- - 初始化时间: {ai_environment.generated_at.strftime('%Y-%m-%d %H:%M:%S')}
441
- - 初始化工具: {self.current_cli}
442
- - 扫描耗时: {ai_environment.scan_duration:.2f}秒
443
-
444
- ## 🔧 配置管理
445
-
446
- 使用以下命令管理项目配置:
447
- ```bash
448
- # 更新AI环境扫描
449
- ai-cli-router scan
450
-
451
- # 验证项目配置
452
- ai-cli-router check-project
453
-
454
- # 重置项目配置
455
- ai-cli-router reset --project
456
- ```
457
-
458
- ---
459
- *此目录由 AI CLI Router 自动生成和管理*
460
- """
461
- with open(readme_path, 'w', encoding='utf-8') as f:
462
- f.write(readme_content)
463
-
464
- logger.info(f"创建 .ai-cli-project 目录结构: {ai_cli_dir}")
465
-
466
- except Exception as e:
467
- logger.warning(f"创建 .ai-cli-project 目录失败: {e}")