ims-flow-dashboard 1.2.1 → 1.2.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.
package/README.md CHANGED
@@ -53,11 +53,14 @@ imsflow --open
53
53
 
54
54
  | 命令 | 说明 |
55
55
  |---|---|
56
- | `imsflow` | 生成 dashboard.html |
56
+ | `imsflow` | 生成 dashboard.html(零配置时自动转服务模式) |
57
57
  | `imsflow --open` | 生成并打开浏览器 |
58
58
  | `imsflow serve` | 启动本地服务(默认端口 17771) |
59
59
  | `imsflow serve --port=17772` | 指定端口 |
60
60
  | `imsflow <过滤词>` | 按名称/路径模糊匹配工作区根 |
61
+ | `imsflow --version` / `-v` | 查看版本(本地 + npm 最新比对) |
62
+ | `imsflow --update` | 更新到 npm 最新版(源码模式给出 git pull 指引) |
63
+ | `imsflow --uninstall` | 卸载命令(npm 模式 `npm uninstall -g`;源码模式清理 shell profile;`~/.imsflow` 配置保留) |
61
64
  | `imsflow --help` | 帮助 |
62
65
 
63
66
  ## 配置
package/bin/imsflow.mjs CHANGED
@@ -2,21 +2,48 @@
2
2
  import { spawn } from 'node:child_process';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import * as path from 'node:path';
5
+ import * as fs from 'node:fs';
5
6
 
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const scanScript = path.join(__dirname, '..', 'scan.mjs');
8
+ const pkgRoot = path.join(__dirname, '..');
9
+ const scanScript = path.join(pkgRoot, 'scan.mjs');
8
10
  const nodeExe = process.execPath;
9
11
  const args = process.argv.slice(2);
10
12
 
11
- if (args.includes('--help') || args.includes('-h')) {
12
- console.log(`imsflow IMS Flow 控制台
13
+ // 本地版本(package.json 随包分发, 永远和代码同步)
14
+ const VERSION = JSON.parse(fs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf8')).version;
15
+
16
+ // npm 全局安装 = 包体在 node_modules 里; 否则是源码 clone + install.mjs 的 profile 模式
17
+ const isNpmInstall = __dirname.includes(`node_modules${path.sep}`);
18
+
19
+ // Windows 下 npm 是 npm.cmd, 必须走 shell 解析
20
+ const npm = (npmArgs, opts = {}) => {
21
+ const child = spawn('npm', npmArgs, { stdio: 'inherit', shell: true, ...opts });
22
+ child.on('exit', (code) => process.exit(code ?? 0));
23
+ };
24
+
25
+ // 查 npm 远程版本(离线/未发布时静默, 不影响本地版本显示)
26
+ function remoteVersion() {
27
+ return new Promise((resolve) => {
28
+ const child = spawn('npm', ['view', 'ims-flow-dashboard', 'version'], { shell: true });
29
+ let out = '';
30
+ child.stdout.on('data', (c) => { out += c; });
31
+ child.on('error', () => resolve(null));
32
+ child.on('exit', () => resolve(out.trim() || null));
33
+ setTimeout(() => { try { child.kill(); } catch {} resolve(null); }, 8000); // 网络差时别卡住
34
+ });
35
+ }
36
+
37
+ const HELP = `imsflow — IMS Flow 控制台 (v${VERSION})
13
38
 
14
39
  用法:
15
40
  imsflow [serve] [过滤词] [--open] [--port=N]
41
+ imsflow --version | --update | --uninstall
16
42
  imsflow --help
17
43
 
18
44
  模式:
19
45
  快照模式 (默认) 生成单文件 dashboard.html,--open 自动打开浏览器
46
+ 零配置时自动转服务模式(页面「工作区」面板里添加扫描根)
20
47
  服务模式 (serve) 本地服务,页面内「重新扫描」按钮生效
21
48
  imsflow serve [--port=17771]
22
49
 
@@ -25,13 +52,62 @@ if (args.includes('--help') || args.includes('-h')) {
25
52
  <过滤词> 按名称/路径模糊匹配工作区根
26
53
  --open 生成后自动打开浏览器
27
54
  --port=<N> serve 模式端口(默认 17771)
55
+ --version, -v 显示版本(本地 + npm 最新)
56
+ --update 更新到 npm 最新版(${isNpmInstall ? 'npm 安装模式' : '当前为源码模式, 见提示'})
57
+ --uninstall 卸载 imsflow 命令并清理
28
58
  --help, -h 显示本帮助
29
59
 
30
60
  配置:
31
61
  projects.json 注册要扫描的工作区根路径(参考 projects.example.json)
32
- `);
62
+ 也可在页面顶栏「工作区」面板里添加, 自动写入配置
63
+ `;
64
+
65
+ // ---------- 子命令分发 ----------
66
+ if (args.includes('--help') || args.includes('-h')) {
67
+ console.log(HELP);
68
+ process.exit(0);
69
+ }
70
+
71
+ if (args.includes('--version') || args.includes('-v') || args.includes('version')) {
72
+ console.log(`imsflow v${VERSION} (${isNpmInstall ? 'npm 全局安装' : '源码模式'})`);
73
+ const remote = await remoteVersion();
74
+ if (remote === null) {
75
+ console.log('npm registry 不可达, 无法比对最新版本');
76
+ } else if (remote === VERSION) {
77
+ console.log(`已是最新版本 (${remote})`);
78
+ } else {
79
+ console.log(`npm 最新版本: ${remote} → 可执行 imsflow --update 更新`);
80
+ }
81
+ process.exit(0);
82
+ }
83
+
84
+ if (args.includes('--update') || args.includes('update')) {
85
+ console.log(`当前版本: v${VERSION} (${isNpmInstall ? 'npm 全局安装' : '源码模式'})`);
86
+ if (!isNpmInstall) {
87
+ console.log('\n源码 clone 模式不走 npm, 更新方式:');
88
+ console.log(' git pull');
89
+ console.log(' node install.mjs # 刷新 profile 里的命令指向');
90
+ process.exit(0);
91
+ }
92
+ console.log('\n正在更新 ims-flow-dashboard@latest ...\n');
93
+ npm(['install', '-g', 'ims-flow-dashboard@latest']);
94
+ // npm 退出码透传后不会走到这
95
+ }
96
+
97
+ if (args.includes('--uninstall') || args.includes('uninstall')) {
98
+ if (!isNpmInstall) {
99
+ // 源码模式: install.mjs 自己会清 profile 标记块
100
+ console.log('源码模式: 清理各 shell profile 中的 imsflow 命令...\n');
101
+ const child = spawn(nodeExe, [path.join(pkgRoot, 'install.mjs'), '--uninstall'], { stdio: 'inherit' });
102
+ child.on('exit', (code) => process.exit(code ?? 0));
103
+ } else {
104
+ console.log('npm 全局安装模式: 执行 npm uninstall -g ims-flow-dashboard ...\n');
105
+ console.log('(配置 ~/.imsflow/projects.json 会保留, 想彻底清理可手动删除该目录)\n');
106
+ npm(['uninstall', '-g', 'ims-flow-dashboard']);
107
+ }
33
108
  process.exit(0);
34
109
  }
35
110
 
111
+ // ---------- 默认: 透传给 scan.mjs ----------
36
112
  const child = spawn(nodeExe, [scanScript, ...args], { stdio: 'inherit' });
37
113
  child.on('exit', (code) => process.exit(code ?? 0));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ims-flow-dashboard",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "IMS Flow 控制台 — 可视化 OpenSpec 变更生命周期、产物完整性与任务进度",
5
5
  "type": "module",
6
6
  "files": [