rl-rockcli 0.0.7 → 0.0.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.
Files changed (74) hide show
  1. package/index.js +15 -5
  2. package/package.json +2 -2
  3. package/commands/log/core/constants.js +0 -237
  4. package/commands/log/core/display.js +0 -370
  5. package/commands/log/core/search.js +0 -330
  6. package/commands/log/core/tail.js +0 -216
  7. package/commands/log/core/utils.js +0 -424
  8. package/commands/log.js +0 -298
  9. package/commands/sandbox/core/log-bridge.js +0 -119
  10. package/commands/sandbox/core/replay/analyzer.js +0 -311
  11. package/commands/sandbox/core/replay/batch-orchestrator.js +0 -536
  12. package/commands/sandbox/core/replay/batch-task.js +0 -369
  13. package/commands/sandbox/core/replay/concurrent-display.js +0 -70
  14. package/commands/sandbox/core/replay/concurrent-orchestrator.js +0 -170
  15. package/commands/sandbox/core/replay/data-source.js +0 -86
  16. package/commands/sandbox/core/replay/display.js +0 -231
  17. package/commands/sandbox/core/replay/executor.js +0 -634
  18. package/commands/sandbox/core/replay/history-fetcher.js +0 -124
  19. package/commands/sandbox/core/replay/index.js +0 -338
  20. package/commands/sandbox/core/replay/loghouse-data-source.js +0 -177
  21. package/commands/sandbox/core/replay/pid-mapping.js +0 -26
  22. package/commands/sandbox/core/replay/request.js +0 -109
  23. package/commands/sandbox/core/replay/worker.js +0 -166
  24. package/commands/sandbox/core/session.js +0 -346
  25. package/commands/sandbox/log-bridge.js +0 -2
  26. package/commands/sandbox/ray.js +0 -2
  27. package/commands/sandbox/replay/analyzer.js +0 -311
  28. package/commands/sandbox/replay/batch-orchestrator.js +0 -536
  29. package/commands/sandbox/replay/batch-task.js +0 -369
  30. package/commands/sandbox/replay/concurrent-display.js +0 -70
  31. package/commands/sandbox/replay/concurrent-orchestrator.js +0 -170
  32. package/commands/sandbox/replay/display.js +0 -231
  33. package/commands/sandbox/replay/executor.js +0 -634
  34. package/commands/sandbox/replay/history-fetcher.js +0 -118
  35. package/commands/sandbox/replay/index.js +0 -338
  36. package/commands/sandbox/replay/pid-mapping.js +0 -26
  37. package/commands/sandbox/replay/request.js +0 -109
  38. package/commands/sandbox/replay/worker.js +0 -166
  39. package/commands/sandbox/replay.js +0 -2
  40. package/commands/sandbox/session.js +0 -2
  41. package/commands/sandbox-original.js +0 -1393
  42. package/commands/sandbox.js +0 -499
  43. package/help/help.json +0 -1071
  44. package/help/middleware.js +0 -71
  45. package/help/renderer.js +0 -800
  46. package/lib/plugin-context.js +0 -40
  47. package/sdks/sandbox/core/client.js +0 -845
  48. package/sdks/sandbox/core/config.js +0 -70
  49. package/sdks/sandbox/core/types.js +0 -74
  50. package/sdks/sandbox/httpLogger.js +0 -251
  51. package/sdks/sandbox/index.js +0 -9
  52. package/utils/asciiArt.js +0 -138
  53. package/utils/bun-compat.js +0 -59
  54. package/utils/ciPipelines.js +0 -138
  55. package/utils/cli.js +0 -17
  56. package/utils/command-router.js +0 -79
  57. package/utils/configManager.js +0 -503
  58. package/utils/dependency-resolver.js +0 -135
  59. package/utils/eagleeye_traceid.js +0 -151
  60. package/utils/envDetector.js +0 -78
  61. package/utils/execution_logger.js +0 -415
  62. package/utils/featureManager.js +0 -68
  63. package/utils/firstTimeTip.js +0 -44
  64. package/utils/hook-manager.js +0 -125
  65. package/utils/http-logger.js +0 -264
  66. package/utils/i18n.js +0 -139
  67. package/utils/image-progress.js +0 -159
  68. package/utils/logger.js +0 -154
  69. package/utils/plugin-loader.js +0 -124
  70. package/utils/plugin-manager.js +0 -348
  71. package/utils/ray_cli_wrapper.js +0 -746
  72. package/utils/sandbox-client.js +0 -419
  73. package/utils/terminal.js +0 -32
  74. package/utils/tips.js +0 -106
@@ -1,503 +0,0 @@
1
- const fs = require('fs-extra');
2
- const os = require('os');
3
- const path = require('path');
4
- const logger = require('./logger');
5
-
6
- class ConfigManager {
7
- constructor() {
8
- // 旧配置文件路径(用于向后兼容)
9
- this.oldConfigDir = path.join(os.homedir(), '.rock-cli');
10
- this.oldConfigPath = path.join(this.oldConfigDir, 'settings.json');
11
-
12
- // 新配置文件路径(统一配置)
13
- this.newConfigDir = path.join(os.homedir(), '.rock');
14
- this.newConfigPath = path.join(this.newConfigDir, 'settings.json');
15
-
16
- // 默认使用新配置路径
17
- this.configPath = this.newConfigPath;
18
- this.configDir = this.newConfigDir;
19
-
20
- this.ensureConfigDir();
21
- }
22
-
23
- /**
24
- * 确保配置目录存在
25
- */
26
- ensureConfigDir() {
27
- if (!fs.existsSync(this.configDir)) {
28
- fs.mkdirpSync(this.configDir, { recursive: true });
29
- logger.info(`Created config directory: ${this.configDir}`);
30
- }
31
- }
32
-
33
- /**
34
- * 读取配置 - 支持新旧格式
35
- */
36
- readConfig() {
37
- // 优先读取新配置文件
38
- if (fs.existsSync(this.newConfigPath)) {
39
- try {
40
- const configData = fs.readJsonSync(this.newConfigPath);
41
- return configData;
42
- } catch (error) {
43
- logger.error(`Failed to read new config file: ${error.message}`);
44
- }
45
- }
46
-
47
- // 如果新配置文件不存在,尝试读取旧配置文件
48
- if (fs.existsSync(this.oldConfigPath)) {
49
- try {
50
- const configData = fs.readJsonSync(this.oldConfigPath);
51
- // 将旧格式转换为新格式
52
- const newFormatConfig = this.convertOldToNewFormat(configData);
53
- // 保存到新位置以实现迁移
54
- this.saveToNewConfig(newFormatConfig);
55
- return newFormatConfig;
56
- } catch (error) {
57
- logger.error(`Failed to read old config file: ${error.message}`);
58
- }
59
- }
60
-
61
- return {};
62
- }
63
-
64
- /**
65
- * 将旧配置格式转换为新格式
66
- */
67
- convertOldToNewFormat(oldConfig) {
68
- const newConfig = { sandbox: {}, test: {} };
69
-
70
- // 将旧配置映射到新格式的 sandbox 部分
71
- for (const [key, value] of Object.entries(oldConfig)) {
72
- if (key === 'base_url' || key === 'api_key' || key === 'cluster' ||
73
- key === 'user_id' || key === 'experiment_id') {
74
- newConfig.sandbox[key] = value;
75
- } else if (key === 'private_token' || key === 'whale_apikey' ||
76
- key === 'code_private_token' || key === 'whale_api_key') {
77
- newConfig.test[key] = value;
78
- } else {
79
- // 其他配置项也放入 sandbox(作为默认)
80
- newConfig.sandbox[key] = value;
81
- }
82
- }
83
-
84
- return newConfig;
85
- }
86
-
87
- /**
88
- * 保存到新配置文件
89
- */
90
- saveToNewConfig(config) {
91
- try {
92
- fs.writeJsonSync(this.newConfigPath, config, { spaces: 2 });
93
- logger.info(`Config saved to: ${this.newConfigPath}`);
94
- return true;
95
- } catch (error) {
96
- logger.error(`Failed to write new config file: ${error.message}`);
97
- return false;
98
- }
99
- }
100
-
101
- /**
102
- * 写入配置
103
- */
104
- writeConfig(config) {
105
- return this.saveToNewConfig(config);
106
- }
107
-
108
- /**
109
- * 获取特定配置项(支持旧格式兼容)
110
- */
111
- getConfig(key) {
112
- const config = this.readConfig();
113
-
114
- // 如果配置已经是新格式(有 sandbox 和 test 部分)
115
- if (config.sandbox || config.test) {
116
- // 检查 test 部分
117
- if (config.test && config.test.hasOwnProperty(key)) {
118
- return config.test[key];
119
- }
120
- // 检查 sandbox 部分
121
- if (config.sandbox && config.sandbox.hasOwnProperty(key)) {
122
- return config.sandbox[key];
123
- }
124
- }
125
-
126
- // 否则按旧格式处理
127
- return config[key];
128
- }
129
-
130
- /**
131
- * 设置特定配置项(支持新格式)
132
- */
133
- setConfig(key, value) {
134
- const config = this.readConfig();
135
-
136
- // 检查是否是测试相关的配置键
137
- const testKeys = ['private_token', 'whale_apikey', 'code_private_token', 'whale_api_key'];
138
- if (testKeys.includes(key)) {
139
- if (!config.test) config.test = {};
140
- config.test[key] = value;
141
- } else {
142
- // 其他配置默认放在 sandbox 部分
143
- if (!config.sandbox) config.sandbox = {};
144
- config.sandbox[key] = value;
145
- }
146
-
147
- return this.writeConfig(config);
148
- }
149
-
150
- /**
151
- * 删除特定配置项
152
- */
153
- deleteConfig(key) {
154
- const config = this.readConfig();
155
-
156
- if (config.test && config.test.hasOwnProperty(key)) {
157
- delete config.test[key];
158
- } else if (config.sandbox && config.sandbox.hasOwnProperty(key)) {
159
- delete config.sandbox[key];
160
- } else {
161
- delete config[key];
162
- }
163
-
164
- return this.writeConfig(config);
165
- }
166
-
167
- /**
168
- * 设置沙箱配置
169
- */
170
- setSandboxConfig(key, value) {
171
- const config = this.readConfig();
172
- if (!config.sandbox) config.sandbox = {};
173
- config.sandbox[key] = value;
174
- return this.writeConfig(config);
175
- }
176
-
177
- /**
178
- * 获取沙箱配置
179
- */
180
- getSandboxConfig(key) {
181
- const config = this.readConfig();
182
- if (config.sandbox && config.sandbox.hasOwnProperty(key)) {
183
- return config.sandbox[key];
184
- }
185
- return undefined;
186
- }
187
-
188
- /**
189
- * 获取 UI 配置
190
- */
191
- getUIConfig(key, defaultValue = undefined) {
192
- const config = this.readConfig();
193
- if (config.ui && Object.prototype.hasOwnProperty.call(config.ui, key)) {
194
- return config.ui[key];
195
- }
196
- return defaultValue;
197
- }
198
-
199
- /**
200
- * 设置 UI 配置
201
- */
202
- setUIConfig(key, value) {
203
- const config = this.readConfig();
204
- if (!config.ui) config.ui = {};
205
- config.ui[key] = value;
206
- return this.writeConfig(config);
207
- }
208
-
209
- /**
210
- * 设置测试配置
211
- */
212
- setTestConfig(key, value) {
213
- const config = this.readConfig();
214
- if (!config.test) config.test = {};
215
- config.test[key] = value;
216
- return this.writeConfig(config);
217
- }
218
-
219
- /**
220
- * 获取测试配置
221
- */
222
- getTestConfig(key) {
223
- const config = this.readConfig();
224
- if (config.test && config.test.hasOwnProperty(key)) {
225
- return config.test[key];
226
- }
227
- return undefined;
228
- }
229
-
230
- /**
231
- * 获取配置路径
232
- */
233
- getConfigPath() {
234
- return this.configPath;
235
- }
236
-
237
- /**
238
- * Get API key with priority: ROCK_API_KEY env > CLI arg > config file
239
- * @param {Object} argv - Command line arguments
240
- * @returns {string|null} - API key or null if not found
241
- */
242
- getApiKeyWithPriority(argv = {}) {
243
- // Priority 1: Environment variable
244
- if (process.env.ROCK_API_KEY) {
245
- return process.env.ROCK_API_KEY;
246
- }
247
-
248
- // Priority 2: CLI argument
249
- if (argv.apiKey) {
250
- return argv.apiKey;
251
- }
252
-
253
- // Priority 3: Config file
254
- const config = this.readConfig();
255
- if (config?.sandbox?.api_key) {
256
- return config.sandbox.api_key;
257
- }
258
-
259
- return null;
260
- }
261
-
262
- /**
263
- * Get cluster with priority: ROCK_CLUSTER env > CLI arg > config file > default
264
- * @param {Object} argv - Command line arguments
265
- * @returns {string} - Cluster or default 'zb'
266
- */
267
- getClusterWithPriority(argv = {}) {
268
- // Priority 1: Environment variable
269
- if (process.env.ROCK_CLUSTER) {
270
- return process.env.ROCK_CLUSTER;
271
- }
272
-
273
- // Priority 2: CLI argument
274
- if (argv.cluster) {
275
- return argv.cluster;
276
- }
277
-
278
- // Priority 3: Config file
279
- const config = this.readConfig();
280
- if (config?.sandbox?.cluster) {
281
- return config.sandbox.cluster;
282
- }
283
-
284
- // Default value
285
- return 'zb';
286
- }
287
-
288
- /**
289
- * Get user ID with priority: ROCK_USER_ID env > CLI arg > config file
290
- * @param {Object} argv - Command line arguments
291
- * @returns {string|null} - User ID or null if not found
292
- */
293
- getUserIdWithPriority(argv = {}) {
294
- // Priority 1: Environment variable
295
- if (process.env.ROCK_USER_ID) {
296
- return process.env.ROCK_USER_ID;
297
- }
298
-
299
- // Priority 2: CLI argument
300
- if (argv.userId) {
301
- return argv.userId;
302
- }
303
-
304
- // Priority 3: Config file
305
- const config = this.readConfig();
306
- if (config?.sandbox?.user_id) {
307
- return config.sandbox.user_id;
308
- }
309
-
310
- return null;
311
- }
312
-
313
- /**
314
- * Get experiment ID with priority: ROCK_EXPERIMENT_ID env > CLI arg > config file
315
- * @param {Object} argv - Command line arguments
316
- * @returns {string|null} - Experiment ID or null if not found
317
- */
318
- getExperimentIdWithPriority(argv = {}) {
319
- // Priority 1: Environment variable
320
- if (process.env.ROCK_EXPERIMENT_ID) {
321
- return process.env.ROCK_EXPERIMENT_ID;
322
- }
323
-
324
- // Priority 2: CLI argument
325
- if (argv.experimentId) {
326
- return argv.experimentId;
327
- }
328
-
329
- // Priority 3: Config file
330
- const config = this.readConfig();
331
- if (config?.sandbox?.experiment_id) {
332
- return config.sandbox.experiment_id;
333
- }
334
-
335
- return null;
336
- }
337
-
338
- /**
339
- * 获取脱敏后的配置(用于显示)
340
- */
341
- getMaskedConfig() {
342
- const config = this.readConfig();
343
-
344
- // 如果是新格式,对各部分分别脱敏
345
- if (config.sandbox || config.test) {
346
- const maskedConfig = {};
347
- if (config.sandbox) {
348
- maskedConfig.sandbox = {};
349
- for (const [key, value] of Object.entries(config.sandbox)) {
350
- if (typeof value === 'string' && (key.toLowerCase().includes('token') || key.toLowerCase().includes('key') || key.toLowerCase().includes('secret'))) {
351
- maskedConfig.sandbox[key] = this.maskValue(value);
352
- } else {
353
- maskedConfig.sandbox[key] = value;
354
- }
355
- }
356
- }
357
- if (config.test) {
358
- maskedConfig.test = {};
359
- for (const [key, value] of Object.entries(config.test)) {
360
- if (typeof value === 'string' && (key.toLowerCase().includes('token') || key.toLowerCase().includes('key') || key.toLowerCase().includes('secret'))) {
361
- maskedConfig.test[key] = this.maskValue(value);
362
- } else {
363
- maskedConfig.test[key] = value;
364
- }
365
- }
366
- }
367
- return maskedConfig;
368
- } else {
369
- // 旧格式处理
370
- const maskedConfig = {};
371
- for (const [key, value] of Object.entries(config)) {
372
- if (typeof value === 'string' && (key.toLowerCase().includes('token') || key.toLowerCase().includes('key'))) {
373
- maskedConfig[key] = this.maskValue(value);
374
- } else {
375
- maskedConfig[key] = value;
376
- }
377
- }
378
- return maskedConfig;
379
- }
380
- }
381
-
382
- /**
383
- * 脱敏处理
384
- */
385
- maskValue(value) {
386
- if (typeof value !== 'string') {
387
- return value;
388
- }
389
-
390
- if (value.length <= 8) {
391
- return '*'.repeat(Math.max(value.length, 4));
392
- }
393
-
394
- // 保留前2位和后2位,中间用星号代替
395
- return value.substring(0, 2) + '*'.repeat(value.length - 4) + value.substring(value.length - 2);
396
- }
397
-
398
- /**
399
- * 获取插件配置
400
- * @param {string} pluginName - 插件名称
401
- * @returns {Object} - 插件配置对象
402
- */
403
- getPluginConfig(pluginName) {
404
- const config = this.readConfig();
405
- const plugins = config.plugins || [];
406
-
407
- // 旧格式:数组
408
- if (Array.isArray(plugins)) {
409
- return {}; // 旧格式不支持配置
410
- }
411
-
412
- // 新格式:对象
413
- const pluginConfig = plugins[pluginName];
414
- return pluginConfig?.config || {};
415
- }
416
-
417
- /**
418
- * 获取所有插件配置(支持新旧格式转换)
419
- * @returns {Object} - 插件配置对象
420
- */
421
- getPlugins() {
422
- const config = this.readConfig();
423
- const plugins = config.plugins || [];
424
-
425
- // 旧格式:转换为新格式
426
- if (Array.isArray(plugins)) {
427
- return plugins.reduce((acc, path, index) => {
428
- const name = `plugin-${index}`;
429
- acc[name] = {
430
- path: path,
431
- config: {},
432
- enabled: true
433
- };
434
- return acc;
435
- }, {});
436
- }
437
-
438
- // 新格式:直接返回
439
- return plugins;
440
- }
441
-
442
- /**
443
- * 检查插件是否启用
444
- * @param {string} pluginName - 插件名称
445
- * @returns {boolean} - 是否启用
446
- */
447
- isPluginEnabled(pluginName) {
448
- const plugins = this.getPlugins();
449
- const pluginConfig = plugins[pluginName];
450
-
451
- // 插件不存在,返回 false
452
- if (!pluginConfig) {
453
- return false;
454
- }
455
-
456
- // enabled 字段不存在,默认启用
457
- if (pluginConfig.enabled === undefined) {
458
- return true;
459
- }
460
-
461
- // 返回 enabled 的值
462
- return pluginConfig.enabled === true;
463
- }
464
-
465
- /**
466
- * 设置插件配置(兼容旧格式)
467
- * @param {Array<string>} plugins - 插件路径数组(旧格式)
468
- * @returns {boolean}
469
- */
470
- setPlugins(plugins) {
471
- const config = this.readConfig();
472
- config.plugins = plugins;
473
- return this.writeConfig(config);
474
- }
475
-
476
- /**
477
- * 获取全局配置(带优先级合并)
478
- * @param {Object} argv - 命令行参数对象
479
- * @returns {Object} - 合并后的全局配置
480
- */
481
- getGlobalConfigWithPriority(argv = {}) {
482
- const config = this.readConfig();
483
- const sandboxConfig = config.sandbox || {};
484
-
485
- // 实现优先级合并逻辑
486
- const mergedConfig = {
487
- ...config,
488
- sandbox: {
489
- ...sandboxConfig,
490
- // 使用优先级函数获取所有参数
491
- api_key: this.getApiKeyWithPriority(argv),
492
- base_url: argv.baseUrl || sandboxConfig.base_url,
493
- cluster: this.getClusterWithPriority(argv),
494
- user_id: this.getUserIdWithPriority(argv),
495
- experiment_id: this.getExperimentIdWithPriority(argv)
496
- }
497
- };
498
-
499
- return mergedConfig;
500
- }
501
- }
502
-
503
- module.exports = new ConfigManager();
@@ -1,135 +0,0 @@
1
- const logger = require('./logger');
2
-
3
- /**
4
- * 依赖关系解析器
5
- * 用于解析插件加载顺序,检测循环依赖
6
- */
7
- class DependencyResolver {
8
- /**
9
- * 解析插件加载顺序
10
- * @param {Array<{name: string, dependsOn?: string[]}>} plugins - 插件列表
11
- * @returns {Array<string>} - 加载顺序(插件名称数组)
12
- * @throws {Error} - 如果存在循环依赖
13
- */
14
- resolveLoadOrder(plugins) {
15
- if (!plugins || plugins.length === 0) {
16
- return [];
17
- }
18
-
19
- // 构建依赖图
20
- const graph = {};
21
- const allPlugins = new Set();
22
-
23
- plugins.forEach(plugin => {
24
- const { name, dependsOn = [] } = plugin;
25
- allPlugins.add(name);
26
-
27
- if (!graph[name]) {
28
- graph[name] = [];
29
- }
30
-
31
- dependsOn.forEach(dep => {
32
- graph[name].push(dep);
33
- allPlugins.add(dep);
34
- });
35
- });
36
-
37
- // 确保所有插件都在图中
38
- allPlugins.forEach(name => {
39
- if (!graph[name]) {
40
- graph[name] = [];
41
- }
42
- });
43
-
44
- // 检测环
45
- if (this._hasCycle(graph)) {
46
- throw new Error('Circular dependency detected in plugins');
47
- }
48
-
49
- // 拓扑排序
50
- return this._topologicalSort(graph);
51
- }
52
-
53
- /**
54
- * 检测依赖图中是否存在环
55
- * @private
56
- */
57
- _hasCycle(graph) {
58
- const visited = new Set();
59
- const recursionStack = new Set();
60
-
61
- const dfs = (node) => {
62
- if (recursionStack.has(node)) {
63
- return true; // 发现环
64
- }
65
- if (visited.has(node)) {
66
- return false;
67
- }
68
-
69
- visited.add(node);
70
- recursionStack.add(node);
71
-
72
- const neighbors = graph[node] || [];
73
- for (const neighbor of neighbors) {
74
- if (dfs(neighbor)) {
75
- return true;
76
- }
77
- }
78
-
79
- recursionStack.delete(node);
80
- return false;
81
- };
82
-
83
- for (const node of Object.keys(graph)) {
84
- if (!visited.has(node)) {
85
- if (dfs(node)) {
86
- return true;
87
- }
88
- }
89
- }
90
-
91
- return false;
92
- }
93
-
94
- /**
95
- * 拓扑排序
96
- * @private
97
- */
98
- _topologicalSort(graph) {
99
- const outDegree = {};
100
- const queue = [];
101
- const result = [];
102
-
103
- // 计算出度(这个节点依赖多少个节点)
104
- for (const node of Object.keys(graph)) {
105
- outDegree[node] = (graph[node] || []).length;
106
- }
107
-
108
- // 将出度为 0 的节点(不依赖任何节点的)加入队列
109
- for (const node of Object.keys(outDegree)) {
110
- if (outDegree[node] === 0) {
111
- queue.push(node);
112
- }
113
- }
114
-
115
- // 拓扑排序
116
- while (queue.length > 0) {
117
- const node = queue.shift();
118
- result.push(node);
119
-
120
- // node 已经加载完成,减少依赖 node 的节点的出度
121
- for (const dependent of Object.keys(graph)) {
122
- if (graph[dependent].includes(node)) {
123
- outDegree[dependent]--;
124
- if (outDegree[dependent] === 0) {
125
- queue.push(dependent);
126
- }
127
- }
128
- }
129
- }
130
-
131
- return result;
132
- }
133
- }
134
-
135
- module.exports = DependencyResolver;