stigmergy 1.0.57

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 (94) hide show
  1. package/LICENSE +19 -0
  2. package/README.de.md +301 -0
  3. package/README.en.md +301 -0
  4. package/README.es.md +301 -0
  5. package/README.fr.md +301 -0
  6. package/README.ja.md +301 -0
  7. package/README.ko.md +301 -0
  8. package/README.md +301 -0
  9. package/README.ru.md +301 -0
  10. package/README.zh.md +301 -0
  11. package/package.json +82 -0
  12. package/src/adapters/claude/__init__.py +13 -0
  13. package/src/adapters/claude/claude_skills_integration.py +609 -0
  14. package/src/adapters/claude/hook_adapter.py +663 -0
  15. package/src/adapters/claude/install_claude_integration.py +265 -0
  16. package/src/adapters/claude/skills_hook_adapter.py +841 -0
  17. package/src/adapters/claude/standalone_claude_adapter.py +384 -0
  18. package/src/adapters/cline/__init__.py +20 -0
  19. package/src/adapters/cline/config.py +108 -0
  20. package/src/adapters/cline/install_cline_integration.py +617 -0
  21. package/src/adapters/cline/mcp_server.py +713 -0
  22. package/src/adapters/cline/standalone_cline_adapter.py +459 -0
  23. package/src/adapters/codebuddy/__init__.py +13 -0
  24. package/src/adapters/codebuddy/buddy_adapter.py +1125 -0
  25. package/src/adapters/codebuddy/install_codebuddy_integration.py +279 -0
  26. package/src/adapters/codebuddy/skills_hook_adapter.py +672 -0
  27. package/src/adapters/codebuddy/skills_integration.py +395 -0
  28. package/src/adapters/codebuddy/standalone_codebuddy_adapter.py +403 -0
  29. package/src/adapters/codex/__init__.py +11 -0
  30. package/src/adapters/codex/base.py +46 -0
  31. package/src/adapters/codex/install_codex_integration.py +311 -0
  32. package/src/adapters/codex/mcp_server.py +493 -0
  33. package/src/adapters/codex/natural_language_parser.py +82 -0
  34. package/src/adapters/codex/slash_command_adapter.py +326 -0
  35. package/src/adapters/codex/standalone_codex_adapter.py +362 -0
  36. package/src/adapters/copilot/__init__.py +13 -0
  37. package/src/adapters/copilot/install_copilot_integration.py +564 -0
  38. package/src/adapters/copilot/mcp_adapter.py +772 -0
  39. package/src/adapters/copilot/mcp_server.py +168 -0
  40. package/src/adapters/copilot/standalone_copilot_adapter.py +114 -0
  41. package/src/adapters/gemini/__init__.py +13 -0
  42. package/src/adapters/gemini/extension_adapter.py +690 -0
  43. package/src/adapters/gemini/install_gemini_integration.py +257 -0
  44. package/src/adapters/gemini/standalone_gemini_adapter.py +366 -0
  45. package/src/adapters/iflow/__init__.py +7 -0
  46. package/src/adapters/iflow/hook_adapter.py +1038 -0
  47. package/src/adapters/iflow/hook_installer.py +536 -0
  48. package/src/adapters/iflow/install_iflow_integration.py +271 -0
  49. package/src/adapters/iflow/official_hook_adapter.py +1272 -0
  50. package/src/adapters/iflow/standalone_iflow_adapter.py +48 -0
  51. package/src/adapters/iflow/workflow_adapter.py +793 -0
  52. package/src/adapters/qoder/hook_installer.py +732 -0
  53. package/src/adapters/qoder/install_qoder_integration.py +265 -0
  54. package/src/adapters/qoder/notification_hook_adapter.py +863 -0
  55. package/src/adapters/qoder/standalone_qoder_adapter.py +48 -0
  56. package/src/adapters/qwen/__init__.py +17 -0
  57. package/src/adapters/qwencode/__init__.py +13 -0
  58. package/src/adapters/qwencode/inheritance_adapter.py +818 -0
  59. package/src/adapters/qwencode/install_qwencode_integration.py +276 -0
  60. package/src/adapters/qwencode/standalone_qwencode_adapter.py +399 -0
  61. package/src/atomic_collaboration_handler.py +461 -0
  62. package/src/cli_collaboration_agent.py +697 -0
  63. package/src/collaboration/hooks.py +315 -0
  64. package/src/core/__init__.py +21 -0
  65. package/src/core/ai_environment_scanner.py +331 -0
  66. package/src/core/base_adapter.py +220 -0
  67. package/src/core/cli_hook_integration.py +406 -0
  68. package/src/core/cross_cli_executor.py +713 -0
  69. package/src/core/cross_cli_mapping.py +1163 -0
  70. package/src/core/cross_platform_encoding.py +365 -0
  71. package/src/core/cross_platform_safe_cli.py +894 -0
  72. package/src/core/direct_cli_executor.py +805 -0
  73. package/src/core/direct_cli_hook_system.py +958 -0
  74. package/src/core/enhanced_init_processor.py +427 -0
  75. package/src/core/graceful_cli_executor.py +912 -0
  76. package/src/core/md_enhancer.py +342 -0
  77. package/src/core/md_generator.py +619 -0
  78. package/src/core/models.py +218 -0
  79. package/src/core/parser.py +108 -0
  80. package/src/core/real_cli_hook_system.py +852 -0
  81. package/src/core/real_cross_cli_system.py +925 -0
  82. package/src/core/verified_cross_cli_system.py +961 -0
  83. package/src/deploy.js +737 -0
  84. package/src/enhanced_deploy.js +303 -0
  85. package/src/enhanced_universal_cli_setup.py +930 -0
  86. package/src/kimi_wrapper.py +104 -0
  87. package/src/main.js +1309 -0
  88. package/src/shell_integration.py +398 -0
  89. package/src/simple-main.js +315 -0
  90. package/src/smart_router_creator.py +323 -0
  91. package/src/universal_cli_setup.py +1289 -0
  92. package/src/utils/__init__.py +12 -0
  93. package/src/utils/cli_detector.py +445 -0
  94. package/src/utils/file_utils.py +246 -0
@@ -0,0 +1,365 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ 跨平台编码安全工具库
5
+ 解决Windows/Linux/macOS上GBK/UTF-8等编码冲突问题
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ import json
11
+ import yaml
12
+ import shutil
13
+ import locale
14
+ import platform
15
+ import codecs
16
+ import traceback
17
+ from pathlib import Path
18
+ from datetime import datetime
19
+ from typing import Dict, Any, Optional, Union, List
20
+
21
+ class EncodingError(Exception):
22
+ """编码相关异常"""
23
+ pass
24
+
25
+ class CrossPlatformEncoding:
26
+ """跨平台编码处理器"""
27
+
28
+ def __init__(self):
29
+ self.system = platform.system().lower()
30
+ self.default_encoding = self._detect_system_encoding()
31
+ self.fallback_encodings = self._get_fallback_encodings()
32
+
33
+ def _detect_system_encoding(self) -> str:
34
+ """检测系统默认编码"""
35
+ try:
36
+ # 优先使用系统locale编码
37
+ system_encoding = locale.getpreferredencoding(False)
38
+ if system_encoding and system_encoding.lower() != 'ascii':
39
+ return system_encoding.lower()
40
+ except:
41
+ pass
42
+
43
+ try:
44
+ # 尝试Python默认编码
45
+ return sys.getdefaultencoding().lower()
46
+ except:
47
+ pass
48
+
49
+ # 最后的默认值
50
+ return 'utf-8'
51
+
52
+ def _get_fallback_encodings(self) -> List[str]:
53
+ """获取备用编码列表"""
54
+ encodings = ['utf-8']
55
+
56
+ if self.system == 'windows':
57
+ encodings.extend(['gbk', 'gb2312', 'cp936', 'utf-8-sig'])
58
+ elif self.system == 'linux':
59
+ encodings.extend(['utf-8-sig', 'latin-1'])
60
+ elif self.system == 'darwin':
61
+ encodings.extend(['utf-8-sig', 'mac-roman'])
62
+
63
+ return encodings
64
+
65
+ def setup_environment(self):
66
+ """设置环境编码"""
67
+ if self.system == 'windows':
68
+ # Windows特殊处理
69
+ os.environ['PYTHONIOENCODING'] = 'utf-8'
70
+ os.environ['PYTHONLEGACYWINDOWSSTDIO'] = 'utf-8'
71
+
72
+ # 重配置标准流
73
+ try:
74
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
75
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
76
+ except:
77
+ pass
78
+
79
+ # 通用设置
80
+ if 'PYTHONIOENCODING' not in os.environ:
81
+ os.environ['PYTHONIOENCODING'] = 'utf-8'
82
+
83
+ class SafeFileWriter:
84
+ """安全文件写入器"""
85
+
86
+ def __init__(self, encoding_handler: CrossPlatformEncoding):
87
+ self.encoding_handler = encoding_handler
88
+
89
+ def write_json(self, file_path: Union[str, Path], data: Dict[str, Any],
90
+ backup: bool = True, indent: int = 2) -> bool:
91
+ """安全写入JSON文件"""
92
+ file_path = Path(file_path)
93
+
94
+ try:
95
+ # 备份现有文件
96
+ if backup and file_path.exists():
97
+ backup_path = self._create_backup(file_path)
98
+ shutil.copy2(file_path, backup_path)
99
+
100
+ # 确保目录存在
101
+ file_path.parent.mkdir(parents=True, exist_ok=True)
102
+
103
+ # 使用临时文件确保原子性写入
104
+ temp_path = file_path.with_suffix('.tmp')
105
+
106
+ # 尝试多种编码
107
+ for encoding in self.encoding_handler.fallback_encodings:
108
+ try:
109
+ with open(temp_path, 'w', encoding=encoding, errors='replace') as f:
110
+ json.dump(data, f, indent=indent, ensure_ascii=False)
111
+
112
+ # 验证写入的文件
113
+ if self._verify_file(temp_path, encoding):
114
+ temp_path.replace(file_path)
115
+ return True
116
+
117
+ except (UnicodeEncodeError, UnicodeDecodeError) as e:
118
+ continue
119
+ except Exception as e:
120
+ break
121
+
122
+ # 所有编码都失败,尝试基本ASCII写入
123
+ try:
124
+ with open(temp_path, 'w', encoding='ascii', errors='replace') as f:
125
+ json.dump(data, f, indent=indent, ensure_ascii=True)
126
+ temp_path.replace(file_path)
127
+ return True
128
+
129
+ except Exception as e:
130
+ self._cleanup_temp_file(temp_path)
131
+ raise EncodingError(f"所有编码尝试都失败: {e}")
132
+
133
+ except Exception as e:
134
+ return False
135
+
136
+ def write_yaml(self, file_path: Union[str, Path], data: Dict[str, Any],
137
+ backup: bool = True) -> bool:
138
+ """安全写入YAML文件"""
139
+ file_path = Path(file_path)
140
+
141
+ try:
142
+ # 备份现有文件
143
+ if backup and file_path.exists():
144
+ backup_path = self._create_backup(file_path)
145
+ shutil.copy2(file_path, backup_path)
146
+
147
+ # 确保目录存在
148
+ file_path.parent.mkdir(parents=True, exist_ok=True)
149
+
150
+ # 使用临时文件确保原子性写入
151
+ temp_path = file_path.with_suffix('.tmp')
152
+
153
+ # 尝试多种编码
154
+ for encoding in self.encoding_handler.fallback_encodings:
155
+ try:
156
+ with open(temp_path, 'w', encoding=encoding, errors='replace') as f:
157
+ yaml.dump(data, f, default_flow_style=False,
158
+ allow_unicode=True, encoding=encoding)
159
+
160
+ # 验证写入的文件
161
+ if self._verify_file(temp_path, encoding):
162
+ temp_path.replace(file_path)
163
+ return True
164
+
165
+ except (UnicodeEncodeError, UnicodeDecodeError) as e:
166
+ continue
167
+ except Exception as e:
168
+ break
169
+
170
+ # 所有编码都失败,尝试ASCII安全模式
171
+ try:
172
+ with open(temp_path, 'w', encoding='ascii', errors='replace') as f:
173
+ yaml.dump(data, f, default_flow_style=False,
174
+ allow_unicode=False)
175
+ temp_path.replace(file_path)
176
+ return True
177
+
178
+ except Exception as e:
179
+ self._cleanup_temp_file(temp_path)
180
+ raise EncodingError(f"YAML写入失败: {e}")
181
+
182
+ except Exception as e:
183
+ return False
184
+
185
+ def copy_file(self, src: Union[str, Path], dst: Union[str, Path]) -> bool:
186
+ """安全复制文件"""
187
+ try:
188
+ src = Path(src)
189
+ dst = Path(dst)
190
+
191
+ if not src.exists():
192
+ return False
193
+
194
+ # 确保目标目录存在
195
+ dst.parent.mkdir(parents=True, exist_ok=True)
196
+
197
+ # 直接复制二进制文件,避免编码转换
198
+ shutil.copy2(src, dst)
199
+ return True
200
+
201
+ except Exception as e:
202
+ return False
203
+
204
+ def _create_backup(self, file_path: Path) -> Path:
205
+ """创建备份文件"""
206
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
207
+ backup_path = file_path.with_suffix(f'.backup_{timestamp}')
208
+ return backup_path
209
+
210
+ def _verify_file(self, file_path: Path, encoding: str) -> bool:
211
+ """验证文件是否可读"""
212
+ try:
213
+ with open(file_path, 'r', encoding=encoding) as f:
214
+ f.read(1024) # 读取前1024字符验证
215
+ return True
216
+ except:
217
+ return False
218
+
219
+ def _cleanup_temp_file(self, temp_path: Path):
220
+ """清理临时文件"""
221
+ try:
222
+ if temp_path.exists():
223
+ temp_path.unlink()
224
+ except:
225
+ pass
226
+
227
+ class SafeFileReader:
228
+ """安全文件读取器"""
229
+
230
+ def __init__(self, encoding_handler: CrossPlatformEncoding):
231
+ self.encoding_handler = encoding_handler
232
+
233
+ def read_json(self, file_path: Union[str, Path]) -> Dict[str, Any]:
234
+ """安全读取JSON文件"""
235
+ file_path = Path(file_path)
236
+
237
+ if not file_path.exists():
238
+ return {}
239
+
240
+ # 尝试多种编码
241
+ for encoding in self.encoding_handler.fallback_encodings:
242
+ try:
243
+ with open(file_path, 'r', encoding=encoding, errors='replace') as f:
244
+ return json.load(f) or {}
245
+ except (UnicodeDecodeError, json.JSONDecodeError):
246
+ continue
247
+ except Exception:
248
+ break
249
+
250
+ # 最后尝试带错误处理的读取
251
+ try:
252
+ with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
253
+ return json.load(f) or {}
254
+ except:
255
+ return {}
256
+
257
+ def read_yaml(self, file_path: Union[str, Path]) -> Dict[str, Any]:
258
+ """安全读取YAML文件"""
259
+ file_path = Path(file_path)
260
+
261
+ if not file_path.exists():
262
+ return {}
263
+
264
+ # 尝试多种编码
265
+ for encoding in self.encoding_handler.fallback_encodings:
266
+ try:
267
+ with open(file_path, 'r', encoding=encoding, errors='replace') as f:
268
+ return yaml.safe_load(f) or {}
269
+ except (UnicodeDecodeError, yaml.YAMLError):
270
+ continue
271
+ except Exception:
272
+ break
273
+
274
+ # 最后尝试带错误处理的读取
275
+ try:
276
+ with open(file_path, 'r', encoding='utf-8', errors='replace') as f:
277
+ return yaml.safe_load(f) or {}
278
+ except:
279
+ return {}
280
+
281
+ class CrossPlatformInstaller:
282
+ """跨平台安装器基类"""
283
+
284
+ def __init__(self):
285
+ self.encoding_handler = CrossPlatformEncoding()
286
+ self.writer = SafeFileWriter(self.encoding_handler)
287
+ self.reader = SafeFileReader(self.encoding_handler)
288
+
289
+ # 设置环境
290
+ self.encoding_handler.setup_environment()
291
+
292
+ def print_system_info(self):
293
+ """打印系统信息"""
294
+ print(f"[INFO] 系统信息:")
295
+ print(f" 操作系统: {self.encoding_handler.system}")
296
+ print(f" 默认编码: {self.encoding_handler.default_encoding}")
297
+ print(f" 备用编码: {', '.join(self.encoding_handler.fallback_encodings)}")
298
+ print()
299
+
300
+ def create_directory(self, dir_path: Union[str, Path]) -> bool:
301
+ """创建目录"""
302
+ try:
303
+ Path(dir_path).mkdir(parents=True, exist_ok=True)
304
+ return True
305
+ except Exception as e:
306
+ print(f"❌ 创建目录失败: {dir_path} - {e}")
307
+ return False
308
+
309
+ def copy_adapter_files(self, src_dir: Union[str, Path],
310
+ dst_dir: Union[str, Path],
311
+ file_patterns: List[str]) -> bool:
312
+ """复制适配器文件"""
313
+ success = True
314
+ src_dir = Path(src_dir)
315
+ dst_dir = Path(dst_dir)
316
+
317
+ # 确保目标目录存在
318
+ dst_dir.mkdir(parents=True, exist_ok=True)
319
+
320
+ for pattern in file_patterns:
321
+ for src_file in src_dir.glob(pattern):
322
+ dst_file = dst_dir / src_file.name
323
+ if not self.writer.copy_file(src_file, dst_file):
324
+ print(f"❌ 复制文件失败: {src_file.name}")
325
+ success = False
326
+ else:
327
+ print(f"[OK] 复制文件: {src_file.name}")
328
+
329
+ return success
330
+
331
+ # 全局实例
332
+ _encoding_installer = None
333
+
334
+ def get_cross_platform_installer() -> CrossPlatformInstaller:
335
+ """获取跨平台安装器实例"""
336
+ global _encoding_installer
337
+ if _encoding_installer is None:
338
+ _encoding_installer = CrossPlatformInstaller()
339
+ return _encoding_installer
340
+
341
+ def setup_cross_platform_encoding():
342
+ """设置跨平台编码环境"""
343
+ installer = get_cross_platform_installer()
344
+ installer.print_system_info()
345
+ return installer
346
+
347
+ # 装饰器:为函数添加编码安全
348
+ def encoding_safe(func):
349
+ """编码安全装饰器"""
350
+ def wrapper(*args, **kwargs):
351
+ # 设置编码环境
352
+ installer = get_cross_platform_installer()
353
+ installer.encoding_handler.setup_environment()
354
+
355
+ try:
356
+ return func(*args, **kwargs)
357
+ except UnicodeError as e:
358
+ print(f"❌ 编码错误: {e}")
359
+ return False
360
+ except Exception as e:
361
+ print(f"❌ 未知错误: {e}")
362
+ print(f"📋 详细错误: {traceback.format_exc()}")
363
+ return False
364
+
365
+ return wrapper