@wanggangqi/workspace-cli 1.0.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/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # Workspace CLI
2
+
3
+ 工作空间管理 CLI 工具,用于初始化、扫描和管理工作空间下的多个 Git 项目。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install -g @wanggangqi/workspace-cli
9
+ ```
10
+
11
+ 或者使用 npx:
12
+
13
+ ```bash
14
+ npx @wanggangqi/workspace-cli init
15
+ ```
16
+
17
+ ## 功能特性
18
+
19
+ - 🚀 快速初始化工作空间
20
+ - 🔍 自动扫描 Git 项目
21
+ - 📁 分组管理项目
22
+ - 📝 智能项目描述
23
+ - 🔄 批量克隆仓库
24
+ - 🌿 分支信息管理
25
+ - 🌐 一键初始化 Nginx 环境(多空间隔离)
26
+
27
+ ## 命令说明
28
+
29
+ ### `wsc init` 或 `workspace-cli init`
30
+
31
+ 初始化工作空间,创建 `.workspace/config.json` 配置文件。
32
+
33
+ ```bash
34
+ # 在当前目录初始化工作空间
35
+ workspace-cli init
36
+
37
+ # 创建新目录并初始化为工作空间
38
+ workspace-cli init my-workspace
39
+
40
+ # 指定 AI 编辑器生成对应的 prompt 文件
41
+ workspace-cli init my-workspace --ai claude-code
42
+ workspace-cli init my-workspace --ai trae
43
+ workspace-cli init my-workspace --ai opencode
44
+ workspace-cli init my-workspace --ai iflow
45
+ ```
46
+
47
+ **参数说明:**
48
+
49
+ - `directory` (可选): 要创建的工作空间目录名称。如果不指定,则在当前目录初始化;如果指定,则创建该目录并初始化。
50
+ - `--ai <editor>` (可选): 指定 AI 编辑器类型,生成对应的 prompt 文件。支持: `claude-code`, `trae`, `opencode`, `iflow`
51
+
52
+ **默认配置:**
53
+ 初始化时会自动从包自带的 `config.json` 加载默认配置:
54
+
55
+ - `平台组` - 包含预配置的仓库列表(erdcloud-plat-frontend, erdcloud-plat-plugins-frontend 等)
56
+ - `other` - 未分组(空列表)
57
+
58
+ **生成的 Prompt 文件:**
59
+
60
+ | AI 编辑器 | 生成的文件路径 |
61
+ | ----------- | --------------------- |
62
+ | claude-code | `CLAUDE.md` |
63
+ | trae | `.trae/prompt.md` |
64
+ | opencode | `.opencode/prompt.md` |
65
+ | iflow | `.iflow/prompt.md` |
66
+
67
+ > 注意:工具使用通用的 `prompts/prompt.md` 模板,根据 `--ai` 参数自动复制并重命名为对应编辑器需要的文件名。
68
+
69
+ **使用示例:**
70
+
71
+ ```bash
72
+ # 创建一个新项目空间(带 Claude Code 支持)
73
+ workspace-cli init plat-workspace --ai claude-code
74
+ cd plat-workspace
75
+
76
+ # 现在可以用自然语言命令:
77
+ # "将平台组的所有项目克隆下来"
78
+ ```
79
+
80
+ ### `wsc scan` 或 `workspace-cli scan`
81
+
82
+ 扫描工作空间下的所有 Git 项目,并更新到配置文件中。
83
+
84
+ ```bash
85
+ # 交互式扫描(默认)
86
+ workspace-cli scan
87
+
88
+ # 非交互式,自动添加到 other 分组
89
+ workspace-cli scan --no-interactive
90
+ ```
91
+
92
+ **说明:**
93
+
94
+ - 自动向上查找 `.workspace/config.json`,在工作空间根目录下扫描
95
+ - 对于新发现的项目,会交互式询问分组和描述
96
+ - 对于已存在的项目,会自动更新分支信息
97
+
98
+ ### `wsc list` 或 `workspace-cli list`
99
+
100
+ 列出工作空间中的所有项目。
101
+
102
+ ```bash
103
+ # 列出所有项目
104
+ workspace-cli list
105
+
106
+ # 只列出指定分组的项目
107
+ workspace-cli list -g 平台组
108
+ ```
109
+
110
+ ### `wsc add` 或 `workspace-cli add`
111
+
112
+ 手动添加项目到工作空间。
113
+
114
+ ```bash
115
+ workspace-cli add erdcloud-plat-frontend \
116
+ --url http://gitlab.example.com/erdcloud-plat-frontend.git \
117
+ --group 平台组 \
118
+ --branch develop \
119
+ --description "平台前端项目"
120
+ ```
121
+
122
+ ### `wsc remove` 或 `workspace-cli remove`
123
+
124
+ 从工作空间移除项目。
125
+
126
+ ```bash
127
+ workspace-cli remove test-materials
128
+ ```
129
+
130
+ ### `wsc clone-all` 或 `workspace-cli clone-all`
131
+
132
+ 克隆配置文件中所有的仓库到当前目录。
133
+
134
+ ```bash
135
+ # 克隆所有仓库
136
+ workspace-cli clone-all
137
+
138
+ # 只克隆指定分组的仓库
139
+ workspace-cli clone-all -g 平台组
140
+ ```
141
+
142
+ ### `wsc nginx` 或 `workspace-cli nginx`
143
+
144
+ 管理 nginx 配置和启动,用于本地开发环境。支持多空间隔离,每个工作空间拥有独立的 nginx 实例。
145
+
146
+ #### `wsc nginx init`
147
+
148
+ 初始化当前工作空间的 nginx 环境。自动下载 nginx Windows 绿色版,复制所有配置文件,**解决多空间 nginx 冲突问题**。
149
+
150
+ ```bash
151
+ # 初始化 nginx(默认版本 1.24.0)
152
+ wsc nginx init
153
+
154
+ # 指定 nginx 版本
155
+ wsc nginx init -v 1.26.0
156
+
157
+ # 指定代理后端地址(默认 http://192.168.10.189)
158
+ wsc nginx init -p http://192.168.1.100:8080
159
+
160
+ # 跳过下载,只生成配置文件
161
+ wsc nginx init --skip-download
162
+ ```
163
+
164
+ **功能说明:**
165
+
166
+ 1. **自动分配独立端口**:扫描同一目录下的其他工作空间,自动分配未被使用的端口段(默认从 50000 开始,每个空间间隔 1000)
167
+ 2. **下载 nginx**:从 nginx.org 自动下载 Windows 绿色版
168
+ 3. **生成配置结构**:
169
+ - `.workspace/nginx/nginx-{version}/` - nginx 程序目录
170
+ - `.workspace/nginx/conf.d/` - 项目配置文件目录(自动复制所有 .conf 文件)
171
+ - `.workspace/nginx/logs/` - 独立日志目录
172
+ 4. **复制管理脚本**:复制并修改 `nginx-config/` 下的 PowerShell 脚本
173
+ - `start-nginx.ps1` - 启动脚本(使用工作空间的 nginx)
174
+ - `stop-nginx.ps1` - 停止脚本
175
+ - `reload-nginx.ps1` - 重载配置脚本
176
+ - `status-nginx.ps1` - 状态检查脚本
177
+
178
+ 5. **生成工作空间域名**:根据目录名自动生成域名(如 `my-project` → `my-project.local`)
179
+
180
+ 6. **替换配置占位符**:自动替换配置文件中的占位符
181
+ - `<servename>` → 工作空间域名(如 `my-project.local`)
182
+ - `<workspaceDir>` → 工作空间根目录路径
183
+ - `<proxyTarget>` → 代理后端接口地址(默认 `http://192.168.10.189`)
184
+
185
+ **配置文件更新:**
186
+
187
+ 初始化后会在 `.workspace/config.json` 中添加 nginx 配置:
188
+
189
+ ```json
190
+ {
191
+ "nginx": {
192
+ "version": "1.24.0",
193
+ "basePort": 50000,
194
+ "domain": "my-project.local",
195
+ "proxyTarget": "http://192.168.10.189",
196
+ "installed": true,
197
+ "binDir": "...",
198
+ "configDir": "...",
199
+ "logsDir": "...",
200
+ "configs": [...]
201
+ }
202
+ }
203
+ ```
204
+
205
+ **域名配置:**
206
+
207
+ 初始化完成后,需要将自动生成的域名添加到 hosts 文件:
208
+
209
+ ```
210
+ # Windows: C:\Windows\System32\drivers\etc\hosts
211
+ 127.0.0.1 my-project.local
212
+ ```
213
+
214
+ 工具会自动生成辅助脚本 `.workspace/add-to-hosts.ps1`,以管理员身份运行它可以自动添加域名:
215
+
216
+ ```powershell
217
+ # 以管理员身份运行 PowerShell,然后执行
218
+ . .workspace/add-to-hosts.ps1
219
+ ```
220
+
221
+ **nginx 配置示例:**
222
+
223
+ 在 `nginx-config/` 目录下的 `.conf` 文件可以使用以下占位符:
224
+
225
+ ```nginx
226
+ server {
227
+ listen 5006;
228
+ server_name <servename>; # 将替换为 my-project.local
229
+
230
+ location / {
231
+ root <workspaceDir>/dist; # 将替换为工作空间根目录
232
+ index index.html;
233
+ }
234
+
235
+ location /api {
236
+ proxy_pass <proxyTarget>; # 将替换为 http://192.168.10.189
237
+ }
238
+ }
239
+ ```
240
+
241
+ 配置完成后,即可通过域名访问:
242
+
243
+ - `http://my-project.local:5006` (具体端口取决于配置)
244
+
245
+ ---
246
+
247
+ #### `wsc nginx start`
248
+
249
+ 启动当前工作空间的 nginx。
250
+
251
+ ```bash
252
+ wsc nginx start
253
+ ```
254
+
255
+ ---
256
+
257
+ #### `wsc nginx stop`
258
+
259
+ 停止当前工作空间的 nginx。
260
+
261
+ ```bash
262
+ wsc nginx stop
263
+ ```
264
+
265
+ ---
266
+
267
+ #### `wsc nginx reload`
268
+
269
+ 重新加载当前工作空间的 nginx 配置。
270
+
271
+ ```bash
272
+ wsc nginx reload
273
+ ```
274
+
275
+ ---
276
+
277
+ #### `wsc nginx status`
278
+
279
+ 查看当前工作空间的 nginx 状态。
280
+
281
+ ```bash
282
+ wsc nginx status
283
+ ```
284
+
285
+ ---
286
+
287
+ #### `wsc nginx list`
288
+
289
+ 列出所有可用的 nginx 配置模板。
290
+
291
+ ```bash
292
+ wsc nginx list
293
+ ```
294
+
295
+ ---
296
+
297
+ **多空间隔离机制:**
298
+
299
+ | 空间 | 基础端口 | 进程隔离 |
300
+ | ----------- | -------- | -------- |
301
+ | workspace-a | 50000 | 独立进程 |
302
+ | workspace-b | 51000 | 独立进程 |
303
+ | workspace-c | 52000 | 独立进程 |
304
+
305
+ **注意事项:**
306
+
307
+ - 每个工作空间的 nginx 使用独立的 `pid` 文件,避免进程冲突
308
+ - 配置文件通过 `include` 加载 `conf.d/` 下的所有 `.conf` 文件
309
+ - 启动前会自动检查配置是否正确
310
+ - 停止时只停止当前工作空间的 nginx 进程
311
+
312
+ **完整使用流程:**
313
+
314
+ ```bash
315
+ # 1. 创建工作空间
316
+ wsc init my-project --ai claude-code
317
+ cd my-project
318
+
319
+ # 2. 初始化 nginx
320
+ wsc nginx init
321
+
322
+ # 3. 启动当前空间的 nginx
323
+ wsc nginx start
324
+
325
+ # 4. 查看状态
326
+ wsc nginx status
327
+
328
+ # 5. 修改配置后重载
329
+ wsc nginx reload
330
+
331
+ # 6. 停止 nginx
332
+ wsc nginx stop
333
+ ```
334
+
335
+ **或者直接使用 PowerShell 脚本:**
336
+
337
+ ```powershell
338
+ # 使用 PowerShell Core (pwsh) 执行(需要设置执行策略)
339
+ pwsh -ExecutionPolicy Bypass -File .workspace/nginx/start-nginx.ps1
340
+ pwsh -ExecutionPolicy Bypass -File .workspace/nginx/stop-nginx.ps1
341
+ pwsh -ExecutionPolicy Bypass -File .workspace/nginx/reload-nginx.ps1
342
+ pwsh -ExecutionPolicy Bypass -File .workspace/nginx/status-nginx.ps1
343
+ ```
344
+
345
+ ## 配置文件结构
346
+
347
+ `.workspace/config.json`:
348
+
349
+ ```json
350
+ {
351
+ "version": "1.0",
352
+ "groups": {
353
+ "平台组": {
354
+ "code": "plat",
355
+ "description": "平台相关仓库集合",
356
+ "repos": [
357
+ {
358
+ "name": "erdcloud-plat-frontend",
359
+ "url": "http://gitlab.example.com/erdcloud-plat-frontend.git",
360
+ "descriptions": ["平台前端", "plat前端"],
361
+ "branch": "develop"
362
+ }
363
+ ]
364
+ }
365
+ },
366
+ "nginx": {
367
+ "version": "1.24.0",
368
+ "basePort": 50000,
369
+ "installed": true,
370
+ "binDir": ".workspace/nginx/nginx-1.24.0",
371
+ "configDir": ".workspace/nginx/conf.d",
372
+ "logsDir": ".workspace/nginx/logs",
373
+ "configs": [{ "name": "5006_plat", "file": "5006_plat.conf", "port": 5006 }]
374
+ }
375
+ }
376
+ ```
377
+
378
+ ## 在 Claude 中使用
379
+
380
+ 将 `prompt.md` 中的内容添加到 Claude Code 的 Agent.md 中,即可使用命令管理工作空间:
381
+
382
+ ```
383
+ ws:scan # 扫描工作空间
384
+ ws:list # 列出所有项目
385
+ ws:clone 平台组 # 克隆平台组的所有仓库
386
+ ws:nginx init # 初始化 nginx 环境
387
+ ws:nginx start # 启动当前空间的 nginx
388
+ ws:nginx stop # 停止当前空间的 nginx
389
+ ws:nginx reload # 重载 nginx 配置
390
+ ws:nginx status # 查看 nginx 状态
391
+ ```
392
+
393
+ ### 可用命令
394
+
395
+ | 命令 | 描述 | 示例 |
396
+ | -------------------- | ----------------------------------- | ------------------------------------------ |
397
+ | `ws:scan` | 扫描当前目录的 Git 项目,同步到配置 | `ws:scan` |
398
+ | `ws:list` | 列出工作空间中的所有项目 | `ws:list`、 `ws:list -g 平台组` |
399
+ | `ws:clone [分组名]` | 克隆指定分组的所有仓库 | `ws:clone`、`ws:clone 平台组` |
400
+ | `ws:add <项目名>` | 添加项目到工作空间 | `ws:add my-project` |
401
+ | `ws:remove <项目名>` | 从工作空间移除项目 | `ws:remove my-project` |
402
+ | `ws:nginx init` | 初始化当前工作空间的 Nginx 环境 | `ws:nginx init`、`ws:nginx init -v 1.26.0` |
403
+ | `ws:nginx start` | 启动当前空间的 nginx | `ws:nginx start` |
404
+ | `ws:nginx stop` | 停止当前空间的 nginx | `ws:nginx stop` |
405
+ | `ws:nginx reload` | 重载当前空间的 nginx 配置 | `ws:nginx reload` |
406
+ | `ws:nginx status` | 查看当前空间的 nginx 状态 | `ws:nginx status` |
407
+
408
+ ## License
409
+
410
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require('commander');
4
+ const chalk = require('chalk');
5
+ const WorkspaceManager = require('../lib/workspace');
6
+
7
+ const program = new Command();
8
+ const workspace = new WorkspaceManager();
9
+
10
+ program
11
+ .name('workspace-cli')
12
+ .description('工作空间管理 CLI 工具')
13
+ .version('1.0.0');
14
+
15
+ program
16
+ .command('init [directory]')
17
+ .description('初始化工作空间,创建 .workspace/config.json。如果指定目录,则创建该目录并初始化。')
18
+ .option('--ai <editor>', '指定 AI 编辑器类型,生成对应的 prompt 文件 (claude-code|trae|opencode|iflow)')
19
+ .action(async (directory, options) => {
20
+ try {
21
+ await workspace.init(directory, options.ai);
22
+ } catch (error) {
23
+ console.error(chalk.red('初始化失败:'), error.message);
24
+ process.exit(1);
25
+ }
26
+ });
27
+
28
+ program
29
+ .command('scan')
30
+ .description('扫描当前目录下的 Git 项目,更新配置文件')
31
+ .option('-i, --interactive', '交互式模式,询问项目描述', true)
32
+ .action(async (options) => {
33
+ try {
34
+ await workspace.scan(options.interactive);
35
+ } catch (error) {
36
+ console.error(chalk.red('扫描失败:'), error.message);
37
+ process.exit(1);
38
+ }
39
+ });
40
+
41
+ program
42
+ .command('list')
43
+ .alias('ls')
44
+ .description('列出工作空间中的所有项目')
45
+ .option('-g, --group <group>', '按分组筛选')
46
+ .action(async (options) => {
47
+ try {
48
+ await workspace.list(options.group);
49
+ } catch (error) {
50
+ console.error(chalk.red('列表获取失败:'), error.message);
51
+ process.exit(1);
52
+ }
53
+ });
54
+
55
+ program
56
+ .command('add <name>')
57
+ .description('添加项目到工作空间')
58
+ .requiredOption('-u, --url <url>', 'Git 仓库地址')
59
+ .option('-g, --group <group>', '所属分组', 'other')
60
+ .option('-b, --branch <branch>', '默认分支', 'main')
61
+ .option('-d, --description <description>', '项目描述')
62
+ .action(async (name, options) => {
63
+ try {
64
+ await workspace.add(name, options);
65
+ } catch (error) {
66
+ console.error(chalk.red('添加失败:'), error.message);
67
+ process.exit(1);
68
+ }
69
+ });
70
+
71
+ program
72
+ .command('remove <name>')
73
+ .alias('rm')
74
+ .description('从工作空间移除项目')
75
+ .action(async (name) => {
76
+ try {
77
+ await workspace.remove(name);
78
+ } catch (error) {
79
+ console.error(chalk.red('移除失败:'), error.message);
80
+ process.exit(1);
81
+ }
82
+ });
83
+
84
+ program
85
+ .command('clone-all')
86
+ .description('克隆所有配置的仓库到当前目录')
87
+ .option('-g, --group <group>', '只克隆指定分组的仓库')
88
+ .action(async (options) => {
89
+ try {
90
+ await workspace.cloneAll(options.group);
91
+ } catch (error) {
92
+ console.error(chalk.red('克隆失败:'), error.message);
93
+ process.exit(1);
94
+ }
95
+ });
96
+
97
+ // nginx 命令组
98
+ const nginxCmd = program
99
+ .command('nginx')
100
+ .description('管理 nginx 配置和启动');
101
+
102
+ nginxCmd
103
+ .command('init')
104
+ .description('初始化当前工作空间的 nginx 环境')
105
+ .option('-v, --version <version>', '指定 nginx 版本', '1.24.0')
106
+ .option('-p, --proxy-target <url>', '代理后端接口地址', 'http://192.168.10.189')
107
+ .option('--skip-download', '跳过下载,只生成配置文件')
108
+ .action(async (options) => {
109
+ try {
110
+ await workspace.initNginx(options);
111
+ } catch (error) {
112
+ console.error(chalk.red('nginx 初始化失败:'), error.message);
113
+ process.exit(1);
114
+ }
115
+ });
116
+
117
+ nginxCmd
118
+ .command('start')
119
+ .description('启动当前工作空间的 nginx')
120
+ .action(async () => {
121
+ try {
122
+ await workspace.manageSpaceNginx({ start: true });
123
+ } catch (error) {
124
+ console.error(chalk.red('nginx 启动失败:'), error.message);
125
+ process.exit(1);
126
+ }
127
+ });
128
+
129
+ nginxCmd
130
+ .command('stop')
131
+ .description('停止当前工作空间的 nginx')
132
+ .action(async () => {
133
+ try {
134
+ await workspace.manageSpaceNginx({ stop: true });
135
+ } catch (error) {
136
+ console.error(chalk.red('nginx 停止失败:'), error.message);
137
+ process.exit(1);
138
+ }
139
+ });
140
+
141
+ nginxCmd
142
+ .command('reload')
143
+ .description('重新加载当前工作空间的 nginx 配置')
144
+ .action(async () => {
145
+ try {
146
+ await workspace.manageSpaceNginx({ reload: true });
147
+ } catch (error) {
148
+ console.error(chalk.red('nginx 重载失败:'), error.message);
149
+ process.exit(1);
150
+ }
151
+ });
152
+
153
+ nginxCmd
154
+ .command('status')
155
+ .description('查看当前工作空间的 nginx 状态')
156
+ .action(async () => {
157
+ try {
158
+ await workspace.manageSpaceNginx({ status: true });
159
+ } catch (error) {
160
+ console.error(chalk.red('nginx 状态检查失败:'), error.message);
161
+ process.exit(1);
162
+ }
163
+ });
164
+
165
+ nginxCmd
166
+ .command('list')
167
+ .description('列出可用的 nginx 配置')
168
+ .action(async () => {
169
+ try {
170
+ await workspace.listNginxConfigs();
171
+ } catch (error) {
172
+ console.error(chalk.red('列出配置失败:'), error.message);
173
+ process.exit(1);
174
+ }
175
+ });
176
+
177
+ program.parse();
package/config.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "version": "1.0",
3
+ "groups": {
4
+ "平台组": {
5
+ "code": "plat",
6
+ "description": "易立德(公司)平台的仓库集合",
7
+ "repos": [
8
+ {
9
+ "name": "erdcloud-plat-frontend",
10
+ "url": "http://gitlab.ddns.e-lead.cn/erdcloud-plm/erdcloud-plat/erdcloud-plat-frontend.git",
11
+ "descriptions": [
12
+ "平台前端",
13
+ "平台仓库",
14
+ "plat前端"
15
+ ],
16
+ "branch": "develop"
17
+ },
18
+ {
19
+ "name": "erdcloud-plat-plugins-frontend",
20
+ "url": "http://gitlab.ddns.e-lead.cn/erdcloud-plm/erdcloud-plat/erdcloud-plat-plugins-frontend.git",
21
+ "descriptions": [
22
+ "插件前端",
23
+ "平台仓库",
24
+ "plat插件前端"
25
+ ],
26
+ "branch": "develop"
27
+ }
28
+ ]
29
+ },
30
+ "other": {
31
+ "code": "other",
32
+ "description": "未分组",
33
+ "repos": [{
34
+ "name": "test-materials",
35
+ "url": "http://gitlab.ddns.e-lead.cn/erdcloud-plm/erdcloud-plat/erdcloud-plat-test/test-materials.git",
36
+ "descriptions": ["测试仓库"],
37
+ "branch": "master"
38
+ }]
39
+ }
40
+ }
41
+ }