feat: 拆分 environment-setup 为 Python/Node.js 运行时双核心 + 父级路由

新增双核心 skill(深度集成 DesireCore Hatch/Volta + HTTP API + Socket.IO):
- python-runtime v1.0.1:Python 运行时管理
  · 四级降级:HTTP API → Hatch CLI 绝对路径 → 系统包管理器 → pyenv
  · references:hatch-desirecore / pyenv-fallback / virtualenv / troubleshooting
  · scripts/probe-python.sh:输出 JSON 快照供 Claude 解析决策
- nodejs-runtime v1.0.1:Node.js 运行时管理
  · 四级降级:HTTP API → Volta CLI → 系统包管理器/NodeSource → nvm/fnm
  · references:volta-desirecore / nvm-fallback / package-managers / troubleshooting
  · scripts/probe-node.sh:输出 JSON 快照(含 volta_tools / package_json_volta 等)

environment-setup → dev-environment-setup v2.0.1(重命名 + 重写为 router):
- 从 1380 行手册瘦身为 ~150 行索引
- 仅负责容器(Docker/Podman)/ WSL2 / 办公依赖速查 / 系统工具
- references/desirecore-runtime.md 沉淀 Hatch/Volta 路径表 + HTTP API 速查 +
  Socket.IO 事件契约,作为两个核心 skill 的共享底座
- references/decision-tree.md 定义四级降级决策树
- scripts/probe.sh + probe.ps1 系统级 JSON 探测

三个 SKILL.md 的 L0 改为场景驱动结构(何时使用 / 何时不要用 / 怎么做),
让 AI 凭名字与 L0 即可判断匹配场景。

注册更新:
- builtin-skills.json:新增 python-runtime / nodejs-runtime / dev-environment-setup
  (原 environment-setup 移除),按字母序,共 21 个 skill
- manifest.json:totalSkills 19→21,lastUpdated 2026-05-02

下游同步:
- docx / pdf / xlsx / pptx 中的环境引用从 environment-setup 拆分为
  python-runtime / nodejs-runtime / dev-environment-setup 三向指引

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-02 13:30:23 +08:00
parent 5472359814
commit 1a50969b93
29 changed files with 3310 additions and 1386 deletions

View File

@@ -0,0 +1,193 @@
---
name: Node.js 运行时管理
description: >-
Use this skill when the user needs to install, upgrade, or troubleshoot
Node.js, npm, pnpm, yarn, and JavaScript/TypeScript runtime environments.
Covers four-tier fallback strategy: (1) DesireCore HTTP API for in-app
installation, (2) DesireCore built-in Volta CLI for Node.js + package
manager version management, (3) system package managers
(brew/apt/dnf/winget/NodeSource), (4) community nvm/fnm as last resort.
Also covers global package management, npm registry/proxy configuration,
EACCES permission errors, and PATH troubleshooting. Triggers include:
"install node", "node not found", "npm not found", "npm EACCES", "pnpm",
"yarn", "volta", "nvm", "fnm", "nodejs version", "package-lock", or any
Node.js / npm runtime error. 使用场景:用户需要 安装 Node.js、安装 npm、
pnpm、yarn、配置全局包、解决 EACCES、PATH 问题、镜像/代理配置。
version: 1.0.1
type: procedural
risk_level: low
status: enabled
disable-model-invocation: true
tags:
- nodejs
- npm
- pnpm
- yarn
- volta
- nvm
- fnm
- environment
metadata:
author: desirecore
updated_at: '2026-05-02'
market:
icon: >-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0
24 24" fill="none"><defs><linearGradient id="node-a" x1="3" y1="3" x2="21"
y2="21" gradientUnits="userSpaceOnUse"><stop
stop-color="#68A063"/><stop offset="1"
stop-color="#3C873A"/></linearGradient></defs><rect x="3" y="3" width="18"
height="18" rx="3" fill="url(#node-a)" fill-opacity="0.12"
stroke="url(#node-a)" stroke-width="1.5"/><path d="M12 6.5L17 9.25v5.5L12
17.5L7 14.75v-5.5z" stroke="url(#node-a)" stroke-width="1.4"
stroke-linejoin="round" fill="none"/><path d="M12 11.5v3M10 12.5l2 1l2-1"
stroke="url(#node-a)" stroke-width="1.4" stroke-linecap="round"
fill="none"/></svg>
short_desc: Node.js / npm / pnpm / yarn 安装与多版本DesireCore Volta 优先)
category: development
maintainer:
name: DesireCore Official
verified: true
channel: latest
---
# nodejs-runtime 技能
## L0一句话摘要
**何时使用**:用户需要 安装 Node.js / 升级 Node / 切换 Node 多版本 / 安装或配置
npm / pnpm / yarn / 排查 `node: command not found``npm: command not found`
EACCES 全局安装权限错误、node-gyp 编译失败、registry 镜像 / proxy 问题 等
Node.js 运行时问题,或其他 skillpptx 用 pptxgenjs 等)报告 "Node.js 不可用" 时。
**怎么做**:优先使用 DesireCore 内置 Volta按四级降级HTTP API → Volta CLI →
系统包管理器 brew/apt/NodeSource/winget → 社区方案 nvm/fnm执行。
## L1概述与使用场景
### 能力描述
procedural skill。每次执行 Node.js 环境操作前,先运行 `scripts/probe-node.sh` 取 JSON 快照,再按 `../dev-environment-setup/references/decision-tree.md` 四级降级选择路径。
### 使用场景
- "node not found" / "npm not found"
- 用户要求安装/升级 Node.js
- 多版本切换(基于 `package.json#volta``.nvmrc`
- 安装/管理 pnpm / yarn / npm
- "EACCES: permission denied"npm 全局安装权限错误)
- 配置 registry / proxy
- 其他 skillpptx 等)报告 Node.js 不可用
### 核心价值
- **DesireCore 优先**Volta + HTTP API 作为 L1/L2避免污染系统 Node
- **JSON 决策**probe 脚本输出结构化数据Claude 可直接解析
- **package.json#volta 兼容**Volta 自动按项目切换版本
## L2详细规范
### 第一步:环境探测(必须)
```bash
bash skills/nodejs-runtime/scripts/probe-node.sh > /tmp/node-probe.json
cat /tmp/node-probe.json | jq .
```
字段含义见 `../dev-environment-setup/references/probe-snapshot.md`
### 第二步:选择执行路径
| 条件 | 路径 |
|------|------|
| `desirecore_api` 非空 | **L1** HTTP API |
| `desirecore_api` 空,`volta_path` 非空 | **L2** Volta CLI |
| 上述都不满足 | **L3** 系统包管理器brew / apt / NodeSource / winget |
| L1L3 全部失败或用户明示 | **L4** 社区方案nvm / fnm |
### 第三步:执行(仅展示主路径,详见各 references
#### L1HTTP API→ `references/volta-desirecore.md`
```bash
PORT=$(cat ~/.desirecore/agent-service.port)
BASE="https://127.0.0.1:${PORT}/api/runtime"
# 列出可装版本
curl -sk "${BASE}/node/available"
# 触发安装(异步)
curl -sk -X POST "${BASE}/node/install" \
-H "Content-Type: application/json" \
-d '{"version":"22"}'
# 安装包管理器
curl -sk -X POST "${BASE}/pkg/pnpm/install" \
-H "Content-Type: application/json" \
-d '{"version":"latest"}'
# 完成后刷新缓存
curl -sk -X POST "${BASE}/environment/refresh"
```
#### L2Volta CLI 绝对路径(→ `references/volta-desirecore.md`
```bash
VOLTA=~/.desirecore/runtime/volta/volta
export VOLTA_HOME=~/.desirecore/runtime/volta
export VOLTA_FEATURE_PNPM=1
"$VOLTA" install node@22
"$VOLTA" install pnpm@latest
"$VOLTA" install yarn@latest
"$VOLTA" list all
# 项目级固定(修改 package.json#volta
"$VOLTA" pin node@22 pnpm@9
```
Windows`%USERPROFILE%\.desirecore\runtime\volta\volta.exe`
#### L3系统包管理器
| 平台 | 命令 |
|------|------|
| macOS | `brew install node` |
| Debian/Ubuntu | NodeSource`curl -fsSL https://deb.nodesource.com/setup_22.x \| sudo -E bash - && sudo apt install nodejs` |
| Fedora/RHEL | `curl -fsSL https://rpm.nodesource.com/setup_22.x \| sudo bash - && sudo dnf install nodejs` |
| Arch | `sudo pacman -S nodejs npm` |
| Windows | `winget install OpenJS.NodeJS.LTS` |
#### L4nvm / fnm→ `references/nvm-fallback.md`
仅在用户明示或上述失败时启用。
### 第四步:包管理器策略
详见 `references/package-managers.md`
- pnpm推荐磁盘高效、严格依赖
- yarnBerry / Classic
- npm默认Node.js 自带)
- 项目级 `package.json#volta` 自动切换
### 第五步:故障排查
详见 `references/troubleshooting.md`
- npm EACCES 权限错误(**不要用 sudo npm**
- registry / proxy 配置
- node-gyp 编译失败
- "node: command not found" 在 nvm 已装时
## 重要约束
1. **绝不 `sudo npm install -g`**:用户级 prefix 或 Volta/nvm。
2. **修改环境后必须刷新**L1 调 `POST /api/runtime/environment/refresh`;其它路径重跑 probe。
3. **跨 skill 协作**`pptx` 等需要 Node.js 时,按本 skill 主路径安装npm 包速查见 `../dev-environment-setup/references/office-deps.md`
4. **package.json#volta 必须尊重**:检测到该字段时优先 Volta不要切到 nvm。
## 引用关系
- 决策树:`../dev-environment-setup/references/decision-tree.md`
- DesireCore 底座:`../dev-environment-setup/references/desirecore-runtime.md`
- 探测协议:`../dev-environment-setup/references/probe-snapshot.md`
- 办公依赖npm 包):`../dev-environment-setup/references/office-deps.md`

View File

@@ -0,0 +1,140 @@
# nvm / fnmL4 社区方案)
仅在以下情况启用:
1. 用户明确要求 nvm / fnm
2. 项目根目录已有 `.nvmrc` 文件且不存在 `package.json#volta`
3. L1 (HTTP API) / L2 (Volta CLI) / L3 (系统包管理器) 全部失败
如条件不满足,**不要**主动建议 nvm——优先 DesireCore Volta。
## nvmPOSIX shell
### 安装
```bash
# macOS / Linux
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.zshrc # 或 ~/.bashrc
# 验证
command -v nvm # 应返回 "nvm"(函数)
```
`install.sh` 会自动追加加载片段到 `~/.zshrc` / `~/.bashrc`
```bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
```
### 使用
```bash
# 列出可装 LTS
nvm ls-remote --lts
# 安装
nvm install 22 # 最新 22.x
nvm install --lts # 最新 LTS
nvm install 20.10.0 # 精确版本
# 切换
nvm use 22
nvm use --lts
# 默认
nvm alias default 22
# 项目级(.nvmrc
echo "22" > .nvmrc
nvm use # 读取 .nvmrc
# 已装
nvm ls
# 卸载
nvm uninstall 18
```
### Windowsnvm-windows独立项目
```
https://github.com/coreybutler/nvm-windows/releases
```
下载安装包安装,重启终端。命令略有差异(无 `.nvmrc` 支持,需用 `nvm-windows-bridge` 之类的扩展)。
## fnmRust 实现,比 nvm 快)
### 安装
```bash
# macOS
brew install fnm
# Linux
curl -fsSL https://fnm.vercel.app/install | bash
# Windows
winget install Schniz.fnm
```
### 配置自动切换
```bash
# zsh
echo 'eval "$(fnm env --use-on-cd --shell zsh)"' >> ~/.zshrc
# bash
echo 'eval "$(fnm env --use-on-cd --shell bash)"' >> ~/.bashrc
# fish
fnm env --use-on-cd --shell fish | source
```
`--use-on-cd``cd` 进入有 `.nvmrc` 的目录时自动切换。
### 使用
```bash
fnm install 22
fnm install --lts
fnm use 22
fnm default 22
fnm ls
fnm uninstall 18
```
## .nvmrc / .node-version 约定
| 文件 | 工具支持 |
|------|----------|
| `.nvmrc` | nvm、fnm默认 |
| `.node-version` | fnm默认、nodenv |
| `package.json#engines.node` | npm 安装时校验,不切换 |
| `package.json#volta` | Volta自动切换 |
存在 `package.json#volta` 时**优先尊重**它,不要让用户改用 nvm。
## 镜像加速
```bash
# nvm
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node/
# fnm
fnm install --node-dist-mirror https://npmmirror.com/mirrors/node/ 22
# 或全局
export FNM_NODE_DIST_MIRROR=https://npmmirror.com/mirrors/node/
```
## 故障排查
| 现象 | 排查 |
|------|------|
| `nvm: command not found` | shell 未 source nvm.sh重启终端或 `source ~/.zshrc` |
| `nvm` 在脚本里失效 | nvm 是 shell function 不是命令;脚本里需先 `source ~/.nvm/nvm.sh` |
| `node: command not found`nvm 已装) | 切换了 shell 但 nvm 没在新 shell 加载,添加加载片段 |
| nvm 编译 Node 时网络超时 | 设镜像 `NVM_NODEJS_ORG_MIRROR` |
| Windows nvm 切换无效 | 以管理员重新运行 nvm 安装包 |

View File

@@ -0,0 +1,160 @@
# 包管理器策略npm / pnpm / yarn
## 选型建议
| 场景 | 推荐 |
|------|------|
| 默认Node.js 自带) | npm |
| 磁盘高效 / 严格依赖 / monorepo | **pnpm**(推荐) |
| 项目已用 yarn | yarn classic / berry |
| DesireCore 应用内 | Volta 管理任何之上 |
## 通过 DesireCore Volta 安装
```bash
VOLTA=~/.desirecore/runtime/volta/volta
export VOLTA_FEATURE_PNPM=1
"$VOLTA" install pnpm@latest
"$VOLTA" install yarn@latest
"$VOLTA" install npm@10
```
或 HTTP API
```bash
BASE="https://127.0.0.1:$(cat ~/.desirecore/agent-service.port)/api/runtime"
curl -sk -X POST "${BASE}/pkg/pnpm/install" -H "Content-Type: application/json" -d '{"version":"latest"}'
```
## 项目级固定版本
### package.json#volta首选
```json
{
"volta": {
"node": "22.11.0",
"pnpm": "9.5.0"
}
}
```
在装了 Volta 的环境中 `cd` 进项目即自动切换。
### packageManager 字段Corepack 标准)
```json
{
"packageManager": "pnpm@9.5.0"
}
```
由 CorepackNode 16.10+ 自带)解析,被 npm/pnpm/yarn 自身识别。可与 Volta 共存。
## npm 全局安装
### 不要用 sudo
错误:
```bash
sudo npm install -g pkg # ❌ 文件 owner 变成 root后续维护麻烦
```
正确:改 npm 全局目录到用户目录。
```bash
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
npm install -g pptxgenjs docx
```
或用 Volta自动隔离无权限问题
```bash
volta install pptxgenjs # ❌ Volta 不直接装库;只能装 CLI 工具
# 库依赖应通过项目 package.json 管理
```
## pnpm 配置
```bash
# 全局存储位置pnpm 单存储多链接的核心)
pnpm config get store-dir
# 默认 ~/.local/share/pnpm/store/v3
# 改 registry
pnpm config set registry https://registry.npmmirror.com/
# 全局安装路径(独立于 npm
pnpm config get global-bin-dir
```
## yarn 配置
```bash
# yarn classic
yarn config set registry https://registry.npmmirror.com/
# yarn berry
yarn config set npmRegistryServer https://registry.npmmirror.com/
```
## 镜像 / 代理
### 中国大陆加速
```bash
npm config set registry https://registry.npmmirror.com/
pnpm config set registry https://registry.npmmirror.com/
yarn config set registry https://registry.npmmirror.com/
```
恢复官方:
```bash
npm config set registry https://registry.npmjs.org/
```
### 公司代理
```bash
npm config set proxy http://proxy:port
npm config set https-proxy http://proxy:port
# 取消
npm config delete proxy
npm config delete https-proxy
```
### 私有 registryVerdaccio / Nexus
```bash
# 项目级(.npmrc
@scope:registry=https://npm.company.com/
//npm.company.com/:_authToken=${NPM_TOKEN}
```
## 卸载与清理
```bash
# 全局列表
npm ls -g --depth=0
pnpm list -g --depth=0
yarn global list
# 卸载
npm uninstall -g pkg
pnpm uninstall -g pkg
yarn global remove pkg
# 清缓存
npm cache clean --force
pnpm store prune
yarn cache clean
```
## 环境快照
probe-node.sh 输出 `volta_tools.{node,pnpm,yarn,npm}` 列出所有 Volta 管理的版本,`registry` / `proxy` 来自 npm 配置。Skill 解析 JSON 即可判断是否需要切换镜像。

View File

@@ -0,0 +1,173 @@
# Node.js 故障排查
## "node: command not found" / "npm: command not found"
```bash
# 1. 找一下二进制
which node 2>/dev/null
ls /usr/bin/node /usr/local/bin/node /opt/homebrew/bin/node 2>/dev/null
# 2. nvm 已装但未加载?
[ -s "$HOME/.nvm/nvm.sh" ] && echo "nvm installed but not loaded"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
node --version
# 3. Volta 已装但未在 PATH
ls ~/.desirecore/runtime/volta/volta 2>/dev/null && \
echo "运行 ~/.desirecore/runtime/volta/volta 直接调用,无需 PATH"
```
**根治**:按主 SKILL.md 决策树重新执行 L1L3 安装路径。
## npm EACCES全局安装权限错误
**症状**`npm install -g <pkg>``EACCES: permission denied, mkdir '/usr/local/lib/node_modules'`
**原因**npm 默认全局目录是系统目录,无写权限。
**修复(推荐:改 npm prefix 到用户目录)**
```bash
mkdir -p ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.zshrc # 或 ~/.bashrc
source ~/.zshrc
# 现在可以正常全局安装
npm install -g pkg
```
**禁忌**`sudo npm install -g` ——会把文件 owner 改成 root后续 npm 升级/卸载报错。
## node-gyp 编译失败
**症状**安装包含原生扩展的依赖sqlite3 / sharp / canvas时报 `node-gyp rebuild failed`
| 平台 | 修复 |
|------|------|
| macOS | `xcode-select --install` |
| Ubuntu/Debian | `sudo apt install build-essential python3` |
| Fedora/RHEL | `sudo dnf groupinstall "Development Tools" && sudo dnf install python3` |
| Windows | `npm install --global windows-build-tools`(管理员)或装 Visual Studio Build Tools |
某些包提供预编译版本:检查 `package.json` 是否有 `prebuild-install` 钩子,没有再编译。
## SSL / TLS 错误
```bash
# 临时不验证(仅调试)
npm config set strict-ssl false
# 永久(不推荐)
npm config set ca null
# 公司证书 / Zscaler
npm config set cafile /path/to/company-ca.pem
```
## 代理环境
```bash
# 设置
npm config set proxy http://proxy:port
npm config set https-proxy http://proxy:port
# 检查
npm config get proxy
npm config get https-proxy
# 取消
npm config delete proxy
npm config delete https-proxy
```
注意HTTP_PROXY / HTTPS_PROXY 环境变量也会被 npm 识别。
## "Cannot find module" 错误
```bash
# 1. 是否在正确目录
pwd
ls package.json
# 2. node_modules 是否安装
ls node_modules/<missing-module> 2>/dev/null
# 3. 是否在虚拟切换中nvm/Volta 没切对)
node -e "console.log(process.execPath)"
# 4. 重装
rm -rf node_modules package-lock.json
npm install
```
## 版本冲突
`package.json#engines` 限制 Node 版本:
```json
{
"engines": { "node": ">=20" }
}
```
Volta 会强制使用 `volta` 字段nvm/fnm 用 `.nvmrc`。检查冲突:
```bash
node --version
cat package.json | grep -A2 '"volta"\|"engines"'
cat .nvmrc 2>/dev/null
```
## Windows PowerShell 执行策略
```powershell
Get-ExecutionPolicy
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
之后才能运行 npm / pnpm / yarn 脚本。
## 镜像与 CDN 慢
```bash
# 切换到淘宝镜像
npm config set registry https://registry.npmmirror.com/
pnpm config set registry https://registry.npmmirror.com/
# 部分二进制sharp / puppeteer有独立 CDN
export SHARP_DIST_BASE_URL=https://npmmirror.com/mirrors/sharp/
export PUPPETEER_DOWNLOAD_HOST=https://npmmirror.com/mirrors/
```
## EnvironmentSnapshot 信号速查
probe-node.sh 输出后,按字段快速判断:
| 字段 | 期望 | 失败原因 |
|------|------|----------|
| `system_node.version` | 非空且 ≥ 18 | 未装或版本太低 |
| `system_npm.version` | 非空 | 应随 Node 自带 |
| `volta_path` | 非空 | DesireCore Volta 未释放,调 `POST /api/runtime/volta/install` |
| `volta_tools.node` | 非空数组 | 还未装任何 Volta 管理的 Node 版本 |
| `package_json_volta` | 项目用 Volta | 优先 Volta不要切到 nvm |
| `registry` | `*.npmmirror.com` | 已加速;空字符串可能是 npm 未装 |
| `proxy` | 非空 | 公司代理已设;如有问题先查代理 |
## 重置整个 Node.js 环境(最后手段)
```bash
# 1. 删除全局缓存
npm cache clean --force
pnpm store prune
yarn cache clean
# 2. 删除项目锁文件 + node_modules
rm -rf node_modules package-lock.json pnpm-lock.yaml yarn.lock
# 3. 重新探测
bash skills/nodejs-runtime/scripts/probe-node.sh
# 4. 按主 SKILL.md 决策树重新安装并 install
```

View File

@@ -0,0 +1,165 @@
# DesireCore 内置 VoltaL1 / L2 主路径)
DesireCore 内置 [Volta](https://volta.sh/) v2.0.2Rust 实现的 Node.js 工具链管理器。Volta 二进制随应用打包于 `static/volta/`,运行时位于 `~/.desirecore/runtime/volta/`**用户无需单独安装**。
> 与系统 Node.js 完全隔离Volta 安装的工具位于 `~/.desirecore/runtime/volta/tools/image/`,不修改系统 PATH。
## L1通过 HTTP API 操作推荐DesireCore 应用内)
### 探测 API 可用性
```bash
PORT_FILE="$HOME/.desirecore/agent-service.port"
[ -r "$PORT_FILE" ] || { echo "API 不可用,降级到 L2"; exit 1; }
PORT=$(cat "$PORT_FILE")
BASE="https://127.0.0.1:${PORT}/api/runtime"
curl -sk --max-time 0.5 "${BASE}/environment" >/dev/null \
|| { echo "API 超时,降级到 L2"; exit 1; }
```
### Volta 自身
```bash
curl -sk "${BASE}/volta/status"
curl -sk -X POST "${BASE}/volta/install" # 自动下载到 runtime/
```
### Node.js 版本
```bash
# 已装版本
curl -sk "${BASE}/node/installed"
# 可装版本(远端 nodejs.org/dist 或 GitHub Releases
curl -sk "${BASE}/node/available"
# ❗ 若返回 502说明远端 / 镜像不可达,立即降级到 L2
# 安装(异步,立即返回 taskId
curl -sk -X POST "${BASE}/node/install" \
-H "Content-Type: application/json" \
-d '{"version":"22"}'
# 移除
curl -sk -X POST "${BASE}/node/remove" \
-H "Content-Type: application/json" \
-d '{"version":"20.10.0"}'
```
### 包管理器pnpm / yarn / npm
```bash
TOOL="pnpm" # 或 yarn / npm
curl -sk "${BASE}/pkg/${TOOL}/installed"
curl -sk "${BASE}/pkg/${TOOL}/available"
curl -sk -X POST "${BASE}/pkg/${TOOL}/install" \
-H "Content-Type: application/json" \
-d '{"version":"latest"}'
curl -sk -X POST "${BASE}/pkg/${TOOL}/remove" \
-H "Content-Type: application/json" \
-d '{"version":"9.0.0"}'
```
### 实时输出 / 缓存刷新
异步任务:监听 Socket.IO 事件 `runtime:terminal` / `runtime:complete`,按 taskId 过滤。
```bash
curl -sk -X POST "${BASE}/environment/refresh" # 安装结束后刷新
```
## L2直接调用 Volta CLI 绝对路径
### macOS / Linux
```bash
VOLTA=~/.desirecore/runtime/volta/volta
export VOLTA_HOME=~/.desirecore/runtime/volta
export VOLTA_FEATURE_PNPM=1
# export VOLTA_NODE_MIRROR=https://npmmirror.com/mirrors/node # 中国大陆加速
# 安装
"$VOLTA" install node@22 # 最新 22.x
"$VOLTA" install node@20.11.0 # 精确版本
"$VOLTA" install pnpm@latest
"$VOLTA" install yarn@latest
"$VOLTA" install npm@10
# 列表
"$VOLTA" list all
"$VOLTA" list node
# 项目级固定(写入 package.json#volta
"$VOLTA" pin node@22 pnpm@9
```
`volta pin``package.json` 中会自动追加:
```json
"volta": {
"node": "22.11.0",
"pnpm": "9.5.0"
}
```
后续 `cd` 进项目目录时 Volta 自动激活对应版本。
### Windows PowerShell
```powershell
$Volta = "$env:USERPROFILE\.desirecore\runtime\volta\volta.exe"
$env:VOLTA_HOME = "$env:USERPROFILE\.desirecore\runtime\volta"
$env:VOLTA_FEATURE_PNPM = "1"
& $Volta install node@22
& $Volta install pnpm@latest
& $Volta list all
```
### 移除
Volta 没有 `volta uninstall node`,直接删目录或用 HTTP API
```bash
rm -rf ~/.desirecore/runtime/volta/tools/image/node/<version>
```
或:
```bash
curl -sk -X POST "${BASE}/node/remove" -H "Content-Type: application/json" -d '{"version":"22.11.0"}'
```
## 可视化管理
DesireCore 应用 → 资源管理器 → 计算资源 → **运行环境** TabGUI 安装/删除 Node.js 与包管理器。
## 版本自动切换(核心优势)
只要 `package.json` 中有 `volta` 字段Volta 会在 `cd` 进入目录时**自动激活**对应版本。无需手动 `volta use`,也无需 `.nvmrc`
## Volta vs nvm
| 维度 | VoltaDesireCore 内置) | nvm社区 |
|------|--------------------------|-------------|
| 安装方式 | 随 DesireCore 内置 | 用户手动 |
| 版本切换 | **自动**(基于 package.json | 手动 `nvm use``.nvmrc` |
| 包管理器 | 支持pnpm/yarn/npm 都可固定版本) | 不支持 |
| Windows 原生 | ✅ | 需 nvm-windows功能受限 |
| 速度 | 极快Rust 实现) | 较慢shell 脚本) |
| 系统 PATH | 不污染 | 修改 PATH |
| GUI | DesireCore 运行环境 Tab | 无 |
| 镜像加速 | `VOLTA_NODE_MIRROR` | 无内建支持 |
**结论**DesireCore 应用内、有 Volta 时永远首选 Volta外部脚本可考虑 nvm/fnm。
## 故障排查Volta 专属)
| 现象 | 排查 |
|------|------|
| `volta: not found` | 二进制未释放,调 `POST /api/runtime/volta/install` |
| `Volta error: Could not download node v22.x.x` | 网络或镜像问题,设 `VOLTA_NODE_MIRROR` |
| `volta install pnpm` 报错 | 检查 `VOLTA_FEATURE_PNPM=1` 是否设置 |
| Windows Defender 隔离 volta.exe | 信任 `~\.desirecore\runtime\volta\` 目录 |
| `cd` 进项目后版本未切换 | 确认 `package.json``volta` 字段且 PATH 中 Volta shim 在最前 |

View File

@@ -0,0 +1,119 @@
#!/usr/bin/env bash
# nodejs-runtime probe: 输出 Node.js 环境快照JSON
# 协议:见 ../../dev-environment-setup/references/probe-snapshot.md
set +e
detect_tool() {
local name="$1"
local path
path=$(command -v "$name" 2>/dev/null)
if [ -z "$path" ]; then
printf '{"path":"","version":""}'
return
fi
local version
version=$("$name" --version 2>&1 | head -n1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)
printf '{"path":"%s","version":"%s"}' "$path" "${version:-}"
}
# ── 平台 ────────────────────────────────
case "$(uname -s)" in
Darwin) PLATFORM="darwin" ;;
Linux) PLATFORM="linux" ;;
*) PLATFORM="other" ;;
esac
ARCH=$(uname -m)
case "$ARCH" in
arm64|aarch64) ARCH="arm64" ;;
x86_64|amd64) ARCH="x64" ;;
esac
# ── DesireCore API ──────────────────────
DESIRECORE_API=""
PORT_FILE="$HOME/.desirecore/agent-service.port"
if [ -r "$PORT_FILE" ]; then
PORT=$(cat "$PORT_FILE" 2>/dev/null | tr -d '[:space:]')
if [ -n "$PORT" ]; then
if curl -sk --max-time 0.5 "https://127.0.0.1:${PORT}/api/runtime/environment" >/dev/null 2>&1; then
DESIRECORE_API="https://127.0.0.1:${PORT}"
fi
fi
fi
# ── 系统 Node / npm ─────────────────────
SYS_NODE=$(detect_tool node)
SYS_NPM=$(detect_tool npm)
# ── DesireCore Volta ────────────────────
VOLTA_BIN="$HOME/.desirecore/runtime/volta/volta"
VOLTA_PATH=""
VOLTA_VERSION=""
if [ -x "$VOLTA_BIN" ]; then
VOLTA_PATH="$VOLTA_BIN"
VOLTA_VERSION=$("$VOLTA_BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -n1)
fi
# Volta 已装工具(直接读 image 目录最稳)
VOLTA_IMG="$HOME/.desirecore/runtime/volta/tools/image"
list_dir() {
local dir="$1"
if [ -d "$dir" ]; then
local items
items=$(ls -1 "$dir" 2>/dev/null | sort -V | tr '\n' ',' | sed 's/,$//')
if [ -n "$items" ]; then
echo "[\"$(echo "$items" | sed 's/,/","/g')\"]"
return
fi
fi
echo "[]"
}
NODE_VERSIONS=$(list_dir "$VOLTA_IMG/node")
PNPM_VERSIONS=$(list_dir "$VOLTA_IMG/pnpm")
YARN_VERSIONS=$(list_dir "$VOLTA_IMG/yarn")
NPM_VERSIONS=$(list_dir "$VOLTA_IMG/npm")
# ── package.json#volta ──────────────────
PKG_VOLTA="null"
if [ -f "package.json" ]; then
PKG_VOLTA=$(python3 -c "import json,sys; d=json.load(open('package.json')); print(json.dumps(d.get('volta')))" 2>/dev/null || echo "null")
[ -z "$PKG_VOLTA" ] && PKG_VOLTA="null"
fi
# ── 社区方案 ────────────────────────────
NVM_PATH=""
[ -s "$HOME/.nvm/nvm.sh" ] && NVM_PATH="$HOME/.nvm/nvm.sh"
FNM_PATH=$(command -v fnm 2>/dev/null)
# ── npm config ──────────────────────────
REGISTRY=""
PROXY=""
if command -v npm >/dev/null 2>&1; then
REGISTRY=$(npm config get registry 2>/dev/null | tr -d '\r\n')
PROXY=$(npm config get https-proxy 2>/dev/null | tr -d '\r\n')
[ "$PROXY" = "null" ] && PROXY=""
fi
# ── 输出 JSON ───────────────────────────
cat <<EOF
{
"platform": "${PLATFORM}",
"arch": "${ARCH}",
"desirecore_api": "${DESIRECORE_API}",
"system_node": ${SYS_NODE},
"system_npm": ${SYS_NPM},
"volta_path": "${VOLTA_PATH}",
"volta_version": "${VOLTA_VERSION}",
"volta_tools": {
"node": ${NODE_VERSIONS},
"pnpm": ${PNPM_VERSIONS},
"yarn": ${YARN_VERSIONS},
"npm": ${NPM_VERSIONS}
},
"package_json_volta": ${PKG_VOLTA},
"nvm_path": "${NVM_PATH}",
"fnm_path": "${FNM_PATH:-}",
"registry": "${REGISTRY}",
"proxy": "${PROXY}"
}
EOF