deepfish-ai 1.0.29 → 2.0.2

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 (62) hide show
  1. package/README.md +126 -368
  2. package/dist/index.js +23320 -0
  3. package/dist/serve/client/assets/index-DUHYC91l.js +1 -0
  4. package/dist/serve/client/assets/index-zcrdNLZs.css +1 -0
  5. package/dist/serve/client/index.html +14 -0
  6. package/dist/serve/pm2-server.js +21015 -0
  7. package/dist/serve/server/entry-server.mjs +224 -0
  8. package/package.json +61 -83
  9. package/LICENSE +0 -21
  10. package/README_CN.md +0 -460
  11. package/src/AgentRobot/AgentRobotFactory/MainAgentRobot.js +0 -88
  12. package/src/AgentRobot/AgentRobotFactory/SubAgentRobot.js +0 -45
  13. package/src/AgentRobot/AgentRobotFactory/SubSkillAgentRobot.js +0 -45
  14. package/src/AgentRobot/AgentRobotFactory/index.js +0 -48
  15. package/src/AgentRobot/BaseAgentRobot/Brain.js +0 -210
  16. package/src/AgentRobot/BaseAgentRobot/BrainEvent.js +0 -17
  17. package/src/AgentRobot/BaseAgentRobot/Hand.js +0 -119
  18. package/src/AgentRobot/BaseAgentRobot/Heart.js +0 -0
  19. package/src/AgentRobot/BaseAgentRobot/Logger.js +0 -114
  20. package/src/AgentRobot/BaseAgentRobot/ScreenPrinter.js +0 -49
  21. package/src/AgentRobot/BaseAgentRobot/index.js +0 -266
  22. package/src/AgentRobot/BaseAgentRobot/lazy-tools/AliBailian.js +0 -997
  23. package/src/AgentRobot/BaseAgentRobot/lazy-tools/doc-transform.js +0 -204
  24. package/src/AgentRobot/BaseAgentRobot/lazy-tools/docx.js +0 -1286
  25. package/src/AgentRobot/BaseAgentRobot/lazy-tools/img.js +0 -765
  26. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pdf.js +0 -736
  27. package/src/AgentRobot/BaseAgentRobot/lazy-tools/pptx.js +0 -567
  28. package/src/AgentRobot/BaseAgentRobot/lazy-tools/video.js +0 -36
  29. package/src/AgentRobot/BaseAgentRobot/lazy-tools/xlsx.js +0 -611
  30. package/src/AgentRobot/BaseAgentRobot/tools/BaseTools.js +0 -13
  31. package/src/AgentRobot/BaseAgentRobot/tools/CreateAgentTools.js +0 -158
  32. package/src/AgentRobot/BaseAgentRobot/tools/FileTools.js +0 -768
  33. package/src/AgentRobot/BaseAgentRobot/tools/GenerateTools.js +0 -441
  34. package/src/AgentRobot/BaseAgentRobot/tools/InquirerTools.js +0 -244
  35. package/src/AgentRobot/BaseAgentRobot/tools/SystemTools.js +0 -424
  36. package/src/AgentRobot/BaseAgentRobot/tools/TaskTools.js +0 -211
  37. package/src/AgentRobot/BaseAgentRobot/tools/TestTools.js +0 -100
  38. package/src/AgentRobot/BaseAgentRobot/tools/UserTool.js +0 -87
  39. package/src/AgentRobot/BaseAgentRobot/tools/WebTools.js +0 -257
  40. package/src/AgentRobot/BaseAgentRobot/utils/AIRequest.js +0 -297
  41. package/src/AgentRobot/BaseAgentRobot/utils/AIToolManager.js +0 -131
  42. package/src/AgentRobot/BaseAgentRobot/utils/AgentTree.js +0 -66
  43. package/src/AgentRobot/BaseAgentRobot/utils/AttachmentToolScanner.js +0 -235
  44. package/src/AgentRobot/BaseAgentRobot/utils/MessageCompresser.js +0 -236
  45. package/src/AgentRobot/BaseAgentRobot/utils/aiConsole.js +0 -74
  46. package/src/AgentRobot/BaseAgentRobot/utils/aiInquirer.js +0 -78
  47. package/src/AgentRobot/BaseAgentRobot/utils/analyzeReturn.test.js +0 -104
  48. package/src/AgentRobot/BaseAgentRobot/utils/copilot.js +0 -117
  49. package/src/AgentRobot/BaseAgentRobot/utils/node-root.js +0 -138
  50. package/src/AgentRobot/BaseAgentRobot/utils/normal.js +0 -399
  51. package/src/cli/ConfigManager.js +0 -283
  52. package/src/cli/DefaultConfig.js +0 -98
  53. package/src/cli/GlobalVariable.js +0 -8
  54. package/src/cli/MemoryManager.js +0 -53
  55. package/src/cli/SkillConfigManager.js +0 -354
  56. package/src/cli/SkillParser.js +0 -58
  57. package/src/cli/ai-auth.js +0 -231
  58. package/src/cli/ai-config.js +0 -225
  59. package/src/cli/ai-memory.js +0 -22
  60. package/src/cli/ai-skill.js +0 -65
  61. package/src/cli/index.js +0 -77
  62. package/src/index.js +0 -54
@@ -1,399 +0,0 @@
1
- const path = require('path')
2
- const fs = require('fs-extra')
3
- const chardet = require('chardet')
4
- const os = require('os')
5
- const { spawn } = require('child_process')
6
-
7
- // 对象字符串转对象
8
- function objStrToObj(str) {
9
- try {
10
- if (typeof str === 'string') {
11
- return eval(`(${str})`)
12
- } else {
13
- return str
14
- }
15
- } catch (error) {
16
- throw new Error(`对象转换失败:${error.message}`)
17
- }
18
- }
19
-
20
- function delay(ms) {
21
- return new Promise((resolve) => setTimeout(resolve, ms))
22
- }
23
-
24
- // 遍历目录和子目录下所有文件
25
- function traverseFiles() {
26
- try {
27
- const currentDir = process.cwd()
28
- const allFiles = []
29
- const currentItems = fs.readdirSync(currentDir, { withFileTypes: true })
30
- for (const item of currentItems) {
31
- const itemPath = path.join(currentDir, item.name)
32
- if (item.isFile()) {
33
- allFiles.push(itemPath)
34
- continue
35
- }
36
- if (item.isDirectory()) {
37
- try {
38
- const subItems = fs.readdirSync(itemPath, { withFileTypes: true })
39
- for (const subItem of subItems) {
40
- if (subItem.isFile()) {
41
- allFiles.push(path.join(itemPath, subItem.name))
42
- }
43
- }
44
- } catch (subErr) {
45
- console.warn(`读取子目录失败 ${itemPath}:${subErr.message}`)
46
- }
47
- }
48
- }
49
- return allFiles
50
- } catch (err) {
51
- console.error(`遍历目录失败:${err.message}`)
52
- return []
53
- }
54
- }
55
-
56
- // 打开目录
57
- function openDirectory(dirPath) {
58
- // 打开目录
59
- const platform = process.platform
60
- let command
61
- let args
62
- const dir = dirPath
63
- if (platform === 'darwin') {
64
- command = 'open'
65
- args = [dir]
66
- } else if (platform === 'win32') {
67
- command = 'explorer.exe'
68
- args = [dir]
69
- } else {
70
- command = 'xdg-open'
71
- args = [dir]
72
- }
73
- const child = spawn(command, args, {
74
- detached: true,
75
- stdio: 'ignore',
76
- })
77
- child.on('error', (error) => {
78
- console.error(`Error opening directory "${dirPath}": ${error.message}`)
79
- })
80
- child.unref()
81
- }
82
-
83
- // 判断编码类型
84
- function detectEncoding(buffer) {
85
- if (!buffer) {
86
- const platform = os.platform()
87
- return platform === 'win32' ? 'gbk' : 'utf-8'
88
- }
89
- const encoding = chardet.detect(buffer)
90
- if (encoding?.toLowerCase() === 'utf-8') {
91
- return 'utf-8'
92
- } else if (['gbk', 'gb2312', 'gb18030'].includes(encoding?.toLowerCase())) {
93
- return 'gbk'
94
- } else {
95
- const platform = os.platform()
96
- return platform === 'win32' ? 'gbk' : 'utf-8'
97
- }
98
- }
99
-
100
- function sleep(ms) {
101
- return new Promise((resolve) => setTimeout(resolve, ms))
102
- }
103
-
104
- // 判断代码是否有返回值
105
- function analyzeReturn(code) {
106
- if (typeof code !== 'string' || !code.trim()) {
107
- return {
108
- hasReturn: false,
109
- hasReturnValue: false,
110
- }
111
- }
112
-
113
- // 移除字符串和注释,避免把文本中的 return 误判为代码关键字。
114
- function stripStringsAndComments(input) {
115
- const chars = input.split('')
116
- let i = 0
117
- let state = 'normal'
118
-
119
- while (i < chars.length) {
120
- const ch = chars[i]
121
- const next = chars[i + 1]
122
-
123
- if (state === 'normal') {
124
- if (ch === '/' && next === '/') {
125
- state = 'line-comment'
126
- chars[i] = ' '
127
- chars[i + 1] = ' '
128
- i += 2
129
- continue
130
- }
131
- if (ch === '/' && next === '*') {
132
- state = 'block-comment'
133
- chars[i] = ' '
134
- chars[i + 1] = ' '
135
- i += 2
136
- continue
137
- }
138
- if (ch === "'") {
139
- state = 'single-quote'
140
- chars[i] = ' '
141
- i += 1
142
- continue
143
- }
144
- if (ch === '"') {
145
- state = 'double-quote'
146
- chars[i] = ' '
147
- i += 1
148
- continue
149
- }
150
- if (ch === '`') {
151
- state = 'template'
152
- chars[i] = ' '
153
- i += 1
154
- continue
155
- }
156
- i += 1
157
- continue
158
- }
159
-
160
- if (state === 'line-comment') {
161
- if (ch === '\n') {
162
- state = 'normal'
163
- } else {
164
- chars[i] = ' '
165
- }
166
- i += 1
167
- continue
168
- }
169
-
170
- if (state === 'block-comment') {
171
- if (ch === '*' && next === '/') {
172
- chars[i] = ' '
173
- chars[i + 1] = ' '
174
- state = 'normal'
175
- i += 2
176
- } else {
177
- if (ch !== '\n') {
178
- chars[i] = ' '
179
- }
180
- i += 1
181
- }
182
- continue
183
- }
184
-
185
- if (state === 'single-quote') {
186
- if (ch === '\\') {
187
- chars[i] = ' '
188
- if (i + 1 < chars.length) {
189
- chars[i + 1] = ' '
190
- }
191
- i += 2
192
- continue
193
- }
194
- chars[i] = ch === '\n' ? '\n' : ' '
195
- if (ch === "'") {
196
- state = 'normal'
197
- }
198
- i += 1
199
- continue
200
- }
201
-
202
- if (state === 'double-quote') {
203
- if (ch === '\\') {
204
- chars[i] = ' '
205
- if (i + 1 < chars.length) {
206
- chars[i + 1] = ' '
207
- }
208
- i += 2
209
- continue
210
- }
211
- chars[i] = ch === '\n' ? '\n' : ' '
212
- if (ch === '"') {
213
- state = 'normal'
214
- }
215
- i += 1
216
- continue
217
- }
218
-
219
- if (state === 'template') {
220
- if (ch === '\\') {
221
- chars[i] = ' '
222
- if (i + 1 < chars.length) {
223
- chars[i + 1] = ' '
224
- }
225
- i += 2
226
- continue
227
- }
228
- chars[i] = ch === '\n' ? '\n' : ' '
229
- if (ch === '`') {
230
- state = 'normal'
231
- }
232
- i += 1
233
- }
234
- }
235
-
236
- return chars.join('')
237
- }
238
-
239
- function isReturnWithValue(input, startIndex) {
240
- let i = startIndex
241
- while (i < input.length) {
242
- const ch = input[i]
243
- const next = input[i + 1]
244
- if (ch === ' ' || ch === '\t' || ch === '\r') {
245
- i += 1
246
- continue
247
- }
248
-
249
- if (ch === '/' && next === '/') {
250
- i += 2
251
- while (i < input.length && input[i] !== '\n') {
252
- i += 1
253
- }
254
- continue
255
- }
256
-
257
- if (ch === '/' && next === '*') {
258
- i += 2
259
- while (i < input.length) {
260
- if (input[i] === '*' && input[i + 1] === '/') {
261
- i += 2
262
- break
263
- }
264
- i += 1
265
- }
266
- continue
267
- }
268
-
269
- if (ch === '\n' || ch === ';' || ch === '}' || ch === ')') {
270
- return false
271
- }
272
- return true
273
- }
274
- return false
275
- }
276
-
277
- function isControlKeyword(token) {
278
- return ['if', 'for', 'while', 'switch', 'catch', 'with'].includes(token)
279
- }
280
-
281
- const cleaned = stripStringsAndComments(code)
282
- const tokenRegex = /[A-Za-z_$][\w$]*|=>|[{}()\[\]]/g
283
- const blockStack = []
284
- const parenStack = []
285
- let functionDepth = 0
286
- let pendingFunctionBlock = 0
287
- let pendingArrow = false
288
- let hasReturn = false
289
- let hasReturnValue = false
290
- let lastToken = ''
291
- let recentClosedParen = null
292
- let match
293
-
294
- while ((match = tokenRegex.exec(cleaned)) !== null) {
295
- const token = match[0]
296
- const index = match.index
297
-
298
- if (token === '(') {
299
- parenStack.push({
300
- beforeToken: lastToken,
301
- })
302
- lastToken = token
303
- continue
304
- }
305
-
306
- if (token === ')') {
307
- recentClosedParen = parenStack.pop() || null
308
- lastToken = token
309
- continue
310
- }
311
-
312
- if (token === 'function') {
313
- pendingFunctionBlock += 1
314
- pendingArrow = false
315
- lastToken = token
316
- recentClosedParen = null
317
- continue
318
- }
319
-
320
- if (token === '=>') {
321
- pendingArrow = true
322
- lastToken = token
323
- recentClosedParen = null
324
- continue
325
- }
326
-
327
- if (token === '{') {
328
- let isFunctionBlock = false
329
- if (pendingFunctionBlock > 0 || pendingArrow) {
330
- isFunctionBlock = true
331
- } else if (lastToken === ')' && recentClosedParen) {
332
- const beforeToken = recentClosedParen.beforeToken
333
- if (beforeToken && !isControlKeyword(beforeToken)) {
334
- // 识别 class/object method 这类无 function 关键字的方法体。
335
- isFunctionBlock = true
336
- }
337
- }
338
-
339
- if (isFunctionBlock) {
340
- blockStack.push('function')
341
- functionDepth += 1
342
- if (pendingFunctionBlock > 0) {
343
- pendingFunctionBlock -= 1
344
- }
345
- } else {
346
- blockStack.push('block')
347
- }
348
-
349
- pendingArrow = false
350
- lastToken = token
351
- recentClosedParen = null
352
- continue
353
- }
354
-
355
- if (token === '}') {
356
- const top = blockStack.pop()
357
- if (top === 'function' && functionDepth > 0) {
358
- functionDepth -= 1
359
- }
360
- pendingArrow = false
361
- lastToken = token
362
- recentClosedParen = null
363
- continue
364
- }
365
-
366
- if (token === 'return' && functionDepth === 0) {
367
- hasReturn = true
368
- if (isReturnWithValue(code, index + token.length)) {
369
- hasReturnValue = true
370
- }
371
- if (hasReturn && hasReturnValue) {
372
- break
373
- }
374
- }
375
-
376
- if (pendingArrow) {
377
- // 箭头函数表达式体不带 {} 时,不会有 return 关键字参与判断。
378
- pendingArrow = false
379
- }
380
-
381
- lastToken = token
382
- recentClosedParen = null
383
- }
384
-
385
- return {
386
- hasReturn,
387
- hasReturnValue,
388
- }
389
- }
390
-
391
- module.exports = {
392
- objStrToObj,
393
- delay,
394
- traverseFiles,
395
- openDirectory,
396
- detectEncoding,
397
- sleep,
398
- analyzeReturn,
399
- }
@@ -1,283 +0,0 @@
1
- const path = require('path')
2
- const os = require('os')
3
- const fs = require('fs-extra')
4
- const { exec } = require('child_process')
5
- const lodash = require('lodash')
6
- const { defaultConfig } = require('./DefaultConfig.js')
7
- const { GlobalVariable } = require('./GlobalVariable.js')
8
- const { openDirectory } = require('../AgentRobot/BaseAgentRobot/utils/normal.js')
9
- const aiConsole = require('../AgentRobot/BaseAgentRobot/utils/aiConsole.js')
10
-
11
- class ConfigManager {
12
- config = null
13
- configDir = path.join(os.homedir(), './.deepfish-ai')
14
- configPath = path.join(this.configDir, './config.js')
15
- constructor() {
16
- this.initConfig()
17
- GlobalVariable.configManager = this
18
- }
19
- // 初始化config
20
- initConfig() {
21
- fs.ensureDirSync(this.configDir)
22
- // 判断之前版本的配置文件是否存在,如果存在则迁移到新目录
23
- const isConfigExists = this.checkConfigExists()
24
- if (
25
- !isConfigExists &&
26
- fs.pathExistsSync(path.join(os.homedir(), '.ai-cmd.config.js'))
27
- ) {
28
- fs.moveSync(path.join(os.homedir(), '.ai-cmd.config.js'), this.configPath)
29
- } else if (!isConfigExists) {
30
- this.writeConfig()
31
- }
32
- this.config = this.getConfig()
33
- this.writeConfig(this.config)
34
- }
35
-
36
- dir() {
37
- openDirectory(this.configDir)
38
- }
39
-
40
- edit() {
41
- const platform = process.platform
42
-
43
- let openCommand
44
- if (process.env.EDITOR) {
45
- openCommand = `${process.env.EDITOR} "${this.configPath}"`
46
- } else if (platform === 'darwin') {
47
- openCommand = `open -e "${this.configPath}"`
48
- } else if (platform === 'win32') {
49
- openCommand = `notepad "${this.configPath}"`
50
- } else {
51
- openCommand = `xdg-open "${this.configPath}"`
52
- }
53
- exec(openCommand, (error) => {
54
- if (error) {
55
- aiConsole.logError('Error opening configuration file:', error.message)
56
- }
57
- })
58
- }
59
-
60
- // 判断config是否存在
61
- checkConfigExists() {
62
- return fs.pathExistsSync(this.configPath)
63
- }
64
-
65
- // 重名验证
66
- checkName(aiName) {
67
- const existingIndex = this.config.ai.findIndex(
68
- (item) => item.name === aiName,
69
- )
70
- return existingIndex !== -1
71
- }
72
-
73
- isAiListEmpty() {
74
- return this.config.ai && this.config.ai.length === 0
75
- }
76
-
77
- // 添加一个aiConfig
78
- addAiConfig(aiConfig) {
79
- this.config.ai.push(aiConfig)
80
- this.writeConfig(this.config)
81
- aiConsole.logSuccess(`AI configuration "${aiConfig.name}" added successfully!`)
82
- return aiConfig
83
- }
84
-
85
- // 删除一个aiConfig
86
- delAiConfig(aiName) {
87
- const existingIndex = this.config.ai.findIndex(
88
- (item) => item.name === aiName,
89
- )
90
- if (existingIndex === -1) {
91
- aiConsole.logError(`Configuration with name "${aiName}" not found.`)
92
- return
93
- }
94
- const currentAi = this.config.currentAi
95
- // Check if it's the current configuration
96
- if (currentAi === aiName) {
97
- aiConsole.logError(`Cannot delete current configuration "${aiName}".`)
98
- return
99
- }
100
- // Remove the configuration
101
- this.config.ai.splice(existingIndex, 1)
102
- this.writeConfig(this.config)
103
- aiConsole.logSuccess(`AI configuration "${aiName}" deleted successfully!`)
104
- }
105
-
106
- // 设置当前Ai
107
- setCurrentAi(aiName) {
108
- // 查看列表中是否存在
109
- const existingIndex = this.config.ai.findIndex(
110
- (item) => item.name === aiName,
111
- )
112
- if (existingIndex === -1) {
113
- aiConsole.logError(`Configuration with name "${aiName}" not found.`)
114
- return
115
- }
116
- this.config.currentAi = aiName
117
- this.writeConfig(this.config)
118
- aiConsole.logSuccess(`Current AI configuration set to "${aiName}" successfully!`)
119
- }
120
-
121
- getCurrentAiConfig() {
122
- return this.config.ai.find((item) => item.name === this.config.currentAi)
123
- }
124
-
125
- getCurrentAi() {
126
- return this.config.currentAi
127
- }
128
-
129
- _getAiConfig(aiName) {
130
- return this.config.ai.find((item) => item.name === aiName)
131
- }
132
-
133
- getAiConfig(aiName) {
134
- return this._getAiConfig(aiName)
135
- }
136
-
137
- updateAiConfigByName(aiName, updater) {
138
- const existingIndex = this.config.ai.findIndex(
139
- (item) => item.name === aiName,
140
- )
141
- if (existingIndex === -1) {
142
- aiConsole.logError(`Configuration with name "${aiName}" not found.`)
143
- return null
144
- }
145
-
146
- const current = this.config.ai[existingIndex]
147
- const next = typeof updater === 'function'
148
- ? updater(lodash.cloneDeep(current))
149
- : lodash.merge(lodash.cloneDeep(current), updater)
150
-
151
- this.config.ai[existingIndex] = next
152
- this.writeConfig(this.config)
153
- return next
154
- }
155
-
156
- // 获取Ai列表
157
- getAiList() {
158
- console.log('AI Configurations')
159
- console.log('='.repeat(50))
160
- if (this.config.ai && Array.isArray(this.config.ai)) {
161
- if (this.config.ai.length === 0) {
162
- aiConsole.logError('No AI configurations found.')
163
- } else {
164
- this.config.ai.forEach((config, index) => {
165
- const isCurrent = this.config.currentAi === config.name
166
- aiConsole.logInfo(`${config.name} ${isCurrent ? '(current)' : ''}`)
167
- })
168
- }
169
- } else {
170
- aiConsole.logError('No AI configurations found.')
171
- }
172
- console.log('='.repeat(50))
173
- }
174
-
175
- // 重置config
176
- resetConfig() {
177
- console.log('Resetting configuration file:', this.configPath)
178
- this.writeConfig()
179
- this.config = this.getConfig()
180
- aiConsole.logSuccess('Configuration file has been reset to default settings.')
181
- }
182
-
183
- // 查看ai详情
184
- viewAiConfigDetail(aiName) {
185
- if (this.isAiListEmpty()) {
186
- aiConsole.logError(
187
- 'No AI configurations found. Please add an AI configuration first.',
188
- )
189
- return
190
- }
191
- if (!aiName) {
192
- aiName = this.config.currentAi
193
- if (!aiName) {
194
- aiConsole.logError(
195
- 'No current AI configuration set. Please input "ai config use <name>" to set a current configuration.',
196
- )
197
- return
198
- }
199
- }
200
- const aiConfig = this._getAiConfig(aiName)
201
- if (!aiConfig) {
202
- aiConsole.logError(
203
- 'AI configuration not found. Please check the name and try again.',
204
- )
205
- return
206
- }
207
- aiConsole.logSuccess('AI Configuration Details')
208
- aiConsole.logSuccess('='.repeat(50))
209
- aiConsole.logInfo(`Name: ${aiConfig.name}`)
210
- aiConsole.logInfo(`Type: ${aiConfig.type}`)
211
- aiConsole.logInfo(`API Base URL: ${aiConfig.baseUrl}`)
212
- aiConsole.logInfo(`Model: ${aiConfig.model}`)
213
- if (aiConfig.apiKey) {
214
- const maskPrefix = String(aiConfig.apiKey).slice(0, 6)
215
- aiConsole.logInfo(`API Key: ${maskPrefix}... (masked)`)
216
- }
217
- aiConsole.logInfo(`Temperature: ${aiConfig.temperature}`)
218
- aiConsole.logInfo(`Max Tokens: ${aiConfig.maxTokens}`)
219
- aiConsole.logInfo(`Streaming Output: ${aiConfig.stream ? 'Enabled' : 'Disabled'}`)
220
- aiConsole.logInfo(
221
- `Is Current: ${this.config.currentAi === aiConfig.name ? 'Yes' : 'No'}`,
222
- )
223
- aiConsole.logInfo(`File Path: ${this.configPath}`)
224
- aiConsole.logSuccess('='.repeat(50))
225
- }
226
-
227
- // 更新扩展
228
- updateExtensions(extensions) {
229
- this.config.extensions = extensions
230
- this.writeConfig(this.config)
231
- aiConsole.logSuccess('Extensions updated successfully!')
232
- }
233
-
234
- // 删除扩展
235
- removeExtensionByIndex(extIndex) {
236
- const filePath = this.config.extensions.splice(extIndex, 1)
237
- this.writeConfig(this.config)
238
- aiConsole.logSuccess(
239
- `Extension removed from config: ${filePath}.You can run 'ai ext ls' to view the changes.`,
240
- )
241
- }
242
-
243
- removeExtensionByPath(filePath) {
244
- this.config.extensions = this.config.extensions.filter(
245
- (ext) => ext !== filePath,
246
- )
247
- this.writeConfig(this.config)
248
- aiConsole.logSuccess(
249
- `Extension removed from config: ${filePath}.You can run 'ai ext ls' to view the changes.`,
250
- )
251
- }
252
-
253
- getConfig() {
254
- const config = require(this.configPath)
255
- return lodash.merge(lodash.cloneDeep(defaultConfig), config)
256
- }
257
-
258
- getAppConfig() {
259
- const config = require(this.configPath)
260
- const mergedConfig = lodash.merge(lodash.cloneDeep(defaultConfig), config)
261
- if (mergedConfig.currentAi) {
262
- const aiConfig = mergedConfig.ai.find(
263
- (item) => item.name === mergedConfig.currentAi,
264
- )
265
- mergedConfig.aiConfig = aiConfig
266
- }
267
- return mergedConfig
268
- }
269
-
270
- // 写入配置
271
- writeConfig(config) {
272
- if (!config) {
273
- config = lodash.cloneDeep(defaultConfig)
274
- }
275
- fs.writeFileSync(
276
- this.configPath,
277
- `module.exports = ${JSON.stringify(config, null, 2)}`,
278
- )
279
- this.config = config
280
- }
281
- }
282
-
283
- module.exports = ConfigManager