daodou-command 1.2.2 → 1.3.0

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/.daodourc CHANGED
@@ -21,8 +21,5 @@
21
21
  defaultLang: 'en',
22
22
  defaultDir: './public/locales',
23
23
  fileName: 'common.json',
24
- // 代理相关配置
25
- proxyListUrl: 'https://free-proxy-list.net/',
26
- proxyTestUrl: 'https://httpbin.org/ip'
27
24
  },
28
25
  }
package/CHANGELOG.md CHANGED
@@ -12,6 +12,60 @@
12
12
  ### 修复
13
13
  ### 移除
14
14
 
15
+ ## [1.3.0] - 2025-09-16
16
+
17
+ ### 新增
18
+ - 添加 `dao config` 全局配置管理命令
19
+ - `dao config init` - 初始化全局配置文件
20
+ - `dao config show` - 显示当前配置信息(全局+项目+合并后)
21
+ - `dao config edit` - 编辑配置文件(支持vim等编辑器)
22
+ - `dao config clear` - 清除配置文件
23
+ - `dao config` - 交互式配置向导
24
+ - 优化配置结构,代理配置提升到全局配置
25
+ - `proxyListUrl` 和 `proxyTestUrl` 移至全局配置
26
+ - 项目配置默认不再生成代理相关配置
27
+ - 简化项目配置,减少重复配置项
28
+
29
+ ### 更改
30
+ - 默认编辑器从nano改为vim,提升编辑体验
31
+ - 配置管理更加智能和用户友好
32
+ - 全局配置和项目配置层级更清晰
33
+
34
+ ### 技术改进
35
+ - 增强配置管理功能
36
+ - 改进用户交互体验
37
+ - 优化配置文件结构
38
+
39
+ ## [1.2.3] - 2025-09-16
40
+
41
+ ### 修复
42
+ - 更新CHANGELOG.md记录1.2.2版本的完整变更内容
43
+
44
+ ## [1.2.2] - 2025-09-16
45
+
46
+ ### 新增
47
+ - 添加AI智能体开发规范文档
48
+ - 详细的命令开发指南 (COMMAND_DEVELOPMENT_GUIDE.md)
49
+ - AI快速参考卡片 (AI_QUICK_REFERENCE.md)
50
+ - 完整的代码规范和最佳实践
51
+ - 开发约束和禁止事项说明
52
+ - 智能更新提醒功能
53
+ - 后台异步检查更新,不影响命令执行性能
54
+ - 自动提醒用户有新版本可用
55
+ - 支持重复提醒,确保用户不会错过更新
56
+
57
+ ### 技术改进
58
+ - 优化后台更新检查为完全异步执行
59
+ - 使用setImmediate和setTimeout确保不阻塞主程序
60
+ - 改进错误处理和用户反馈机制
61
+ - 清理测试文件,保持项目整洁
62
+
63
+ ### 文档完善
64
+ - 为AI智能体提供详细的开发规范
65
+ - 包含项目架构、代码规范、错误处理等完整指南
66
+ - 提供快速参考和检查清单
67
+ - 明确开发约束和注意事项
68
+
15
69
  ## [1.2.0] - 2025-09-16
16
70
 
17
71
  ### 新增
package/README.md CHANGED
@@ -25,6 +25,11 @@ npm install -g daodou-command
25
25
  - 一键升级到最新版本
26
26
  - 支持强制更新和仅检查模式
27
27
 
28
+ ### ⚙️ 配置管理
29
+ - 全局配置和项目配置支持
30
+ - 交互式配置向导
31
+ - 配置文件编辑和管理
32
+
28
33
  ## 快速开始
29
34
 
30
35
  ### 构建项目
@@ -46,6 +51,21 @@ dao upgrade
46
51
  dao upgrade --force
47
52
  ```
48
53
 
54
+ ### 配置管理
55
+ ```bash
56
+ # 初始化全局配置
57
+ dao config init
58
+
59
+ # 查看当前配置
60
+ dao config show
61
+
62
+ # 编辑配置文件
63
+ dao config edit
64
+
65
+ # 清除配置文件
66
+ dao config clear
67
+ ```
68
+
49
69
  ### 多语言管理
50
70
  ```bash
51
71
  # 添加多语言项(自动翻译)
@@ -104,6 +124,16 @@ dao upgrade --force # 强制更新到最新版本
104
124
  dao upgrade --help # 查看帮助
105
125
  ```
106
126
 
127
+ ### 配置命令
128
+ ```bash
129
+ dao config # 配置管理向导
130
+ dao config init # 初始化全局配置
131
+ dao config show # 显示当前配置
132
+ dao config edit # 编辑配置文件
133
+ dao config clear # 清除配置文件
134
+ dao config --help # 查看帮助
135
+ ```
136
+
107
137
  ### 多语言命令
108
138
  ```bash
109
139
  dao lang add "key" "value" # 添加多语言项
package/bin/daodou.js CHANGED
@@ -69,6 +69,79 @@ program
69
69
  }
70
70
  });
71
71
 
72
+ // 添加 config 命令
73
+ const configCmd = program
74
+ .command('config')
75
+ .description('全局配置管理工具');
76
+
77
+ configCmd
78
+ .command('init')
79
+ .description('初始化全局配置文件')
80
+ .action(async () => {
81
+ try {
82
+ const { ConfigCommand } = require('../lib/commands/config');
83
+ const configCommand = new ConfigCommand();
84
+ await configCommand.execute('init');
85
+ } catch (error) {
86
+ console.error(chalk.red('初始化失败:'), error.message);
87
+ process.exit(1);
88
+ }
89
+ });
90
+
91
+ configCmd
92
+ .command('show')
93
+ .description('显示当前配置信息')
94
+ .action(async () => {
95
+ try {
96
+ const { ConfigCommand } = require('../lib/commands/config');
97
+ const configCommand = new ConfigCommand();
98
+ await configCommand.execute('show');
99
+ } catch (error) {
100
+ console.error(chalk.red('显示配置失败:'), error.message);
101
+ process.exit(1);
102
+ }
103
+ });
104
+
105
+ configCmd
106
+ .command('edit')
107
+ .description('编辑配置文件')
108
+ .action(async () => {
109
+ try {
110
+ const { ConfigCommand } = require('../lib/commands/config');
111
+ const configCommand = new ConfigCommand();
112
+ await configCommand.execute('edit');
113
+ } catch (error) {
114
+ console.error(chalk.red('编辑失败:'), error.message);
115
+ process.exit(1);
116
+ }
117
+ });
118
+
119
+ configCmd
120
+ .command('clear')
121
+ .description('清除配置文件')
122
+ .action(async () => {
123
+ try {
124
+ const { ConfigCommand } = require('../lib/commands/config');
125
+ const configCommand = new ConfigCommand();
126
+ await configCommand.execute('clear');
127
+ } catch (error) {
128
+ console.error(chalk.red('清除失败:'), error.message);
129
+ process.exit(1);
130
+ }
131
+ });
132
+
133
+ configCmd
134
+ .action(async () => {
135
+ try {
136
+ const { ConfigCommand } = require('../lib/commands/config');
137
+ const configCommand = new ConfigCommand();
138
+ await configCommand.execute();
139
+ } catch (error) {
140
+ console.error(chalk.red('配置操作失败:'), error.message);
141
+ process.exit(1);
142
+ }
143
+ });
144
+
72
145
  // 添加 lang 命令
73
146
  const langCmd = program
74
147
  .command('lang')
@@ -114,6 +187,12 @@ program.addHelpText('after', `
114
187
  $ dao upgrade --check # 仅检查是否有新版本
115
188
  $ dao upgrade --force # 强制更新到最新版本
116
189
 
190
+ $ dao config # 配置管理向导
191
+ $ dao config init # 初始化全局配置
192
+ $ dao config show # 显示当前配置
193
+ $ dao config edit # 编辑配置文件
194
+ $ dao config clear # 清除配置文件
195
+
117
196
  $ dao lang add "hello"
118
197
  $ dao lang add "hello" "Hello World"
119
198
  $ dao lang add "world" --lang en
@@ -0,0 +1,318 @@
1
+ const chalk = require('chalk');
2
+ const ora = require('ora');
3
+ const inquirer = require('inquirer');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+ const os = require('os');
7
+ const { ConfigManager } = require('../utils/config');
8
+
9
+ class ConfigCommand {
10
+ constructor() {
11
+ this.configManager = new ConfigManager();
12
+ }
13
+
14
+ /**
15
+ * 执行config命令
16
+ * @param {string} action - 操作类型 (init, show, edit, clear)
17
+ * @param {Object} options - 命令选项
18
+ */
19
+ async execute(action, options = {}) {
20
+ switch (action) {
21
+ case 'init':
22
+ await this.initGlobalConfig();
23
+ break;
24
+ case 'show':
25
+ await this.showConfig();
26
+ break;
27
+ case 'edit':
28
+ await this.editConfig();
29
+ break;
30
+ case 'clear':
31
+ await this.clearConfig();
32
+ break;
33
+ default:
34
+ await this.interactiveConfig();
35
+ break;
36
+ }
37
+ }
38
+
39
+ /**
40
+ * 初始化全局配置
41
+ */
42
+ async initGlobalConfig() {
43
+ console.log(chalk.blue('🔧 初始化全局配置...\n'));
44
+
45
+ // 检查是否已存在全局配置
46
+ if (fs.existsSync(this.configManager.configFile)) {
47
+ const { overwrite } = await inquirer.prompt([
48
+ {
49
+ type: 'confirm',
50
+ name: 'overwrite',
51
+ message: '全局配置文件已存在,是否覆盖?',
52
+ default: false
53
+ }
54
+ ]);
55
+
56
+ if (!overwrite) {
57
+ console.log(chalk.yellow('❌ 操作已取消'));
58
+ return;
59
+ }
60
+ }
61
+
62
+ const spinner = ora('创建全局配置...').start();
63
+
64
+ try {
65
+ // 创建全局配置目录
66
+ if (!fs.existsSync(this.configManager.configDir)) {
67
+ fs.mkdirSync(this.configManager.configDir, { recursive: true });
68
+ }
69
+
70
+ // 创建默认全局配置
71
+ await this.createDefaultGlobalConfig();
72
+
73
+ spinner.succeed('全局配置创建成功');
74
+ console.log(chalk.green(`📁 配置文件位置: ${this.configManager.configFile}`));
75
+ console.log(chalk.yellow('💡 请编辑配置文件,填写你的实际配置信息'));
76
+ console.log(chalk.blue('📖 使用 "dao config show" 查看当前配置'));
77
+ console.log(chalk.blue('📝 使用 "dao config edit" 编辑配置'));
78
+
79
+ } catch (error) {
80
+ spinner.fail('创建失败');
81
+ throw new Error(`创建全局配置失败: ${error.message}`);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * 显示当前配置
87
+ */
88
+ async showConfig() {
89
+ console.log(chalk.blue('📋 当前配置信息:\n'));
90
+
91
+ // 显示全局配置
92
+ console.log(chalk.cyan('🌍 全局配置:'));
93
+ if (fs.existsSync(this.configManager.configFile)) {
94
+ const globalConfig = this.configManager.loadConfigFile(this.configManager.configFile);
95
+ console.log(chalk.gray(` 文件位置: ${this.configManager.configFile}`));
96
+ console.log(chalk.gray(` 配置内容:`));
97
+ console.log(JSON.stringify(globalConfig, null, 4));
98
+ } else {
99
+ console.log(chalk.yellow(' ❌ 全局配置文件不存在'));
100
+ console.log(chalk.blue(' 💡 使用 "dao config init" 创建全局配置'));
101
+ }
102
+
103
+ console.log();
104
+
105
+ // 显示项目配置
106
+ console.log(chalk.cyan('📁 项目配置:'));
107
+ if (fs.existsSync(this.configManager.projectConfigFile)) {
108
+ const projectConfig = this.configManager.loadConfigFile(this.configManager.projectConfigFile);
109
+ console.log(chalk.gray(` 文件位置: ${this.configManager.projectConfigFile}`));
110
+ console.log(chalk.gray(` 配置内容:`));
111
+ console.log(JSON.stringify(projectConfig, null, 4));
112
+ } else {
113
+ console.log(chalk.yellow(' ❌ 项目配置文件不存在'));
114
+ console.log(chalk.blue(' 💡 运行 build 命令时会自动创建'));
115
+ }
116
+
117
+ console.log();
118
+
119
+ // 显示合并后的配置
120
+ console.log(chalk.cyan('🔀 合并后配置 (项目配置优先):'));
121
+ const mergedConfig = this.configManager.getAll();
122
+ console.log(JSON.stringify(mergedConfig, null, 4));
123
+ }
124
+
125
+ /**
126
+ * 编辑配置
127
+ */
128
+ async editConfig() {
129
+ console.log(chalk.blue('📝 编辑配置...\n'));
130
+
131
+ const { configType } = await inquirer.prompt([
132
+ {
133
+ type: 'list',
134
+ name: 'configType',
135
+ message: '选择要编辑的配置文件:',
136
+ choices: [
137
+ {
138
+ name: '全局配置 (推荐)',
139
+ value: 'global',
140
+ disabled: !fs.existsSync(this.configManager.configFile) ? '文件不存在' : false
141
+ },
142
+ {
143
+ name: '项目配置',
144
+ value: 'project',
145
+ disabled: !fs.existsSync(this.configManager.projectConfigFile) ? '文件不存在' : false
146
+ }
147
+ ]
148
+ }
149
+ ]);
150
+
151
+ const configFile = configType === 'global'
152
+ ? this.configManager.configFile
153
+ : this.configManager.projectConfigFile;
154
+
155
+ console.log(chalk.blue(`📁 配置文件位置: ${configFile}`));
156
+ console.log(chalk.yellow('💡 请使用你喜欢的编辑器打开该文件进行编辑'));
157
+
158
+ // 尝试打开默认编辑器
159
+ const { openEditor } = await inquirer.prompt([
160
+ {
161
+ type: 'confirm',
162
+ name: 'openEditor',
163
+ message: '是否使用默认编辑器打开文件?',
164
+ default: true
165
+ }
166
+ ]);
167
+
168
+ if (openEditor) {
169
+ const editor = process.env.EDITOR || process.env.VISUAL || 'vim';
170
+ const { spawn } = require('child_process');
171
+
172
+ try {
173
+ const child = spawn(editor, [configFile], { stdio: 'inherit' });
174
+ child.on('exit', (code) => {
175
+ if (code === 0) {
176
+ console.log(chalk.green('✅ 配置编辑完成'));
177
+ } else {
178
+ console.log(chalk.yellow('⚠️ 编辑器退出,请手动检查配置'));
179
+ }
180
+ });
181
+ } catch (error) {
182
+ console.log(chalk.red(`❌ 无法打开编辑器: ${error.message}`));
183
+ console.log(chalk.yellow('请手动编辑配置文件'));
184
+ }
185
+ }
186
+ }
187
+
188
+ /**
189
+ * 清除配置
190
+ */
191
+ async clearConfig() {
192
+ console.log(chalk.blue('🗑️ 清除配置...\n'));
193
+
194
+ const { configType } = await inquirer.prompt([
195
+ {
196
+ type: 'list',
197
+ name: 'configType',
198
+ message: '选择要清除的配置:',
199
+ choices: [
200
+ {
201
+ name: '全局配置',
202
+ value: 'global',
203
+ disabled: !fs.existsSync(this.configManager.configFile) ? '文件不存在' : false
204
+ },
205
+ {
206
+ name: '项目配置',
207
+ value: 'project',
208
+ disabled: !fs.existsSync(this.configManager.projectConfigFile) ? '文件不存在' : false
209
+ },
210
+ {
211
+ name: '所有配置',
212
+ value: 'all'
213
+ }
214
+ ]
215
+ }
216
+ ]);
217
+
218
+ const { confirm } = await inquirer.prompt([
219
+ {
220
+ type: 'confirm',
221
+ name: 'confirm',
222
+ message: '确定要删除配置吗?此操作不可恢复!',
223
+ default: false
224
+ }
225
+ ]);
226
+
227
+ if (!confirm) {
228
+ console.log(chalk.yellow('❌ 操作已取消'));
229
+ return;
230
+ }
231
+
232
+ const spinner = ora('清除配置...').start();
233
+
234
+ try {
235
+ if (configType === 'global' || configType === 'all') {
236
+ if (fs.existsSync(this.configManager.configFile)) {
237
+ fs.unlinkSync(this.configManager.configFile);
238
+ console.log(chalk.green('✅ 全局配置已删除'));
239
+ }
240
+ }
241
+
242
+ if (configType === 'project' || configType === 'all') {
243
+ if (fs.existsSync(this.configManager.projectConfigFile)) {
244
+ fs.unlinkSync(this.configManager.projectConfigFile);
245
+ console.log(chalk.green('✅ 项目配置已删除'));
246
+ }
247
+ }
248
+
249
+ spinner.succeed('配置清除完成');
250
+
251
+ } catch (error) {
252
+ spinner.fail('清除失败');
253
+ throw new Error(`清除配置失败: ${error.message}`);
254
+ }
255
+ }
256
+
257
+ /**
258
+ * 交互式配置向导
259
+ */
260
+ async interactiveConfig() {
261
+ console.log(chalk.blue('🎯 配置向导\n'));
262
+
263
+ const { action } = await inquirer.prompt([
264
+ {
265
+ type: 'list',
266
+ name: 'action',
267
+ message: '请选择操作:',
268
+ choices: [
269
+ { name: '初始化全局配置', value: 'init' },
270
+ { name: '查看当前配置', value: 'show' },
271
+ { name: '编辑配置文件', value: 'edit' },
272
+ { name: '清除配置', value: 'clear' },
273
+ { name: '退出', value: 'exit' }
274
+ ]
275
+ }
276
+ ]);
277
+
278
+ if (action === 'exit') {
279
+ console.log(chalk.yellow('👋 再见!'));
280
+ return;
281
+ }
282
+
283
+ await this.execute(action);
284
+ }
285
+
286
+ /**
287
+ * 创建默认全局配置
288
+ */
289
+ async createDefaultGlobalConfig() {
290
+ const configContent = `{
291
+ // build 命令全局配置
292
+ build: {
293
+ // Jenkins 基础配置 (可选,项目配置优先)
294
+ // jenkinsUrl: "https://your-company-jenkins.com/",
295
+ // jenkinsBase: "https://your-company-jenkins.com/job",
296
+ // jenkinsToken: "your-global-token",
297
+ // jenkinsUsername: "your-global-username",
298
+ // jenkinsPassword: "your-global-password"
299
+ },
300
+
301
+ // lang 命令全局配置
302
+ lang: {
303
+ defaultLang: "en",
304
+ defaultDir: "./public/locales",
305
+ fileName: "common.json",
306
+ // 代理相关配置(全局默认)
307
+ proxyListUrl: "https://free-proxy-list.net/",
308
+ proxyTestUrl: "https://httpbin.org/ip"
309
+ }
310
+ }`;
311
+
312
+ fs.writeFileSync(this.configManager.configFile, configContent);
313
+ }
314
+ }
315
+
316
+ module.exports = {
317
+ ConfigCommand
318
+ };
@@ -206,10 +206,7 @@ class ConfigManager {
206
206
  lang: {
207
207
  defaultLang: "en",
208
208
  defaultDir: "./public/locales",
209
- fileName: "common.json",
210
- // 代理相关配置
211
- proxyListUrl: "https://free-proxy-list.net/",
212
- proxyTestUrl: "https://httpbin.org/ip"
209
+ fileName: "common.json"
213
210
  }
214
211
  }`;
215
212
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "daodou-command",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "刀豆命令行工具 - 自动化构建和部署",
5
5
  "main": "index.js",
6
6
  "bin": {