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,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