stigmergy 1.2.0 → 1.2.8
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/LICENSE +18 -18
- package/README.md +31 -211
- package/STIGMERGY.md +70 -61
- package/docs/MULTI_USER_WIKI_COLLABORATION_SYSTEM.md +523 -0
- package/docs/PROJECT_CONSTITUTION.md +433 -433
- package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
- package/docs/PROMPT_BASED_SKILLS_SYSTEM_DESIGN.md +458 -0
- package/docs/SKILL_IMPLEMENTATION_CONSTRAINTS_AND_ALIGNMENT.md +423 -0
- package/docs/TECHNICAL_FEASIBILITY_ANALYSIS.md +308 -0
- package/examples/calculator-example.js +72 -72
- package/examples/cline_usage_examples.md +364 -364
- package/examples/encryption-example.js +67 -67
- package/examples/json-parser-example.js +120 -120
- package/examples/json-validation-example.js +64 -64
- package/examples/multilingual-hook-demo.js +125 -0
- package/examples/rest-client-example.js +52 -52
- package/examples/rest_client_example.js +54 -54
- package/package.json +38 -20
- package/scripts/build.js +74 -74
- package/scripts/dependency-analyzer.js +101 -0
- package/scripts/generate-cli-docs.js +64 -0
- package/scripts/post-deployment-config.js +296 -296
- package/scripts/postuninstall.js +46 -0
- package/scripts/preinstall-check.js +173 -173
- package/scripts/preuninstall.js +75 -0
- package/scripts/publish.js +58 -268
- package/scripts/run-layered-tests.js +247 -0
- package/scripts/safe-install.js +139 -139
- package/scripts/simple-publish.js +57 -59
- package/src/adapters/claude/install_claude_integration.js +292 -0
- package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
- package/src/adapters/codex/install_codex_integration.js +395 -0
- package/src/adapters/copilot/install_copilot_integration.js +716 -0
- package/src/adapters/gemini/install_gemini_integration.js +304 -0
- package/src/adapters/iflow/install_iflow_integration.js +304 -0
- package/src/adapters/qoder/install_qoder_integration.js +1090 -0
- package/src/adapters/qwen/install_qwen_integration.js +285 -0
- package/src/cli/router.js +562 -39
- package/src/core/cache_cleaner.js +82 -59
- package/src/core/cli_help_analyzer.js +297 -291
- package/src/core/cli_parameter_handler.js +5 -0
- package/src/core/cli_tools.js +6 -6
- package/src/core/coordination/index.js +2 -2
- package/src/core/coordination/nodejs/AdapterManager.js +30 -17
- package/src/core/coordination/nodejs/CLCommunication.js +28 -20
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +72 -36
- package/src/core/coordination/nodejs/HealthChecker.js +13 -14
- package/src/core/coordination/nodejs/HookDeploymentManager.js +325 -63
- package/src/core/coordination/nodejs/StatisticsCollector.js +6 -6
- package/src/core/coordination/nodejs/index.js +29 -11
- package/src/core/coordination/nodejs/utils/Logger.js +1 -1
- package/src/core/enhanced_installer.js +92 -69
- package/src/core/enhanced_uninstaller.js +73 -53
- package/src/core/installer.js +815 -294
- package/src/core/multilingual/language-pattern-manager.js +172 -0
- package/src/core/smart_router.js +141 -26
- package/src/core/upgrade_manager.js +91 -46
- package/src/data_structures.js +1 -1
- package/src/deploy.js +2 -2
- package/src/index.js +3 -3
- package/src/test/cli-availability-checker.js +194 -0
- package/src/test/test-environment.js +289 -0
- package/src/utils/helpers.js +2 -2
- package/src/utils.js +7 -1
- package/test/multilingual/hook-deployment.test.js +91 -0
- package/test/multilingual/language-pattern-manager.test.js +140 -0
- package/test/multilingual/system-test.js +85 -0
- package/test/cache-cleaner-implemented.test.js +0 -328
- package/test/cache-cleaner.test.js +0 -390
- package/test/calculator.test.js +0 -215
- package/test/collision-test.js +0 -26
- package/test/comprehensive-enhanced-features.test.js +0 -252
- package/test/comprehensive-execution-test.js +0 -428
- package/test/conflict-prevention-test.js +0 -95
- package/test/cross-cli-detection-test.js +0 -33
- package/test/csv-processing-test.js +0 -36
- package/test/deploy-hooks-test.js +0 -250
- package/test/e2e/claude-cli-test.js +0 -128
- package/test/e2e/collaboration-test.js +0 -75
- package/test/e2e/comprehensive-test.js +0 -431
- package/test/e2e/error-handling-test.js +0 -90
- package/test/e2e/individual-tool-test.js +0 -143
- package/test/e2e/other-cli-test.js +0 -130
- package/test/e2e/qoder-cli-test.js +0 -128
- package/test/e2e/run-e2e-tests.js +0 -73
- package/test/e2e/test-data.js +0 -88
- package/test/e2e/test-utils.js +0 -222
- package/test/encryption-simple-test.js +0 -110
- package/test/encryption.test.js +0 -129
- package/test/enhanced-main-alignment.test.js +0 -298
- package/test/enhanced-uninstaller-implemented.test.js +0 -271
- package/test/enhanced-uninstaller.test.js +0 -284
- package/test/error-handling-test.js +0 -341
- package/test/fibonacci.test.js +0 -178
- package/test/final-deploy-test.js +0 -221
- package/test/final-install-test.js +0 -226
- package/test/hash-table-demo.js +0 -33
- package/test/hash-table-test.js +0 -26
- package/test/hash_table_test.js +0 -114
- package/test/hook-system-integration-test.js +0 -307
- package/test/iflow-integration-test.js +0 -292
- package/test/improved-install-test.js +0 -362
- package/test/install-command-test.js +0 -370
- package/test/json-parser-test.js +0 -161
- package/test/json-validation-test.js +0 -164
- package/test/natural-language-skills-test.js +0 -320
- package/test/nl-integration-test.js +0 -179
- package/test/parameter-parsing-test.js +0 -143
- package/test/plugin-deployment-test.js +0 -316
- package/test/postinstall-test.js +0 -269
- package/test/python-plugins-test.js +0 -259
- package/test/real-test.js +0 -435
- package/test/remaining-adapters-test.js +0 -256
- package/test/rest-client-test.js +0 -56
- package/test/rest_client.test.js +0 -85
- package/test/safe-installation-cleaner.test.js +0 -343
- package/test/simple-iflow-hook-test.js +0 -137
- package/test/stigmergy-upgrade-test.js +0 -243
- package/test/system-compatibility-test.js +0 -467
- package/test/tdd-deploy-fix-test.js +0 -324
- package/test/tdd-fixes-test.js +0 -211
- package/test/third-party-skills-test.js +0 -321
- package/test/tool-selection-integration-test.js +0 -158
- package/test/unit/calculator-full.test.js +0 -191
- package/test/unit/calculator-simple.test.js +0 -96
- package/test/unit/calculator.test.js +0 -97
- package/test/unit/cli-scanner.test.js +0 -291
- package/test/unit/cli_parameter_handler.test.js +0 -116
- package/test/unit/cross-cli-executor.test.js +0 -399
- package/test/weather-processor.test.js +0 -104
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Gemini CLI Extension集成安装脚本
|
|
5
|
+
* 为Gemini CLI安装跨CLI协作感知能力
|
|
6
|
+
*
|
|
7
|
+
* 使用方法:
|
|
8
|
+
* node install_gemini_integration.js [--verify|--uninstall]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs').promises;
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
|
|
15
|
+
// Gemini CLI配置路径
|
|
16
|
+
const GEMINI_CONFIG_DIR = path.join(os.homedir(), '.config', 'gemini');
|
|
17
|
+
const GEMINI_EXTENSIONS_FILE = path.join(GEMINI_CONFIG_DIR, 'extensions.json');
|
|
18
|
+
|
|
19
|
+
class GeminiIntegrationInstaller {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.startTime = Date.now();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 创建Gemini配置目录
|
|
26
|
+
*/
|
|
27
|
+
async createGeminiConfigDirectory() {
|
|
28
|
+
try {
|
|
29
|
+
await fs.mkdir(GEMINI_CONFIG_DIR, { recursive: true });
|
|
30
|
+
console.log(`[OK] 创建Gemini配置目录: ${GEMINI_CONFIG_DIR}`);
|
|
31
|
+
return true;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.log(`[ERROR] 创建Gemini配置目录失败: ${error.message}`);
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 安装Gemini Extension配置
|
|
40
|
+
*/
|
|
41
|
+
async installGeminiExtensions() {
|
|
42
|
+
try {
|
|
43
|
+
// 读取现有extensions配置
|
|
44
|
+
let existingExtensions = {};
|
|
45
|
+
try {
|
|
46
|
+
const data = await fs.readFile(GEMINI_EXTENSIONS_FILE, 'utf8');
|
|
47
|
+
existingExtensions = JSON.parse(data);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.log(`[WARN] 读取现有extensions配置失败: ${error.message}`);
|
|
50
|
+
existingExtensions = {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 定义跨CLI协作的Extension配置
|
|
54
|
+
const crossCliExtensions = {
|
|
55
|
+
cross_cli_preprocessor: {
|
|
56
|
+
module: 'src.adapters.gemini.extension_adapter',
|
|
57
|
+
class: 'GeminiExtensionAdapter',
|
|
58
|
+
enabled: true,
|
|
59
|
+
priority: 100,
|
|
60
|
+
config: {
|
|
61
|
+
cross_cli_enabled: true,
|
|
62
|
+
supported_clis: ['claude', 'qwen', 'iflow', 'qoder', 'codebuddy', 'copilot'],
|
|
63
|
+
auto_detect: true,
|
|
64
|
+
timeout: 30,
|
|
65
|
+
error_handling: 'continue',
|
|
66
|
+
collaboration_mode: 'active'
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
cross_cli_response_processor: {
|
|
70
|
+
module: 'src.adapters.gemini.extension_adapter',
|
|
71
|
+
class: 'GeminiExtensionAdapter',
|
|
72
|
+
enabled: true,
|
|
73
|
+
priority: 90,
|
|
74
|
+
config: {
|
|
75
|
+
cross_cli_enabled: true,
|
|
76
|
+
format_cross_cli_results: true,
|
|
77
|
+
add_collaboration_header: true,
|
|
78
|
+
include_tool_status: true
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// 合并配置(保留现有配置,添加协作功能)
|
|
84
|
+
const mergedExtensions = { ...existingExtensions, ...crossCliExtensions };
|
|
85
|
+
|
|
86
|
+
// 写入extensions配置文件
|
|
87
|
+
await fs.writeFile(GEMINI_EXTENSIONS_FILE, JSON.stringify(mergedExtensions, null, 2), 'utf8');
|
|
88
|
+
|
|
89
|
+
console.log(`[OK] Gemini Extension配置已安装: ${GEMINI_EXTENSIONS_FILE}`);
|
|
90
|
+
console.log('已安装的Extension:');
|
|
91
|
+
Object.keys(crossCliExtensions).forEach(extName => {
|
|
92
|
+
console.log(` - ${extName}: [OK] 跨CLI协作感知`);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return true;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.log(`[ERROR] 安装Gemini Extension配置失败: ${error.message}`);
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* 复制适配器文件到Gemini配置目录
|
|
104
|
+
*/
|
|
105
|
+
async copyAdapterFile() {
|
|
106
|
+
try {
|
|
107
|
+
// 创建适配器目录
|
|
108
|
+
const adapterDir = path.join(GEMINI_CONFIG_DIR, 'adapters');
|
|
109
|
+
await fs.mkdir(adapterDir, { recursive: true });
|
|
110
|
+
|
|
111
|
+
// 获取当前脚本目录
|
|
112
|
+
const currentDir = __dirname;
|
|
113
|
+
const adapterSource = path.join(currentDir, 'extension_adapter.js');
|
|
114
|
+
const adapterDest = path.join(adapterDir, 'extension_adapter.js');
|
|
115
|
+
|
|
116
|
+
// 复制适配器文件
|
|
117
|
+
try {
|
|
118
|
+
await fs.access(adapterSource);
|
|
119
|
+
await fs.copyFile(adapterSource, adapterDest);
|
|
120
|
+
console.log(`[OK] 复制适配器文件: ${adapterDest}`);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.log(`[WARN] 适配器源文件不存在: ${adapterSource}`);
|
|
123
|
+
// 不强制要求适配器文件
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return true;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(`[WARN] 复制适配器文件失败: ${error.message}`);
|
|
129
|
+
return true; // 不强制要求适配器文件
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 验证安装
|
|
135
|
+
*/
|
|
136
|
+
async verifyInstallation() {
|
|
137
|
+
const checks = [
|
|
138
|
+
{ name: 'Gemini配置目录', path: GEMINI_CONFIG_DIR },
|
|
139
|
+
{ name: 'Gemini Extensions文件', path: GEMINI_EXTENSIONS_FILE }
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
let allPassed = true;
|
|
143
|
+
for (const check of checks) {
|
|
144
|
+
try {
|
|
145
|
+
await fs.access(check.path);
|
|
146
|
+
console.log(`[OK] ${check.name}`);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.log(`[FAIL] ${check.name}`);
|
|
149
|
+
allPassed = false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return allPassed;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 卸载集成
|
|
158
|
+
*/
|
|
159
|
+
async uninstallIntegration() {
|
|
160
|
+
try {
|
|
161
|
+
// 删除extensions配置中的跨CLI适配器
|
|
162
|
+
try {
|
|
163
|
+
const data = await fs.readFile(GEMINI_EXTENSIONS_FILE, 'utf8');
|
|
164
|
+
const extensionsConfig = JSON.parse(data);
|
|
165
|
+
|
|
166
|
+
// 移除跨CLI适配器
|
|
167
|
+
const extensionsToRemove = ['cross_cli_preprocessor', 'cross_cli_response_processor'];
|
|
168
|
+
let removedCount = 0;
|
|
169
|
+
|
|
170
|
+
extensionsToRemove.forEach(extName => {
|
|
171
|
+
if (extName in extensionsConfig) {
|
|
172
|
+
delete extensionsConfig[extName];
|
|
173
|
+
removedCount++;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// 保存更新后的配置
|
|
178
|
+
if (removedCount > 0) {
|
|
179
|
+
await fs.writeFile(GEMINI_EXTENSIONS_FILE, JSON.stringify(extensionsConfig, null, 2), 'utf8');
|
|
180
|
+
console.log(`[OK] 已从Gemini Extensions配置中移除${removedCount}个跨CLI适配器`);
|
|
181
|
+
}
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.log(`[WARN] 处理extensions配置失败: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 删除适配器文件
|
|
187
|
+
try {
|
|
188
|
+
const adapterFile = path.join(GEMINI_CONFIG_DIR, 'adapters', 'extension_adapter.js');
|
|
189
|
+
await fs.unlink(adapterFile);
|
|
190
|
+
console.log('[OK] 已删除Gemini适配器文件');
|
|
191
|
+
} catch (error) {
|
|
192
|
+
// 文件可能不存在,忽略错误
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log('[OK] Gemini CLI跨CLI集成已卸载');
|
|
196
|
+
return true;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.log(`[ERROR] 卸载失败: ${error.message}`);
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 创建Cross-CLI通信指南
|
|
205
|
+
*/
|
|
206
|
+
async createCrossCliGuide() {
|
|
207
|
+
try {
|
|
208
|
+
const guideContent = `# Gemini CLI Cross-CLI Communication Guide
|
|
209
|
+
|
|
210
|
+
## Cross-CLI Communication
|
|
211
|
+
When you need to call other AI tools, please use the following prompt <<<Execute the following command in shell: stigmergy <tool_name> <task_description>>>>
|
|
212
|
+
|
|
213
|
+
Examples:
|
|
214
|
+
- Run in shell: stigmergy claude "write a Python function"
|
|
215
|
+
- Run in shell: stigmergy qwen "translate this text"
|
|
216
|
+
- Run in shell: stigmergy iflow "analyze this code"
|
|
217
|
+
|
|
218
|
+
Available tools: claude, gemini, qwen, iflow, qodercli, codebuddy, copilot, codex
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
*This document is automatically generated and maintained by Stigmergy CLI*
|
|
222
|
+
`;
|
|
223
|
+
|
|
224
|
+
const guidePath = path.join(GEMINI_CONFIG_DIR, 'CROSS_CLI_GUIDE.md');
|
|
225
|
+
await fs.writeFile(guidePath, guideContent, 'utf8');
|
|
226
|
+
console.log(`[OK] 创建Cross-CLI通信指南: ${guidePath}`);
|
|
227
|
+
return true;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
console.log(`[WARN] 创建Cross-CLI通信指南失败: ${error.message}`);
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 主安装流程
|
|
236
|
+
*/
|
|
237
|
+
async install() {
|
|
238
|
+
console.log('Gemini CLI跨CLI集成安装程序');
|
|
239
|
+
console.log('='.repeat(50));
|
|
240
|
+
|
|
241
|
+
// 步骤1. 创建配置目录
|
|
242
|
+
console.log('\n步骤1. 创建配置目录...');
|
|
243
|
+
const configDirSuccess = await this.createGeminiConfigDirectory();
|
|
244
|
+
|
|
245
|
+
// 步骤2. 安装Extension配置
|
|
246
|
+
console.log('\n步骤2. 安装Extension配置...');
|
|
247
|
+
const extensionsSuccess = await this.installGeminiExtensions();
|
|
248
|
+
|
|
249
|
+
// 步骤3. 复制适配器文件
|
|
250
|
+
console.log('\n步骤3. 复制适配器文件...');
|
|
251
|
+
const adapterSuccess = await this.copyAdapterFile();
|
|
252
|
+
|
|
253
|
+
// 步骤4. 创建Cross-CLI通信指南
|
|
254
|
+
console.log('\n步骤4. 创建Cross-CLI通信指南...');
|
|
255
|
+
const guideSuccess = await this.createCrossCliGuide();
|
|
256
|
+
|
|
257
|
+
// 步骤5. 验证安装
|
|
258
|
+
console.log('\n步骤5. 验证安装...');
|
|
259
|
+
const verificationSuccess = await this.verifyInstallation();
|
|
260
|
+
|
|
261
|
+
const overallSuccess = configDirSuccess && extensionsSuccess && adapterSuccess && guideSuccess && verificationSuccess;
|
|
262
|
+
|
|
263
|
+
const duration = Date.now() - this.startTime;
|
|
264
|
+
console.log(`\n[INFO] 安装耗时: ${duration}ms`);
|
|
265
|
+
|
|
266
|
+
if (overallSuccess) {
|
|
267
|
+
console.log('\n[SUCCESS] Gemini CLI跨CLI集成安装成功!');
|
|
268
|
+
} else {
|
|
269
|
+
console.log('\n[WARNING] 安装过程中出现警告,请检查上述输出');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return overallSuccess;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 主函数
|
|
277
|
+
async function main() {
|
|
278
|
+
const args = process.argv.slice(2);
|
|
279
|
+
const verify = args.includes('--verify');
|
|
280
|
+
const uninstall = args.includes('--uninstall');
|
|
281
|
+
|
|
282
|
+
const installer = new GeminiIntegrationInstaller();
|
|
283
|
+
|
|
284
|
+
if (uninstall) {
|
|
285
|
+
return await installer.uninstallIntegration();
|
|
286
|
+
} else if (verify) {
|
|
287
|
+
return await installer.verifyInstallation();
|
|
288
|
+
} else {
|
|
289
|
+
return await installer.install();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 导出模块
|
|
294
|
+
module.exports = GeminiIntegrationInstaller;
|
|
295
|
+
|
|
296
|
+
// 如果直接运行此脚本
|
|
297
|
+
if (require.main === module) {
|
|
298
|
+
main().then(success => {
|
|
299
|
+
process.exit(success ? 0 : 1);
|
|
300
|
+
}).catch(error => {
|
|
301
|
+
console.error('[FATAL]', error.message);
|
|
302
|
+
process.exit(1);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* iFlow CLI Hook适配器安装脚本
|
|
5
|
+
* 为iFlow CLI安装跨CLI协作感知能力
|
|
6
|
+
*
|
|
7
|
+
* 使用方法:
|
|
8
|
+
* node install_iflow_integration.js [--verify|--uninstall]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs').promises;
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const yaml = require('js-yaml');
|
|
15
|
+
|
|
16
|
+
// iFlow CLI配置路径
|
|
17
|
+
const IFLOW_CONFIG_DIR = path.join(os.homedir(), '.config', 'iflow');
|
|
18
|
+
const IFLOW_HOOKS_FILE = path.join(IFLOW_CONFIG_DIR, 'hooks.yml');
|
|
19
|
+
|
|
20
|
+
class IFlowIntegrationInstaller {
|
|
21
|
+
constructor() {
|
|
22
|
+
this.startTime = Date.now();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 创建iFlow配置目录
|
|
27
|
+
*/
|
|
28
|
+
async createIFlowConfigDirectory() {
|
|
29
|
+
try {
|
|
30
|
+
await fs.mkdir(IFLOW_CONFIG_DIR, { recursive: true });
|
|
31
|
+
console.log(`[OK] 创建iFlow配置目录: ${IFLOW_CONFIG_DIR}`);
|
|
32
|
+
return true;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.log(`[ERROR] 创建iFlow配置目录失败: ${error.message}`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 安装iFlow Hook配置
|
|
41
|
+
*/
|
|
42
|
+
async installIFlowHooks() {
|
|
43
|
+
try {
|
|
44
|
+
// 读取现有hooks配置
|
|
45
|
+
let existingHooks = {};
|
|
46
|
+
try {
|
|
47
|
+
const data = await fs.readFile(IFLOW_HOOKS_FILE, 'utf8');
|
|
48
|
+
existingHooks = yaml.load(data) || {};
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.log(`[WARN] 读取现有hooks配置失败: ${error.message}`);
|
|
51
|
+
existingHooks = {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 定义跨CLI协作的Hook配置
|
|
55
|
+
const crossCliHooks = {
|
|
56
|
+
cross_cli_adapter: {
|
|
57
|
+
module: 'src.adapters.iflow.hook_adapter',
|
|
58
|
+
class: 'IFlowHookAdapter',
|
|
59
|
+
enabled: true,
|
|
60
|
+
priority: 100,
|
|
61
|
+
events: ['workflow_start', 'task_execute', 'pipeline_complete', 'user_input']
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// 合并配置(保留现有配置,添加协作功能)
|
|
66
|
+
const mergedHooks = { ...existingHooks, ...crossCliHooks };
|
|
67
|
+
|
|
68
|
+
// 写入hooks配置文件
|
|
69
|
+
const yamlContent = yaml.dump(mergedHooks, { indent: 2, lineWidth: 120, noRefs: true });
|
|
70
|
+
await fs.writeFile(IFLOW_HOOKS_FILE, yamlContent, 'utf8');
|
|
71
|
+
|
|
72
|
+
console.log(`[OK] iFlow Hook配置已安装: ${IFLOW_HOOKS_FILE}`);
|
|
73
|
+
console.log('已安装的Hook:');
|
|
74
|
+
Object.keys(crossCliHooks).forEach(hookName => {
|
|
75
|
+
console.log(` - ${hookName}: [OK] 跨CLI协作感知`);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return true;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.log(`[ERROR] 安装iFlow Hook配置失败: ${error.message}`);
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 复制适配器文件到iFlow配置目录
|
|
87
|
+
*/
|
|
88
|
+
async copyAdapterFile() {
|
|
89
|
+
try {
|
|
90
|
+
// 创建适配器目录
|
|
91
|
+
const adapterDir = path.join(IFLOW_CONFIG_DIR, 'adapters');
|
|
92
|
+
await fs.mkdir(adapterDir, { recursive: true });
|
|
93
|
+
|
|
94
|
+
// 获取当前脚本目录
|
|
95
|
+
const currentDir = __dirname;
|
|
96
|
+
const adapterSource = path.join(currentDir, 'hook_adapter.js');
|
|
97
|
+
const adapterDest = path.join(adapterDir, 'hook_adapter.js');
|
|
98
|
+
|
|
99
|
+
// 复制适配器文件
|
|
100
|
+
try {
|
|
101
|
+
await fs.access(adapterSource);
|
|
102
|
+
await fs.copyFile(adapterSource, adapterDest);
|
|
103
|
+
console.log(`[OK] 复制适配器文件: ${adapterDest}`);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.log(`[ERROR] 适配器源文件不存在: ${adapterSource}`);
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 创建全局Cross-CLI文档
|
|
110
|
+
await this.createGlobalCrossCliDocumentation(IFLOW_CONFIG_DIR);
|
|
111
|
+
|
|
112
|
+
return true;
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.log(`[ERROR] 复制适配器文件失败: ${error.message}`);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 创建全局Cross-CLI通信文档
|
|
121
|
+
*/
|
|
122
|
+
async createGlobalCrossCliDocumentation(configDir) {
|
|
123
|
+
try {
|
|
124
|
+
const docContent = `# iFlow CLI 跨CLI通信指南
|
|
125
|
+
|
|
126
|
+
## Cross-CLI Communication
|
|
127
|
+
当您需要调用其他AI工具时,请使用以下提示<<<在shell中执行以下命令:stigmergy <工具名> <任务描述>>>>
|
|
128
|
+
|
|
129
|
+
示例:
|
|
130
|
+
- 在shell中运行:stigmergy claude "写一个Python函数"
|
|
131
|
+
- 在shell中运行:stigmergy gemini "翻译这段文字"
|
|
132
|
+
- 在shell中运行:stigmergy qwen "分析这段代码"
|
|
133
|
+
|
|
134
|
+
可用工具:claude, gemini, qwen, iflow, qodercli, codebuddy, copilot, codex
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
*本文档由Stigmergy CLI自动生成和维护*
|
|
138
|
+
`;
|
|
139
|
+
|
|
140
|
+
const docPath = path.join(configDir, 'CROSS_CLI_GUIDE.md');
|
|
141
|
+
await fs.writeFile(docPath, docContent, 'utf8');
|
|
142
|
+
console.log(`[OK] 创建Cross-CLI通信指南: ${docPath}`);
|
|
143
|
+
|
|
144
|
+
// 如果存在iflow.md文件,则在末尾追加Cross-CLI通信提示
|
|
145
|
+
const iflowMdPath = path.join(os.homedir(), '.iflow', 'iflow.md');
|
|
146
|
+
try {
|
|
147
|
+
await fs.access(iflowMdPath);
|
|
148
|
+
|
|
149
|
+
const crossCliContent = `
|
|
150
|
+
|
|
151
|
+
## Cross-CLI Communication
|
|
152
|
+
当您需要调用其他AI工具时,请使用以下提示<<<在shell中执行以下命令:stigmergy <工具名> <任务描述>>>>
|
|
153
|
+
|
|
154
|
+
示例:
|
|
155
|
+
- 在shell中运行:stigmergy claude "写一个Python函数"
|
|
156
|
+
- 在shell中运行:stigmergy gemini "翻译这段文字"
|
|
157
|
+
- 在shell中运行:stigmergy qwen "分析这段代码"
|
|
158
|
+
|
|
159
|
+
可用工具:claude, gemini, qwen, iflow, qodercli, codebuddy, copilot, codex
|
|
160
|
+
`;
|
|
161
|
+
await fs.appendFile(iflowMdPath, crossCliContent, 'utf8');
|
|
162
|
+
console.log('[OK] 在IFLOW.md末尾追加Cross-CLI通信提示');
|
|
163
|
+
} catch (error) {
|
|
164
|
+
// 文件可能不存在,忽略
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return true;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.log(`[WARN] 创建Cross-CLI通信指南失败: ${error.message}`);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* 验证安装
|
|
176
|
+
*/
|
|
177
|
+
async verifyInstallation() {
|
|
178
|
+
const checks = [
|
|
179
|
+
{ name: 'iFlow配置目录', path: IFLOW_CONFIG_DIR },
|
|
180
|
+
{ name: 'iFlow Hooks文件', path: IFLOW_HOOKS_FILE }
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
let allPassed = true;
|
|
184
|
+
for (const check of checks) {
|
|
185
|
+
try {
|
|
186
|
+
await fs.access(check.path);
|
|
187
|
+
console.log(`[OK] ${check.name}`);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.log(`[FAIL] ${check.name}`);
|
|
190
|
+
allPassed = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return allPassed;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* 卸载集成
|
|
199
|
+
*/
|
|
200
|
+
async uninstallIntegration() {
|
|
201
|
+
try {
|
|
202
|
+
// 删除hooks配置中的跨CLI适配器
|
|
203
|
+
try {
|
|
204
|
+
const data = await fs.readFile(IFLOW_HOOKS_FILE, 'utf8');
|
|
205
|
+
const hooksConfig = yaml.load(data) || {};
|
|
206
|
+
|
|
207
|
+
// 移除跨CLI适配器
|
|
208
|
+
if ('cross_cli_adapter' in hooksConfig) {
|
|
209
|
+
delete hooksConfig['cross_cli_adapter'];
|
|
210
|
+
|
|
211
|
+
// 保存更新后的配置
|
|
212
|
+
const yamlContent = yaml.dump(hooksConfig, { indent: 2, lineWidth: 120, noRefs: true });
|
|
213
|
+
await fs.writeFile(IFLOW_HOOKS_FILE, yamlContent, 'utf8');
|
|
214
|
+
|
|
215
|
+
console.log('[OK] 已从iFlow Hooks配置中移除跨CLI适配器');
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.log(`[WARN] 处理hooks配置失败: ${error.message}`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// 删除适配器文件
|
|
222
|
+
try {
|
|
223
|
+
const adapterFile = path.join(IFLOW_CONFIG_DIR, 'adapters', 'hook_adapter.js');
|
|
224
|
+
await fs.unlink(adapterFile);
|
|
225
|
+
console.log('[OK] 已删除iFlow适配器文件');
|
|
226
|
+
} catch (error) {
|
|
227
|
+
// 文件可能不存在,忽略错误
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
console.log('[OK] iFlow CLI跨CLI集成已卸载');
|
|
231
|
+
return true;
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.log(`[ERROR] 卸载失败: ${error.message}`);
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* 主安装流程
|
|
240
|
+
*/
|
|
241
|
+
async install() {
|
|
242
|
+
console.log('iFlow CLI跨CLI集成安装程序');
|
|
243
|
+
console.log('='.repeat(50));
|
|
244
|
+
|
|
245
|
+
// 步骤1. 创建配置目录
|
|
246
|
+
console.log('\n步骤1. 创建配置目录...');
|
|
247
|
+
const configDirSuccess = await this.createIFlowConfigDirectory();
|
|
248
|
+
|
|
249
|
+
// 步骤2. 安装Hook配置
|
|
250
|
+
console.log('\n步骤2. 安装Hook配置...');
|
|
251
|
+
const hooksSuccess = await this.installIFlowHooks();
|
|
252
|
+
|
|
253
|
+
// 步骤3. 复制适配器文件
|
|
254
|
+
console.log('\n步骤3. 复制适配器文件...');
|
|
255
|
+
const adapterSuccess = await this.copyAdapterFile();
|
|
256
|
+
|
|
257
|
+
// 步骤4. 验证安装
|
|
258
|
+
console.log('\n步骤4. 验证安装...');
|
|
259
|
+
const verificationSuccess = await this.verifyInstallation();
|
|
260
|
+
|
|
261
|
+
const overallSuccess = configDirSuccess && hooksSuccess && adapterSuccess && verificationSuccess;
|
|
262
|
+
|
|
263
|
+
const duration = Date.now() - this.startTime;
|
|
264
|
+
console.log(`\n[INFO] 安装耗时: ${duration}ms`);
|
|
265
|
+
|
|
266
|
+
if (overallSuccess) {
|
|
267
|
+
console.log('\n[SUCCESS] iFlow CLI跨CLI集成安装成功!');
|
|
268
|
+
} else {
|
|
269
|
+
console.log('\n[WARNING] 安装过程中出现警告,请检查上述输出');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return overallSuccess;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 主函数
|
|
277
|
+
async function main() {
|
|
278
|
+
const args = process.argv.slice(2);
|
|
279
|
+
const verify = args.includes('--verify');
|
|
280
|
+
const uninstall = args.includes('--uninstall');
|
|
281
|
+
|
|
282
|
+
const installer = new IFlowIntegrationInstaller();
|
|
283
|
+
|
|
284
|
+
if (uninstall) {
|
|
285
|
+
return await installer.uninstallIntegration();
|
|
286
|
+
} else if (verify) {
|
|
287
|
+
return await installer.verifyInstallation();
|
|
288
|
+
} else {
|
|
289
|
+
return await installer.install();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 导出模块
|
|
294
|
+
module.exports = IFlowIntegrationInstaller;
|
|
295
|
+
|
|
296
|
+
// 如果直接运行此脚本
|
|
297
|
+
if (require.main === module) {
|
|
298
|
+
main().then(success => {
|
|
299
|
+
process.exit(success ? 0 : 1);
|
|
300
|
+
}).catch(error => {
|
|
301
|
+
console.error('[FATAL]', error.message);
|
|
302
|
+
process.exit(1);
|
|
303
|
+
});
|
|
304
|
+
}
|