@iflow-ai/iflow-cli 0.4.16-beta-20260107164003 → 0.4.16
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/bundle/entry.js +57 -57
- package/bundle/iflow-cli-vscode-ide-companion-0.2.9.vsix +0 -0
- package/bundle/iflow.js +1619 -2100
- package/package.json +1 -6
- package/scripts/postinstall-idea-plugin.js +63 -88
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iflow-ai/iflow-cli",
|
|
3
|
-
"version": "0.4.16
|
|
3
|
+
"version": "0.4.16",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.0.0"
|
|
6
6
|
},
|
|
@@ -63,7 +63,6 @@
|
|
|
63
63
|
"LICENSE"
|
|
64
64
|
],
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@types/jsdom": "^27.0.0",
|
|
67
66
|
"@types/marked": "^5.0.2",
|
|
68
67
|
"@types/micromatch": "^4.0.9",
|
|
69
68
|
"@types/mime-types": "^3.0.1",
|
|
@@ -119,11 +118,7 @@
|
|
|
119
118
|
"access": "public"
|
|
120
119
|
},
|
|
121
120
|
"dependencies": {
|
|
122
|
-
"asciify-image": "^0.1.10",
|
|
123
|
-
"gifuct-js": "^2.1.2",
|
|
124
121
|
"ink": "^6.5.0",
|
|
125
|
-
"ink-picture": "^1.3.3",
|
|
126
|
-
"is-unicode-supported": "^2.1.0",
|
|
127
122
|
"react-devtools-core": "^6.1.5",
|
|
128
123
|
"shell-quote": "^1.8.3"
|
|
129
124
|
}
|
|
@@ -4,17 +4,8 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
mkdirSync,
|
|
10
|
-
createWriteStream,
|
|
11
|
-
statSync,
|
|
12
|
-
readdirSync,
|
|
13
|
-
createReadStream,
|
|
14
|
-
unlinkSync,
|
|
15
|
-
rmSync,
|
|
16
|
-
} from 'fs';
|
|
17
|
-
import { join } from 'path';
|
|
7
|
+
import { existsSync, mkdirSync, createWriteStream, statSync, readdirSync, createReadStream, unlinkSync, rmSync } from 'fs';
|
|
8
|
+
import { join, dirname, resolve } from 'path';
|
|
18
9
|
import { fileURLToPath } from 'url';
|
|
19
10
|
import os from 'os';
|
|
20
11
|
import https from 'https';
|
|
@@ -24,29 +15,48 @@ import { pipeline } from 'stream/promises';
|
|
|
24
15
|
import { Extract } from 'unzipper';
|
|
25
16
|
|
|
26
17
|
// 常量定义
|
|
27
|
-
const PLUGIN_URL =
|
|
28
|
-
'https://cloud.iflow.cn/iflow-cli/idea-plugin/iflow-idea-0.0.5.zip';
|
|
18
|
+
const PLUGIN_URL = 'https://cloud.iflow.cn/iflow-cli/idea-plugin/iflow-idea-0.0.3.zip';
|
|
29
19
|
const PLUGIN_DIR_NAME = 'iflow-idea';
|
|
30
20
|
const TEMP_DIR_NAME = 'tstar-cli-idea-plugin';
|
|
31
21
|
const LOG_PREFIX = '[JetBrains Extension]';
|
|
32
22
|
// 扩展支持的JetBrains IDE产品
|
|
33
23
|
const IDE_PATTERNS = [
|
|
34
|
-
'IntelliJIdea',
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
40
|
-
'
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
'Rider', // Rider
|
|
45
|
-
'AndroidStudio', // Android Studio
|
|
24
|
+
'IntelliJIdea', 'IdeaIC', // IntelliJ IDEA
|
|
25
|
+
'PyCharm', 'PyCharmCE', // PyCharm
|
|
26
|
+
'GoLand', // GoLand
|
|
27
|
+
'WebStorm', // WebStorm
|
|
28
|
+
'PhpStorm', // PhpStorm
|
|
29
|
+
'CLion', // CLion
|
|
30
|
+
'RubyMine', // RubyMine
|
|
31
|
+
'DataGrip', // DataGrip
|
|
32
|
+
'Rider', // Rider
|
|
33
|
+
'AndroidStudio' // Android Studio
|
|
46
34
|
];
|
|
47
35
|
|
|
48
36
|
// 获取当前脚本的目录
|
|
49
37
|
const __filename = fileURLToPath(import.meta.url);
|
|
38
|
+
const __dirname = dirname(__filename);
|
|
39
|
+
|
|
40
|
+
// 验证路径是否安全
|
|
41
|
+
function validatePath(path) {
|
|
42
|
+
if (!path || typeof path !== 'string') {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 防止路径遍历攻击
|
|
47
|
+
const normalizedPath = resolve(path);
|
|
48
|
+
return !normalizedPath.includes('..');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 检查文件是否存在且可执行
|
|
52
|
+
function isExecutable(filePath) {
|
|
53
|
+
try {
|
|
54
|
+
const stats = statSync(filePath);
|
|
55
|
+
return stats.isFile() && (stats.mode & parseInt('111', 8)) !== 0;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
50
60
|
|
|
51
61
|
// 获取 JetBrains IDE 插件目录的跨平台函数
|
|
52
62
|
function getJetBrainsPluginsDirectory() {
|
|
@@ -77,17 +87,14 @@ function findLatestJetBrainsDirectories() {
|
|
|
77
87
|
try {
|
|
78
88
|
// 获取所有匹配的IDE目录,并按修改时间排序
|
|
79
89
|
const dirs = readdirSync(jetbrainsDir)
|
|
80
|
-
.filter(
|
|
81
|
-
.map(
|
|
90
|
+
.filter(dir => IDE_PATTERNS.some(pattern => dir.startsWith(pattern)))
|
|
91
|
+
.map(dir => {
|
|
82
92
|
const fullPath = join(jetbrainsDir, dir);
|
|
83
93
|
try {
|
|
84
94
|
const stats = statSync(fullPath);
|
|
85
95
|
return { path: fullPath, mtime: stats.mtime, name: dir };
|
|
86
96
|
} catch (error) {
|
|
87
|
-
console.warn(
|
|
88
|
-
`${LOG_PREFIX} Cannot access directory ${fullPath}:`,
|
|
89
|
-
error.message,
|
|
90
|
-
);
|
|
97
|
+
console.warn(`${LOG_PREFIX} Cannot access directory ${fullPath}:`, error.message);
|
|
91
98
|
return null;
|
|
92
99
|
}
|
|
93
100
|
})
|
|
@@ -101,10 +108,8 @@ function findLatestJetBrainsDirectories() {
|
|
|
101
108
|
|
|
102
109
|
// 按IDE类型分组,每种IDE只保留最新版本
|
|
103
110
|
const latestByType = {};
|
|
104
|
-
dirs.forEach(
|
|
105
|
-
const ideType = IDE_PATTERNS.find((pattern)
|
|
106
|
-
dir.name.startsWith(pattern),
|
|
107
|
-
);
|
|
111
|
+
dirs.forEach(dir => {
|
|
112
|
+
const ideType = IDE_PATTERNS.find(pattern => dir.name.startsWith(pattern));
|
|
108
113
|
if (ideType && !latestByType[ideType]) {
|
|
109
114
|
latestByType[ideType] = dir;
|
|
110
115
|
}
|
|
@@ -112,10 +117,7 @@ function findLatestJetBrainsDirectories() {
|
|
|
112
117
|
|
|
113
118
|
return Object.values(latestByType);
|
|
114
119
|
} catch (error) {
|
|
115
|
-
console.error(
|
|
116
|
-
`${LOG_PREFIX} Error finding JetBrains IDE directories:`,
|
|
117
|
-
error.message,
|
|
118
|
-
);
|
|
120
|
+
console.error(`${LOG_PREFIX} Error finding JetBrains IDE directories:`, error.message);
|
|
119
121
|
return [];
|
|
120
122
|
}
|
|
121
123
|
}
|
|
@@ -128,22 +130,18 @@ async function downloadPlugin(url, destPath) {
|
|
|
128
130
|
// 根据URL协议选择适当的模块
|
|
129
131
|
const protocol = url.startsWith('https:') ? https : http;
|
|
130
132
|
|
|
131
|
-
protocol
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
133
|
+
protocol.get(url, (response) => {
|
|
134
|
+
if (response.statusCode !== 200) {
|
|
135
|
+
reject(new Error(`Failed to download plugin: ${response.statusCode}`));
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
});
|
|
139
|
+
pipeline(response, file)
|
|
140
|
+
.then(() => resolve())
|
|
141
|
+
.catch(reject);
|
|
142
|
+
}).on('error', (err) => {
|
|
143
|
+
reject(err);
|
|
144
|
+
});
|
|
147
145
|
});
|
|
148
146
|
}
|
|
149
147
|
|
|
@@ -179,9 +177,7 @@ async function installJetBrainsExtension() {
|
|
|
179
177
|
// 查找所有支持的 JetBrains IDE 目录
|
|
180
178
|
const ideDirs = findLatestJetBrainsDirectories();
|
|
181
179
|
if (ideDirs.length === 0) {
|
|
182
|
-
console.warn(
|
|
183
|
-
`${LOG_PREFIX} Could not find any JetBrains IDE installation, skipping plugin installation`,
|
|
184
|
-
);
|
|
180
|
+
console.warn(`${LOG_PREFIX} Could not find any JetBrains IDE installation, skipping plugin installation`);
|
|
185
181
|
return;
|
|
186
182
|
}
|
|
187
183
|
|
|
@@ -191,10 +187,7 @@ async function installJetBrainsExtension() {
|
|
|
191
187
|
try {
|
|
192
188
|
mkdirSync(tempDir, { recursive: true });
|
|
193
189
|
} catch (error) {
|
|
194
|
-
console.error(
|
|
195
|
-
`${LOG_PREFIX} Failed to create temporary directory: ${tempDir}`,
|
|
196
|
-
error.message,
|
|
197
|
-
);
|
|
190
|
+
console.error(`${LOG_PREFIX} Failed to create temporary directory: ${tempDir}`, error.message);
|
|
198
191
|
return;
|
|
199
192
|
}
|
|
200
193
|
}
|
|
@@ -224,10 +217,7 @@ async function installJetBrainsExtension() {
|
|
|
224
217
|
try {
|
|
225
218
|
mkdirSync(pluginsDir, { recursive: true });
|
|
226
219
|
} catch (error) {
|
|
227
|
-
console.error(
|
|
228
|
-
`${LOG_PREFIX} Failed to create plugins directory: ${pluginsDir}`,
|
|
229
|
-
error.message,
|
|
230
|
-
);
|
|
220
|
+
console.error(`${LOG_PREFIX} Failed to create plugins directory: ${pluginsDir}`, error.message);
|
|
231
221
|
continue; // 跳过此IDE,继续下一个
|
|
232
222
|
}
|
|
233
223
|
}
|
|
@@ -236,15 +226,10 @@ async function installJetBrainsExtension() {
|
|
|
236
226
|
const existingPluginDir = join(pluginsDir, PLUGIN_DIR_NAME);
|
|
237
227
|
if (existsSync(existingPluginDir)) {
|
|
238
228
|
try {
|
|
239
|
-
console.info(
|
|
240
|
-
`${LOG_PREFIX} Removing existing plugin directory: ${existingPluginDir}`,
|
|
241
|
-
);
|
|
229
|
+
console.info(`${LOG_PREFIX} Removing existing plugin directory: ${existingPluginDir}`);
|
|
242
230
|
rmSync(existingPluginDir, { recursive: true, force: true });
|
|
243
231
|
} catch (error) {
|
|
244
|
-
console.error(
|
|
245
|
-
`${LOG_PREFIX} Failed to remove existing plugin directory: ${existingPluginDir}`,
|
|
246
|
-
error.message,
|
|
247
|
-
);
|
|
232
|
+
console.error(`${LOG_PREFIX} Failed to remove existing plugin directory: ${existingPluginDir}`, error.message);
|
|
248
233
|
// 继续安装,即使删除失败
|
|
249
234
|
}
|
|
250
235
|
}
|
|
@@ -255,14 +240,9 @@ async function installJetBrainsExtension() {
|
|
|
255
240
|
try {
|
|
256
241
|
// 直接解压到插件目录,不创建额外的子目录
|
|
257
242
|
await extractPlugin(pluginFilePath, pluginsDir);
|
|
258
|
-
console.info(
|
|
259
|
-
`${LOG_PREFIX} ✔ Plugin installed successfully to: ${pluginsDir}`,
|
|
260
|
-
);
|
|
243
|
+
console.info(`${LOG_PREFIX} ✔ Plugin installed successfully to: ${pluginsDir}`);
|
|
261
244
|
} catch (error) {
|
|
262
|
-
console.error(
|
|
263
|
-
`${LOG_PREFIX} Failed to install plugin for ${ideDir.name}:`,
|
|
264
|
-
error.message,
|
|
265
|
-
);
|
|
245
|
+
console.error(`${LOG_PREFIX} Failed to install plugin for ${ideDir.name}:`, error.message);
|
|
266
246
|
}
|
|
267
247
|
}
|
|
268
248
|
|
|
@@ -270,27 +250,22 @@ async function installJetBrainsExtension() {
|
|
|
270
250
|
try {
|
|
271
251
|
unlinkSync(pluginFilePath);
|
|
272
252
|
} catch (error) {
|
|
273
|
-
console.warn(
|
|
274
|
-
`${LOG_PREFIX} Failed to clean up temporary file: ${pluginFilePath}`,
|
|
275
|
-
error.message,
|
|
276
|
-
);
|
|
253
|
+
console.warn(`${LOG_PREFIX} Failed to clean up temporary file: ${pluginFilePath}`, error.message);
|
|
277
254
|
}
|
|
255
|
+
|
|
278
256
|
} catch (error) {
|
|
279
257
|
console.error(`${LOG_PREFIX} Failed to install plugin:`, error.message);
|
|
280
258
|
console.debug(`${LOG_PREFIX} Stack trace:`, error.stack);
|
|
281
259
|
}
|
|
282
260
|
} catch (error) {
|
|
283
|
-
console.error(
|
|
284
|
-
`${LOG_PREFIX} Unexpected error during JetBrains extension installation:`,
|
|
285
|
-
error.message,
|
|
286
|
-
);
|
|
261
|
+
console.error(`${LOG_PREFIX} Unexpected error during JetBrains extension installation:`, error.message);
|
|
287
262
|
console.debug(`${LOG_PREFIX} Stack trace:`, error.stack);
|
|
288
263
|
}
|
|
289
264
|
}
|
|
290
265
|
|
|
291
266
|
// 只在非 CI 环境执行
|
|
292
267
|
if (!process.env.CI) {
|
|
293
|
-
installJetBrainsExtension().catch(
|
|
268
|
+
installJetBrainsExtension().catch(error => {
|
|
294
269
|
console.error(`${LOG_PREFIX} Installation failed:`, error.message);
|
|
295
270
|
});
|
|
296
271
|
}
|