@wwkit/opm 1.0.9 → 1.0.10
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 +21 -4
- package/docs/managers/nvm.md +2 -0
- package/docs/managers/phpenv.md +2 -0
- package/docs/managers/uv.md +2 -0
- package/docs/opm.html +6 -3
- package/package.json +3 -3
- package/src/cli/groups/ensure.js +25 -4
- package/src/cli/groups/nvm.js +5 -1
- package/src/cli/groups/phpenv.js +5 -1
- package/src/cli/groups/uv.js +5 -1
- package/src/cli/groups/version-manager.js +27 -0
- package/src/cli/index.js +2 -0
- package/src/harnesses/base.js +88 -20
- package/src/harnesses/harness/index.js +132 -0
- package/src/index.js +1 -0
- package/src/managers/node.js +17 -8
- package/src/managers/php.js +17 -8
- package/src/managers/python.js +18 -8
- package/src/tools/webwork/index.js +132 -463
package/README.md
CHANGED
|
@@ -52,11 +52,11 @@ pnpm opm <command> [args] [options]
|
|
|
52
52
|
| `composer <action>` | composer 包管理器(PHP) |
|
|
53
53
|
| `bun <action>` | bun 包管理器(Bun runtime,npm 兼容源) |
|
|
54
54
|
| `winget <action>` | winget 包管理器(Windows) |
|
|
55
|
-
| `nvm <action>` | nvm 自身管理(安装/升级/卸载 nvm
|
|
55
|
+
| `nvm <action>` | nvm 自身管理(安装/升级/卸载 nvm;list 列出已安装 Node.js 版本) |
|
|
56
56
|
| `node <action>` | node 版本管理(基于 nvm 安装/切换/卸载 Node.js 版本) |
|
|
57
|
-
| `phpenv <action>` | phpenv 自身管理(安装/升级/卸载 phpenv
|
|
57
|
+
| `phpenv <action>` | phpenv 自身管理(安装/升级/卸载 phpenv;list 列出已安装 PHP 版本) |
|
|
58
58
|
| `php <action>` | php 版本管理(基于 phpenv 安装/切换/卸载 PHP 版本) |
|
|
59
|
-
| `uv <action>` | uv 自身管理(安装/升级/卸载 uv
|
|
59
|
+
| `uv <action>` | uv 自身管理(安装/升级/卸载 uv;list 列出已安装 Python 版本) |
|
|
60
60
|
| `python <action>` | python 版本管理(基于 uv 安装/切换/卸载 Python 版本) |
|
|
61
61
|
| `docker <action>` | Docker 自身管理(安装/升级/启停/open,含 daemon 状态) |
|
|
62
62
|
| `homebrew <action>` | Homebrew 自身管理(安装/升级/卸载 brew) |
|
|
@@ -69,6 +69,7 @@ pnpm opm <command> [args] [options]
|
|
|
69
69
|
| `ping <host|proxy|registry>` | 验证主机、代理或所有 registry 的可访问性 |
|
|
70
70
|
| `config [section]` | 查看常用配置(proxy + 各 registry 段,段名动态生成) |
|
|
71
71
|
| `opencode <action>` | opencode 运维命令(安装/升级/清理/env/open) |
|
|
72
|
+
| `harness <action>` | @wwkit/harness 插件管理(安装/升级/list/status/env/dir) |
|
|
72
73
|
|
|
73
74
|
## Managers
|
|
74
75
|
|
|
@@ -100,7 +101,7 @@ pnpm opm <command> [args] [options]
|
|
|
100
101
|
| `view <name>` | 查询包在全局与项目作用域的安装信息(仅包管理器;运行时查询版本是否已安装) |
|
|
101
102
|
| `info <name>` | 查询包详情 |
|
|
102
103
|
| `versions <name>` | 列出所有可用版本 |
|
|
103
|
-
| `list` |
|
|
104
|
+
| `list` | 列出所有已安装包(仅运行时 node/php/python 与工具组 nvm/phpenv/uv 支持) |
|
|
104
105
|
| `outdated` | 列出过期包 |
|
|
105
106
|
| `install <name> [version]` | 安装包 |
|
|
106
107
|
| `uninstall <name>` | 卸载包 |
|
|
@@ -280,6 +281,7 @@ opm nvm version # 查看 nvm 版本
|
|
|
280
281
|
opm nvm registry set gitee # 设置 nvm git 镜像为 gitee
|
|
281
282
|
opm nvm install # 安装 nvm(git clone + shell profile)
|
|
282
283
|
opm nvm upgrade # 更新 nvm(git pull)
|
|
284
|
+
opm nvm list # 列出已安装 Node.js 版本
|
|
283
285
|
opm nvm view # 检查 nvm 是否已安装
|
|
284
286
|
opm nvm uninstall # 卸载 nvm
|
|
285
287
|
```
|
|
@@ -308,6 +310,7 @@ opm phpenv version # 查看 phpenv 版本
|
|
|
308
310
|
opm phpenv registry set gitee # 设置 phpenv git 镜像为 gitee
|
|
309
311
|
opm phpenv install # 安装 phpenv(git clone + php-build 插件 + shell profile)
|
|
310
312
|
opm phpenv upgrade # 更新 phpenv + php-build 插件
|
|
313
|
+
opm phpenv list # 列出已安装 PHP 版本
|
|
311
314
|
opm phpenv view # 检查 phpenv 是否已安装
|
|
312
315
|
opm phpenv uninstall # 卸载 phpenv
|
|
313
316
|
```
|
|
@@ -336,6 +339,7 @@ opm uv registry set <url|preset> # 设置安装脚本 URL(写 uv.registry
|
|
|
336
339
|
opm uv registry presets # 列出可用镜像预设
|
|
337
340
|
opm uv install # 安装 uv(curl 执行 active 脚本 URL)
|
|
338
341
|
opm uv upgrade # 更新 uv(uv self update)
|
|
342
|
+
opm uv list # 列出已安装 Python 版本
|
|
339
343
|
opm uv view # 检查 uv 是否已安装
|
|
340
344
|
opm uv uninstall # 卸载 uv
|
|
341
345
|
```
|
|
@@ -548,6 +552,19 @@ opm opencode clear --dry-run # 仅预览
|
|
|
548
552
|
opm opencode clear -y # 跳过确认直接执行
|
|
549
553
|
```
|
|
550
554
|
|
|
555
|
+
### harness
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
opm harness version # 查看已安装版本
|
|
559
|
+
opm harness installed # 检查是否已安装
|
|
560
|
+
opm harness install # 安装(使用 opm npm 镜像 + proxy)
|
|
561
|
+
opm harness upgrade # 升级到最新
|
|
562
|
+
opm harness dir # 查看安装路径 + skills/agents/commands 目录
|
|
563
|
+
opm harness list # 列出包提供的 skills/agents/commands
|
|
564
|
+
opm harness status # 健康检查(安装 + env + 内容完整性)
|
|
565
|
+
opm harness env # 查看环境变量(OPENCODE_CONFIG_DIR 等)
|
|
566
|
+
```
|
|
567
|
+
|
|
551
568
|
## npm scripts
|
|
552
569
|
|
|
553
570
|
| 命令 | 说明 |
|
package/docs/managers/nvm.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
| `opm nvm upgrade` | `cd ~/.nvm && git pull --tags` | 更新 nvm |
|
|
15
15
|
| `opm nvm uninstall` | `rm -rf ~/.nvm` | 卸载 nvm |
|
|
16
16
|
| `opm nvm dir` | 返回 `~/.nvm` 安装目录 |
|
|
17
|
+
| `opm nvm list` | `nvm ls --no-colors` | 列出已安装 Node.js 版本 |
|
|
17
18
|
|
|
18
19
|
## 镜像预设
|
|
19
20
|
|
|
@@ -29,6 +30,7 @@ opm nvm version
|
|
|
29
30
|
opm nvm registry set gitee
|
|
30
31
|
opm nvm install
|
|
31
32
|
opm nvm upgrade
|
|
33
|
+
opm nvm list
|
|
32
34
|
opm nvm dir
|
|
33
35
|
opm nvm uninstall
|
|
34
36
|
```
|
package/docs/managers/phpenv.md
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
| `opm phpenv upgrade` | `cd ~/.phpenv && git pull` + `cd plugins/php-build && git pull` | 更新 phpenv + php-build |
|
|
15
15
|
| `opm phpenv uninstall` | `rm -rf ~/.phpenv` | 卸载 phpenv |
|
|
16
16
|
| `opm phpenv dir` | 返回 `~/.phpenv` 安装目录 |
|
|
17
|
+
| `opm phpenv list` | `phpenv versions` | 列出已安装 PHP 版本 |
|
|
17
18
|
|
|
18
19
|
## 镜像预设
|
|
19
20
|
|
|
@@ -29,6 +30,7 @@ opm phpenv version
|
|
|
29
30
|
opm phpenv registry set gitee
|
|
30
31
|
opm phpenv install
|
|
31
32
|
opm phpenv upgrade
|
|
33
|
+
opm phpenv list
|
|
32
34
|
opm phpenv dir
|
|
33
35
|
opm phpenv uninstall
|
|
34
36
|
```
|
package/docs/managers/uv.md
CHANGED
|
@@ -16,6 +16,7 @@ uv 是 Astral 出品的快速 Python 包/版本管理器(Rust 实现),替
|
|
|
16
16
|
| `opm uv upgrade` | `uv self update` | 更新 uv |
|
|
17
17
|
| `opm uv uninstall` | `rm ~/.local/bin/uv` + `rm -rf ~/.local/share/uv` | 卸载 uv |
|
|
18
18
|
| `opm uv dir` | 返回 uv 安装目录 |
|
|
19
|
+
| `opm uv list` | `uv python list --only-installed` | 列出已安装 Python 版本 |
|
|
19
20
|
|
|
20
21
|
> 安装脚本 URL 通过 `uv.registry.active` 配置(`opm uv registry set <url>`);Windows 仍使用官方 `install.ps1`。
|
|
21
22
|
|
|
@@ -28,6 +29,7 @@ opm uv registry presets
|
|
|
28
29
|
opm uv registry set official
|
|
29
30
|
opm uv install
|
|
30
31
|
opm uv upgrade
|
|
32
|
+
opm uv list
|
|
31
33
|
opm uv dir
|
|
32
34
|
opm uv uninstall
|
|
33
35
|
```
|
package/docs/opm.html
CHANGED
|
@@ -450,7 +450,7 @@ opm npm help</code></pre></div>
|
|
|
450
450
|
<div id="managers_nvm" class="doc-content" style="display:none;"><h1>nvm 命令对照表</h1>
|
|
451
451
|
<p><code>@wwkit/opm</code> 统一命令管理 nvm 自身(安装/升级/卸载)。</p>
|
|
452
452
|
<h2>命令对照</h2>
|
|
453
|
-
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm nvm version</code></td><td><code>nvm --version</code></td><td>查看 nvm 版本</td></tr><tr><td><code>opm nvm registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>nvm.registry.active</code></td><td>查询 nvm git 镜像</td></tr><tr><td><code>opm nvm registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code></td><td>设置 nvm git 镜像</td></tr><tr><td><code>opm nvm registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm nvm install</code></td><td><code>git clone <mirror> ~/.nvm</code> + 写 shell profile</td><td>安装 nvm</td></tr><tr><td><code>opm nvm upgrade</code></td><td><code>cd ~/.nvm && git pull --tags</code></td><td>更新 nvm</td></tr><tr><td><code>opm nvm uninstall</code></td><td><code>rm -rf ~/.nvm</code></td><td>卸载 nvm</td></tr><tr><td><code>opm nvm dir</code></td><td>返回 <code>~/.nvm</code> 安装目录</td></tr></tbody></table>
|
|
453
|
+
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm nvm version</code></td><td><code>nvm --version</code></td><td>查看 nvm 版本</td></tr><tr><td><code>opm nvm registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>nvm.registry.active</code></td><td>查询 nvm git 镜像</td></tr><tr><td><code>opm nvm registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code></td><td>设置 nvm git 镜像</td></tr><tr><td><code>opm nvm registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm nvm install</code></td><td><code>git clone <mirror> ~/.nvm</code> + 写 shell profile</td><td>安装 nvm</td></tr><tr><td><code>opm nvm upgrade</code></td><td><code>cd ~/.nvm && git pull --tags</code></td><td>更新 nvm</td></tr><tr><td><code>opm nvm uninstall</code></td><td><code>rm -rf ~/.nvm</code></td><td>卸载 nvm</td></tr><tr><td><code>opm nvm dir</code></td><td>返回 <code>~/.nvm</code> 安装目录</td></tr><tr><td><code>opm nvm list</code></td><td><code>nvm ls --no-colors</code></td><td>列出已安装 Node.js 版本</td></tr></tbody></table>
|
|
454
454
|
<h2>镜像预设</h2>
|
|
455
455
|
<table><thead><tr><th>预设名</th><th>地址</th></tr></thead><tbody><tr><td><code>official</code></td><td><code>https://github.com/nvm-sh/nvm.git</code></td></tr><tr><td><code>gitee</code></td><td><code>https://gitee.com/mirrors/nvm.git</code></td></tr></tbody></table>
|
|
456
456
|
<h2>示例</h2>
|
|
@@ -458,6 +458,7 @@ opm npm help</code></pre></div>
|
|
|
458
458
|
opm nvm registry set gitee
|
|
459
459
|
opm nvm install
|
|
460
460
|
opm nvm upgrade
|
|
461
|
+
opm nvm list
|
|
461
462
|
opm nvm dir
|
|
462
463
|
opm nvm uninstall</code></pre></div>
|
|
463
464
|
<div id="managers_php" class="doc-content" style="display:none;"><h1>php 命令对照表</h1>
|
|
@@ -482,7 +483,7 @@ opm php upgrade</code></pre></div>
|
|
|
482
483
|
<div id="managers_phpenv" class="doc-content" style="display:none;"><h1>phpenv 命令对照表</h1>
|
|
483
484
|
<p><code>@wwkit/opm</code> 统一命令管理 phpenv 自身(安装/升级/卸载)。</p>
|
|
484
485
|
<h2>命令对照</h2>
|
|
485
|
-
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm phpenv version</code></td><td><code>phpenv --version</code></td><td>查看 phpenv 版本</td></tr><tr><td><code>opm phpenv registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>phpenv.registry.active</code></td><td>查询 phpenv git 镜像</td></tr><tr><td><code>opm phpenv registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code></td><td>设置 phpenv git 镜像</td></tr><tr><td><code>opm phpenv registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm phpenv install</code></td><td><code>git clone <mirror> ~/.phpenv</code> + <code>git clone php-build</code> + 写 shell profile</td><td>安装 phpenv + php-build 插件</td></tr><tr><td><code>opm phpenv upgrade</code></td><td><code>cd ~/.phpenv && git pull</code> + <code>cd plugins/php-build && git pull</code></td><td>更新 phpenv + php-build</td></tr><tr><td><code>opm phpenv uninstall</code></td><td><code>rm -rf ~/.phpenv</code></td><td>卸载 phpenv</td></tr><tr><td><code>opm phpenv dir</code></td><td>返回 <code>~/.phpenv</code> 安装目录</td></tr></tbody></table>
|
|
486
|
+
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm phpenv version</code></td><td><code>phpenv --version</code></td><td>查看 phpenv 版本</td></tr><tr><td><code>opm phpenv registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>phpenv.registry.active</code></td><td>查询 phpenv git 镜像</td></tr><tr><td><code>opm phpenv registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code></td><td>设置 phpenv git 镜像</td></tr><tr><td><code>opm phpenv registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm phpenv install</code></td><td><code>git clone <mirror> ~/.phpenv</code> + <code>git clone php-build</code> + 写 shell profile</td><td>安装 phpenv + php-build 插件</td></tr><tr><td><code>opm phpenv upgrade</code></td><td><code>cd ~/.phpenv && git pull</code> + <code>cd plugins/php-build && git pull</code></td><td>更新 phpenv + php-build</td></tr><tr><td><code>opm phpenv uninstall</code></td><td><code>rm -rf ~/.phpenv</code></td><td>卸载 phpenv</td></tr><tr><td><code>opm phpenv dir</code></td><td>返回 <code>~/.phpenv</code> 安装目录</td></tr><tr><td><code>opm phpenv list</code></td><td><code>phpenv versions</code></td><td>列出已安装 PHP 版本</td></tr></tbody></table>
|
|
486
487
|
<h2>镜像预设</h2>
|
|
487
488
|
<table><thead><tr><th>预设名</th><th>地址</th></tr></thead><tbody><tr><td><code>official</code></td><td><code>https://github.com/phpenv/phpenv.git</code></td></tr><tr><td><code>gitee</code></td><td><code>https://gitee.com/mirrors/phpenv.git</code></td></tr></tbody></table>
|
|
488
489
|
<h2>示例</h2>
|
|
@@ -490,6 +491,7 @@ opm php upgrade</code></pre></div>
|
|
|
490
491
|
opm phpenv registry set gitee
|
|
491
492
|
opm phpenv install
|
|
492
493
|
opm phpenv upgrade
|
|
494
|
+
opm phpenv list
|
|
493
495
|
opm phpenv dir
|
|
494
496
|
opm phpenv uninstall</code></pre></div>
|
|
495
497
|
<div id="managers_pip" class="doc-content" style="display:none;"><h1>pip 命令对照表</h1>
|
|
@@ -610,7 +612,7 @@ opm python upgrade</code></pre></div>
|
|
|
610
612
|
<p><code>@wwkit/opm</code> 统一命令管理 uv 自身(安装/升级/卸载)。</p>
|
|
611
613
|
<p>uv 是 Astral 出品的快速 Python 包/版本管理器(Rust 实现),替代 pyenv + pip。</p>
|
|
612
614
|
<h2>命令对照</h2>
|
|
613
|
-
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm uv version</code></td><td><code>uv --version</code></td><td>查看 uv 版本</td></tr><tr><td><code>opm uv registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>uv.registry.active</code></td><td>查询激活的安装脚本 URL</td></tr><tr><td><code>opm uv registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code> 的 <code>uv.registry.active</code></td><td>设置激活安装脚本 URL(支持预设名)</td></tr><tr><td><code>opm uv registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm uv install</code></td><td><code>curl -LsSf <active> | sh</code></td><td>安装 uv(脚本 URL 来自 <code>uv.registry.active</code>)</td></tr><tr><td><code>opm uv upgrade</code></td><td><code>uv self update</code></td><td>更新 uv</td></tr><tr><td><code>opm uv uninstall</code></td><td><code>rm ~/.local/bin/uv</code> + <code>rm -rf ~/.local/share/uv</code></td><td>卸载 uv</td></tr><tr><td><code>opm uv dir</code></td><td>返回 uv 安装目录</td></tr></tbody></table>
|
|
615
|
+
<table><thead><tr><th>统一命令</th><th>原始命令</th><th>说明</th></tr></thead><tbody><tr><td><code>opm uv version</code></td><td><code>uv --version</code></td><td>查看 uv 版本</td></tr><tr><td><code>opm uv registry</code></td><td>读 <code>~/.config/opm/config.json5</code> 的 <code>uv.registry.active</code></td><td>查询激活的安装脚本 URL</td></tr><tr><td><code>opm uv registry set <url|preset></code></td><td>写 <code>~/.config/opm/config.json5</code> 的 <code>uv.registry.active</code></td><td>设置激活安装脚本 URL(支持预设名)</td></tr><tr><td><code>opm uv registry presets</code></td><td>—</td><td>列出可用镜像预设</td></tr><tr><td><code>opm uv install</code></td><td><code>curl -LsSf <active> | sh</code></td><td>安装 uv(脚本 URL 来自 <code>uv.registry.active</code>)</td></tr><tr><td><code>opm uv upgrade</code></td><td><code>uv self update</code></td><td>更新 uv</td></tr><tr><td><code>opm uv uninstall</code></td><td><code>rm ~/.local/bin/uv</code> + <code>rm -rf ~/.local/share/uv</code></td><td>卸载 uv</td></tr><tr><td><code>opm uv dir</code></td><td>返回 uv 安装目录</td></tr><tr><td><code>opm uv list</code></td><td><code>uv python list --only-installed</code></td><td>列出已安装 Python 版本</td></tr></tbody></table>
|
|
614
616
|
<blockquote>安装脚本 URL 通过 <code>uv.registry.active</code> 配置(<code>opm uv registry set <url></code>);Windows 仍使用官方 <code>install.ps1</code>。</blockquote>
|
|
615
617
|
<h2>示例</h2>
|
|
616
618
|
<pre><code class="lang-bash">opm uv version
|
|
@@ -619,6 +621,7 @@ opm uv registry presets
|
|
|
619
621
|
opm uv registry set official
|
|
620
622
|
opm uv install
|
|
621
623
|
opm uv upgrade
|
|
624
|
+
opm uv list
|
|
622
625
|
opm uv dir
|
|
623
626
|
opm uv uninstall</code></pre></div>
|
|
624
627
|
<div id="packages_opencode" class="doc-content" style="display:none;"><h1>opencode 命令对照</h1>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wwkit/opm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"author": "bluesliu <langcai163@163.com>",
|
|
5
5
|
"description": "Unified CLI — package management (npm/pip/dnf/apt) + config view + opencode maintenance",
|
|
6
6
|
"type": "module",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"basic-ftp": "^6.2.1",
|
|
36
36
|
"extract-zip": "^2.0.1",
|
|
37
37
|
"systeminformation": "^5.23.0",
|
|
38
|
-
"@wwkit/harness": "1.0.
|
|
39
|
-
"@wwkit/shared": "1.0.
|
|
38
|
+
"@wwkit/harness": "1.0.19",
|
|
39
|
+
"@wwkit/shared": "1.0.14"
|
|
40
40
|
},
|
|
41
41
|
"publishConfig": {
|
|
42
42
|
"registry": "https://registry.npmjs.org/",
|
package/src/cli/groups/ensure.js
CHANGED
|
@@ -21,6 +21,18 @@ const RUNTIMES = {
|
|
|
21
21
|
python: () => new PythonManager(),
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* 按前缀(x 或 x.y)匹配已安装版本列表,返回完整版本号
|
|
26
|
+
* @param {{ version: string }[]} items
|
|
27
|
+
* @param {string} version
|
|
28
|
+
* @returns {string}
|
|
29
|
+
*/
|
|
30
|
+
export function resolveVersion(items, version) {
|
|
31
|
+
const v = version.replace(/^v/, '')
|
|
32
|
+
const hit = items.find((i) => i.version.replace(/^v/, '').startsWith(v))
|
|
33
|
+
return hit ? hit.version : ''
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
export class EnsureGroup {
|
|
25
37
|
constructor() {
|
|
26
38
|
this.name = 'ensure'
|
|
@@ -47,11 +59,18 @@ export class EnsureGroup {
|
|
|
47
59
|
|
|
48
60
|
let satisfied = false
|
|
49
61
|
let currentVersion = ''
|
|
62
|
+
let installVersion = ''
|
|
50
63
|
|
|
51
64
|
if (version) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
// 支持 x / x.y 简写:按前缀匹配已安装版本
|
|
66
|
+
const installed = await manager.listInstalled()
|
|
67
|
+
const full = resolveVersion(installed, version)
|
|
68
|
+
if (full) {
|
|
69
|
+
satisfied = true
|
|
70
|
+
currentVersion = full
|
|
71
|
+
} else {
|
|
72
|
+
installVersion = version
|
|
73
|
+
}
|
|
55
74
|
} else {
|
|
56
75
|
const result = await manager.getVersion()
|
|
57
76
|
satisfied = result.installed
|
|
@@ -63,7 +82,9 @@ export class EnsureGroup {
|
|
|
63
82
|
return
|
|
64
83
|
}
|
|
65
84
|
|
|
66
|
-
|
|
85
|
+
if (!installVersion) {
|
|
86
|
+
installVersion = manager.getDefaultVersion ? manager.getDefaultVersion() : ''
|
|
87
|
+
}
|
|
67
88
|
if (!installVersion) {
|
|
68
89
|
console.error(`No version specified and no defaultVersion configured for ${runtime}`)
|
|
69
90
|
process.exit(1)
|
package/src/cli/groups/nvm.js
CHANGED
|
@@ -13,7 +13,7 @@ import os from 'node:os'
|
|
|
13
13
|
import { ToolManagerGroup } from './version-manager.js'
|
|
14
14
|
import { Shell } from '@wwkit/shared'
|
|
15
15
|
import { getActiveRegistry } from '../../config.js'
|
|
16
|
-
import { installNvm } from '../../managers/node.js'
|
|
16
|
+
import { installNvm, parseNvmInstalled } from '../../managers/node.js'
|
|
17
17
|
|
|
18
18
|
const shell = new Shell()
|
|
19
19
|
|
|
@@ -35,6 +35,8 @@ export class NvmGroup extends ToolManagerGroup {
|
|
|
35
35
|
getPath: () => getNvmDir(),
|
|
36
36
|
versionCmd: () => `source "${path.join(getNvmDir(), 'nvm.sh')}" && nvm --version`,
|
|
37
37
|
parseVersion: (out) => out.trim(),
|
|
38
|
+
listCmd: () => `source "${path.join(getNvmDir(), 'nvm.sh')}" && nvm ls --no-colors`,
|
|
39
|
+
parseList: parseNvmInstalled,
|
|
38
40
|
install: (proxy) => installNvm(proxy),
|
|
39
41
|
upgrade: () => {
|
|
40
42
|
const nvmDir = getNvmDir()
|
|
@@ -62,6 +64,7 @@ export class NvmGroup extends ToolManagerGroup {
|
|
|
62
64
|
['upgrade', 'Update nvm (git pull)'],
|
|
63
65
|
['uninstall', 'Remove nvm (~/.nvm)'],
|
|
64
66
|
['dir', 'Show nvm install directory'],
|
|
67
|
+
['list', 'List installed Node.js versions (nvm ls --no-colors)'],
|
|
65
68
|
['help', 'Show this help'],
|
|
66
69
|
],
|
|
67
70
|
examples: [
|
|
@@ -71,6 +74,7 @@ export class NvmGroup extends ToolManagerGroup {
|
|
|
71
74
|
'opm nvm install',
|
|
72
75
|
'opm nvm upgrade',
|
|
73
76
|
'opm nvm dir',
|
|
77
|
+
'opm nvm list',
|
|
74
78
|
],
|
|
75
79
|
})
|
|
76
80
|
}
|
package/src/cli/groups/phpenv.js
CHANGED
|
@@ -14,7 +14,7 @@ import os from 'node:os'
|
|
|
14
14
|
import { ToolManagerGroup } from './version-manager.js'
|
|
15
15
|
import { Shell } from '@wwkit/shared'
|
|
16
16
|
import { getActiveRegistry } from '../../config.js'
|
|
17
|
-
import { installPhpenv } from '../../managers/php.js'
|
|
17
|
+
import { installPhpenv, parsePhpenvInstalled } from '../../managers/php.js'
|
|
18
18
|
|
|
19
19
|
const shell = new Shell()
|
|
20
20
|
|
|
@@ -47,6 +47,8 @@ export class PhpenvGroup extends ToolManagerGroup {
|
|
|
47
47
|
const m = out.trim().match(/phpenv\s+([\d.]+)/)
|
|
48
48
|
return m ? m[1] : out.trim()
|
|
49
49
|
},
|
|
50
|
+
listCmd: () => `${getPhpenvBin()} versions`,
|
|
51
|
+
parseList: parsePhpenvInstalled,
|
|
50
52
|
install: () => installPhpenv(),
|
|
51
53
|
upgrade: () => {
|
|
52
54
|
execSync(`cd "${getPhpenvRoot()}" && git remote set-url origin "${getActiveRegistry('phpenv')}" && git pull --tags`, {
|
|
@@ -74,6 +76,7 @@ export class PhpenvGroup extends ToolManagerGroup {
|
|
|
74
76
|
['upgrade', 'Update phpenv and php-build plugin (git pull)'],
|
|
75
77
|
['uninstall', 'Remove phpenv (~/.phpenv)'],
|
|
76
78
|
['dir', 'Show phpenv install directory'],
|
|
79
|
+
['list', 'List installed PHP versions (phpenv versions)'],
|
|
77
80
|
['help', 'Show this help'],
|
|
78
81
|
],
|
|
79
82
|
examples: [
|
|
@@ -83,6 +86,7 @@ export class PhpenvGroup extends ToolManagerGroup {
|
|
|
83
86
|
'opm phpenv install',
|
|
84
87
|
'opm phpenv upgrade',
|
|
85
88
|
'opm phpenv dir',
|
|
89
|
+
'opm phpenv list',
|
|
86
90
|
],
|
|
87
91
|
})
|
|
88
92
|
}
|
package/src/cli/groups/uv.js
CHANGED
|
@@ -11,7 +11,7 @@ import fs from 'node:fs'
|
|
|
11
11
|
import path from 'node:path'
|
|
12
12
|
import os from 'node:os'
|
|
13
13
|
import { ToolManagerGroup } from './version-manager.js'
|
|
14
|
-
import { installUv, getUvBin } from '../../managers/python.js'
|
|
14
|
+
import { installUv, getUvBin, parseUvInstalled } from '../../managers/python.js'
|
|
15
15
|
|
|
16
16
|
export class UvGroup extends ToolManagerGroup {
|
|
17
17
|
constructor() {
|
|
@@ -29,6 +29,8 @@ export class UvGroup extends ToolManagerGroup {
|
|
|
29
29
|
getPath: () => getUvBin(),
|
|
30
30
|
versionCmd: () => `${getUvBin()} --version`,
|
|
31
31
|
parseVersion: (out) => out.trim(),
|
|
32
|
+
listCmd: () => `${getUvBin()} python list --only-installed`,
|
|
33
|
+
parseList: parseUvInstalled,
|
|
32
34
|
install: (proxy) => installUv(proxy),
|
|
33
35
|
upgrade: () => {
|
|
34
36
|
execSync(`${getUvBin()} self update`, { stdio: 'inherit' })
|
|
@@ -56,6 +58,7 @@ export class UvGroup extends ToolManagerGroup {
|
|
|
56
58
|
['upgrade', 'Update uv (uv self update)'],
|
|
57
59
|
['uninstall', 'Remove uv (~/.local/bin/uv + ~/.local/share/uv)'],
|
|
58
60
|
['dir', 'Show uv install directory'],
|
|
61
|
+
['list', 'List installed Python versions (uv python list --only-installed)'],
|
|
59
62
|
['help', 'Show this help'],
|
|
60
63
|
],
|
|
61
64
|
examples: [
|
|
@@ -67,6 +70,7 @@ export class UvGroup extends ToolManagerGroup {
|
|
|
67
70
|
'opm uv install',
|
|
68
71
|
'opm uv upgrade',
|
|
69
72
|
'opm uv dir',
|
|
73
|
+
'opm uv list',
|
|
70
74
|
'opm uv uninstall',
|
|
71
75
|
],
|
|
72
76
|
})
|
|
@@ -25,6 +25,8 @@ const shell = new Shell()
|
|
|
25
25
|
* @property {() => string} getPath - view 展示的安装路径
|
|
26
26
|
* @property {() => string} versionCmd - 返回查询版本的 shell 命令
|
|
27
27
|
* @property {(out: string) => string} [parseVersion] - 解析版本输出
|
|
28
|
+
* @property {() => string} [listCmd] - 返回列出已安装版本的 shell 命令(缺省则 list 输出空列表)
|
|
29
|
+
* @property {(out: string) => { name: string, version: string, current: boolean }[]} [parseList] - 解析 list 输出
|
|
28
30
|
* @property {(proxy?: string) => Object} install - 安装并返回结果字段(失败时 throw)
|
|
29
31
|
* @property {() => Object} upgrade - 升级并返回结果字段(失败时 throw)
|
|
30
32
|
* @property {() => Object} uninstall - 卸载并返回结果字段(失败时 throw)
|
|
@@ -81,6 +83,8 @@ export class ToolManagerGroup {
|
|
|
81
83
|
return this._uninstall(parsed)
|
|
82
84
|
case 'dir':
|
|
83
85
|
return this._dir()
|
|
86
|
+
case 'list':
|
|
87
|
+
return this._list()
|
|
84
88
|
default:
|
|
85
89
|
console.error(`Unknown action: ${action}`)
|
|
86
90
|
this.printHelp()
|
|
@@ -193,6 +197,29 @@ const out = execSync(this.cfg.versionCmd(), { encoding: 'utf8', shell: shell.she
|
|
|
193
197
|
output(result)
|
|
194
198
|
}
|
|
195
199
|
|
|
200
|
+
/**
|
|
201
|
+
* 列出工具已安装的版本
|
|
202
|
+
* @returns {void}
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
_list() {
|
|
206
|
+
if (!this.cfg.isInstalled()) {
|
|
207
|
+
output({ name: this.name, installed: false, hint: `Run \`opm ${this.name} install\` first` })
|
|
208
|
+
return
|
|
209
|
+
}
|
|
210
|
+
if (!this.cfg.listCmd) {
|
|
211
|
+
output({ name: this.name, count: 0, versions: [] })
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const out = execSync(this.cfg.listCmd(), { encoding: 'utf8', shell: shell.shellForExec(this.cfg.needsBash) })
|
|
216
|
+
const versions = this.cfg.parseList ? this.cfg.parseList(out) : []
|
|
217
|
+
output({ name: this.name, count: versions.length, versions })
|
|
218
|
+
} catch {
|
|
219
|
+
output({ name: this.name, count: 0, versions: [] })
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
196
223
|
printHelp() {
|
|
197
224
|
const actionLines = this.cfg.actions.map(([sig, desc]) => ` ${sig.padEnd(34)} ${desc}`).join('\n')
|
|
198
225
|
const exampleLines = this.cfg.examples.map((e) => ` ${e}`).join('\n')
|
package/src/cli/index.js
CHANGED
|
@@ -27,6 +27,7 @@ import { ShareGroup } from '../tools/share/index.js'
|
|
|
27
27
|
import { WebworkGroup } from '../tools/webwork/index.js'
|
|
28
28
|
import { HarnessGroup } from '../harnesses/base.js'
|
|
29
29
|
import { opencodeHarness } from '../harnesses/opencode/index.js'
|
|
30
|
+
import { harnessCfg } from '../harnesses/harness/index.js'
|
|
30
31
|
import { CftGroup } from '../binaries/cft/index.js'
|
|
31
32
|
import { generateDocHtml } from './doc.js'
|
|
32
33
|
|
|
@@ -59,6 +60,7 @@ const GROUPS = {
|
|
|
59
60
|
uv: new UvGroup(),
|
|
60
61
|
config: new ConfigGroup(),
|
|
61
62
|
opencode: new HarnessGroup(opencodeHarness),
|
|
63
|
+
harness: new HarnessGroup(harnessCfg),
|
|
62
64
|
cft: new CftGroup(),
|
|
63
65
|
ensure: new EnsureGroup(),
|
|
64
66
|
ping: new PingGroup(),
|
package/src/harnesses/base.js
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
* AI harness 统一命令组基类
|
|
3
3
|
*
|
|
4
4
|
* 各 harness(opencode / claude / …)共享同一套命令:
|
|
5
|
-
* version / installed / install / uninstall / upgrade / config / clear / dir
|
|
5
|
+
* version / installed / install / uninstall / upgrade / config / clear / dir / env
|
|
6
|
+
* 内容型 harness(harness/@wwkit/harness 插件)额外提供:
|
|
7
|
+
* list(列出 skills/agents/commands) / status(安装 + env 健康检查)
|
|
8
|
+
*
|
|
9
|
+
* 支持的动作按 cfg 能力动态裁剪(_supportedActions):只有 cfg 提供了对应的
|
|
10
|
+
* 实现(list/status/clear/getConfigFile/getEnvVars)时才出现在帮助与路由中。
|
|
6
11
|
*
|
|
7
12
|
* install/uninstall/upgrade 委托 NpmManager(global),自动使用 opm 配置的
|
|
8
13
|
* npm registry 镜像与 proxy,而非裸 npm。
|
|
@@ -25,7 +30,9 @@ const ACTIONS = {
|
|
|
25
30
|
upgrade: { desc: 'Upgrade to latest via npm -g (uses opm npm registry + proxy)' },
|
|
26
31
|
config: { desc: 'Show config file content' },
|
|
27
32
|
clear: { desc: 'Clear sessions / data' },
|
|
28
|
-
dir: { desc: 'Show data / db / log / config paths' },
|
|
33
|
+
dir: { desc: 'Show install / data / db / log / config paths' },
|
|
34
|
+
list: { desc: 'List installed content (skills/agents/commands)' },
|
|
35
|
+
status: { desc: 'Show install status + environment health' },
|
|
29
36
|
env: { desc: 'Show harness environment variables' },
|
|
30
37
|
help: { desc: 'Show this help' },
|
|
31
38
|
}
|
|
@@ -35,12 +42,15 @@ const ACTIONS = {
|
|
|
35
42
|
* @property {string} name - harness 名(命令名)
|
|
36
43
|
* @property {string} desc - 描述
|
|
37
44
|
* @property {string} npmPackage - npm 全局包名
|
|
38
|
-
* @property {() => string|null} getConfigFile - 配置文件路径
|
|
39
|
-
* @property {() => string} getDataDir - 数据目录
|
|
40
|
-
* @property {() => string} getDbPath - DB 路径
|
|
41
|
-
* @property {() => string} getLogPath - 日志路径
|
|
42
|
-
* @property {(argv: string[]) => Promise<void>} clear - 清理实现
|
|
45
|
+
* @property {() => string|null} [getConfigFile] - 配置文件路径
|
|
46
|
+
* @property {() => string} [getDataDir] - 数据目录
|
|
47
|
+
* @property {() => string} [getDbPath] - DB 路径
|
|
48
|
+
* @property {() => string} [getLogPath] - 日志路径
|
|
49
|
+
* @property {(argv: string[]) => Promise<void>} [clear] - 清理实现
|
|
43
50
|
* @property {string[][]} [clearOptions] - clear 子选项帮助 [flag, desc]
|
|
51
|
+
* @property {() => Promise<Object>} [list] - 列出包内容(skills/agents/commands)
|
|
52
|
+
* @property {() => Promise<Object>} [status] - 安装/环境健康检查
|
|
53
|
+
* @property {() => Promise<Object>} [dirInfo] - 自定义 dir 输出(覆盖默认 npm install 路径)
|
|
44
54
|
*/
|
|
45
55
|
|
|
46
56
|
export class HarnessGroup {
|
|
@@ -62,9 +72,19 @@ export class HarnessGroup {
|
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
if (!action || !ACTIONS[action]) {
|
|
75
|
+
if (!this.cfg.open) {
|
|
76
|
+
this.printHelp()
|
|
77
|
+
return
|
|
78
|
+
}
|
|
65
79
|
return this._open(argv)
|
|
66
80
|
}
|
|
67
81
|
|
|
82
|
+
if (!this._supportedActions().includes(action)) {
|
|
83
|
+
console.error(`Action "${action}" is not supported for ${this.cfg.name}`)
|
|
84
|
+
this.printHelp()
|
|
85
|
+
process.exit(1)
|
|
86
|
+
}
|
|
87
|
+
|
|
68
88
|
switch (action) {
|
|
69
89
|
case 'version':
|
|
70
90
|
return this._version()
|
|
@@ -82,6 +102,10 @@ export class HarnessGroup {
|
|
|
82
102
|
return this._clear(rest)
|
|
83
103
|
case 'dir':
|
|
84
104
|
return this._dir()
|
|
105
|
+
case 'list':
|
|
106
|
+
return this._list()
|
|
107
|
+
case 'status':
|
|
108
|
+
return this._status()
|
|
85
109
|
case 'env':
|
|
86
110
|
return this._env()
|
|
87
111
|
default:
|
|
@@ -91,6 +115,23 @@ export class HarnessGroup {
|
|
|
91
115
|
}
|
|
92
116
|
}
|
|
93
117
|
|
|
118
|
+
/**
|
|
119
|
+
* 本 harness 支持的动作列表(按 cfg 能力动态裁剪)
|
|
120
|
+
* @returns {string[]}
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
_supportedActions() {
|
|
124
|
+
return Object.keys(ACTIONS).filter((sig) => {
|
|
125
|
+
if (sig === 'help') return true
|
|
126
|
+
if (sig === 'list') return Boolean(this.cfg.list)
|
|
127
|
+
if (sig === 'status') return Boolean(this.cfg.status)
|
|
128
|
+
if (sig === 'clear') return Boolean(this.cfg.clear)
|
|
129
|
+
if (sig === 'config') return Boolean(this.cfg.getConfigFile)
|
|
130
|
+
if (sig === 'env') return Boolean(this.cfg.getEnvVars)
|
|
131
|
+
return true
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
94
135
|
/**
|
|
95
136
|
* 解析 proxy(-p/--proxy 优先,否则回退配置 active proxy)
|
|
96
137
|
* @param {string[]} argv
|
|
@@ -152,6 +193,22 @@ export class HarnessGroup {
|
|
|
152
193
|
output({ file, content })
|
|
153
194
|
}
|
|
154
195
|
|
|
196
|
+
async _list() {
|
|
197
|
+
if (!this.cfg.list) {
|
|
198
|
+
output({ name: this.cfg.name, error: 'list not supported for this harness' })
|
|
199
|
+
return
|
|
200
|
+
}
|
|
201
|
+
output(await this.cfg.list())
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async _status() {
|
|
205
|
+
if (!this.cfg.status) {
|
|
206
|
+
output({ name: this.cfg.name, error: 'status not supported for this harness' })
|
|
207
|
+
return
|
|
208
|
+
}
|
|
209
|
+
output(await this.cfg.status())
|
|
210
|
+
}
|
|
211
|
+
|
|
155
212
|
async _clear(rest) {
|
|
156
213
|
const parsed = parseFlags(rest)
|
|
157
214
|
if (parsed.flags.help === 'true') {
|
|
@@ -162,6 +219,10 @@ export class HarnessGroup {
|
|
|
162
219
|
}
|
|
163
220
|
|
|
164
221
|
async _dir() {
|
|
222
|
+
if (this.cfg.dirInfo) {
|
|
223
|
+
output(await this.cfg.dirInfo())
|
|
224
|
+
return
|
|
225
|
+
}
|
|
165
226
|
const npm = new NpmManager()
|
|
166
227
|
const npmResult = await npm.isInstalled(this.cfg.npmPackage, { global: true })
|
|
167
228
|
const configFile = this.cfg.getConfigFile()
|
|
@@ -218,18 +279,34 @@ export class HarnessGroup {
|
|
|
218
279
|
}
|
|
219
280
|
|
|
220
281
|
printHelp() {
|
|
221
|
-
const actionLines =
|
|
222
|
-
.map((
|
|
282
|
+
const actionLines = this._supportedActions()
|
|
283
|
+
.map((sig) => ` ${sig.padEnd(12)} ${ACTIONS[sig].desc}`)
|
|
223
284
|
.join('\n')
|
|
224
285
|
|
|
225
286
|
let clearSection = ''
|
|
226
|
-
if (this.cfg.clearOptions && this.cfg.clearOptions.length > 0) {
|
|
287
|
+
if (this._supportedActions().includes('clear') && this.cfg.clearOptions && this.cfg.clearOptions.length > 0) {
|
|
227
288
|
const optLines = this.cfg.clearOptions
|
|
228
289
|
.map(([flag, desc]) => ` ${flag.padEnd(20)} ${desc}`)
|
|
229
290
|
.join('\n')
|
|
230
291
|
clearSection = `\nClear options:\n${optLines}\n`
|
|
231
292
|
}
|
|
232
293
|
|
|
294
|
+
const supported = this._supportedActions()
|
|
295
|
+
const examples = [
|
|
296
|
+
' opm ' + this.cfg.name + ' version',
|
|
297
|
+
' opm ' + this.cfg.name + ' install',
|
|
298
|
+
' opm ' + this.cfg.name + ' upgrade',
|
|
299
|
+
...(supported.includes('list') ? [` opm ${this.cfg.name} list`] : []),
|
|
300
|
+
...(supported.includes('status') ? [` opm ${this.cfg.name} status`] : []),
|
|
301
|
+
...(supported.includes('env') ? [` opm ${this.cfg.name} env`] : []),
|
|
302
|
+
...(supported.includes('dir') ? [` opm ${this.cfg.name} dir`] : []),
|
|
303
|
+
]
|
|
304
|
+
if (this.cfg.open) {
|
|
305
|
+
examples.push(` opm ${this.cfg.name} Launch TUI in current directory`)
|
|
306
|
+
examples.push(` opm ${this.cfg.name} -d /path/to/project`)
|
|
307
|
+
examples.push(` opm ${this.cfg.name} -c config --agent work Pass through args to opencode`)
|
|
308
|
+
}
|
|
309
|
+
|
|
233
310
|
console.log(`
|
|
234
311
|
Usage: opm ${this.cfg.name} <action> [options]
|
|
235
312
|
|
|
@@ -242,16 +319,7 @@ Options:
|
|
|
242
319
|
-h, --help Show this help
|
|
243
320
|
|
|
244
321
|
Examples:
|
|
245
|
-
|
|
246
|
-
opm ${this.cfg.name} install
|
|
247
|
-
opm ${this.cfg.name} upgrade
|
|
248
|
-
opm ${this.cfg.name} config
|
|
249
|
-
opm ${this.cfg.name} clear
|
|
250
|
-
opm ${this.cfg.name} dir
|
|
251
|
-
opm ${this.cfg.name} env
|
|
252
|
-
opm ${this.cfg.name} Launch TUI in current directory
|
|
253
|
-
opm ${this.cfg.name} -d /path/to/project
|
|
254
|
-
opm ${this.cfg.name} -c config --agent work Pass through args to opencode
|
|
322
|
+
${examples.join('\n')}
|
|
255
323
|
`)
|
|
256
324
|
}
|
|
257
325
|
}
|