feat: Mac 控制端一键安装(pack:mac + install-macos.sh)

Mac 是控制端,不需要 Windows 安装包,但此前必须 cd 到仓库敲
node apps/cli/dist/index.js,太啰嗦。

新增:
- pnpm pack:mac(scripts/pack-macos.mjs):把 CLI 与 MCP 打包为带 shebang 的
  可执行单文件(195KB / 772KB),免 node_modules
- scripts/install-macos.sh:安装到 ~/.local/bin(已在 PATH)+ 打印 MCP 配置片段
- Mac 端不打 Node 运行时(控制端本机已有 Node,体积从约 50MB 降到约 1MB)

修复:execFileSync 不能接收带参数的命令字符串(改用 execSync)

验证:./nodeagent --help 与 MCP tools/list(18) 可直接执行;
install-macos.sh 安装后可在任意目录调用 nodeagent
This commit is contained in:
jkooe committed 2026-09-27 19:24:57 +08:00
1 parent 4c9b44288c
commit 665c0e85c4
4 files changed
+169 -13

No files matched your search

+37 -12
View File
@@ -66,21 +66,46 @@ powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
### 2. Mac 侧(控制端)
> Mac 作为控制端,**不需要**上面的 Windows 安装包;只需本机 Node.js 22+(`brew install node`)。
**方式 A:装成全局命令(推荐,随处可用)**
```bash
# 局域网内先自动发现有哪些 Windows(免手抄 IP)
node apps/cli/dist/index.js discover --wait 5
# 连接并命名设备(自签证书需 --insecure)
node apps/cli/dist/index.js connect 192.168.1.100 --port 8765 --key <密钥> --insecure --name win_a
# 开始使用
node apps/cli/dist/index.js info # 系统信息
node apps/cli/dist/index.js status # CPU / 内存 / 磁盘 / 网络
node apps/cli/dist/index.js exec "Get-Service Spooler"
node apps/cli/dist/index.js install Microsoft.VisualStudioCode
node apps/cli/dist/index.js screenshot --out s.jpg --scale 0.5
cd <项目目录>
pnpm pack:mac # 打包为单文件(约 1MB,免 node_modules)
bash scripts/install-macos.sh # 安装到 ~/.local/bin 并打印 MCP 配置
```
装好后命令行直接可用:
```bash
nodeagent discover --wait 5 # 局域网内有哪些 Windows(免手抄 IP)
nodeagent connect 192.168.1.100 --key <密钥> --insecure --name win_a
nodeagent info
```
**方式 B:仓库内直接调用(开发调试)**
```bash
node apps/cli/dist/index.js discover --wait 5
node apps/cli/dist/index.js info
```
**常用命令**
```bash
nodeagent info | status | ps | services # 系统与资源
nodeagent exec "Get-Service Spooler" # 执行命令
nodeagent install Microsoft.VisualStudioCode # 装软件
nodeagent apps # 已安装软件
nodeagent screen # 显示器信息
nodeagent screenshot --out s.jpg --scale 0.5 # 截屏
nodeagent ls "C:\Users\me\Desktop" --recursive # 列目录
nodeagent pull "C:\big.iso" --out ./big.iso # 下载(大文件自动分块)
```
> 完整命令见下方「命令速查」。
### 3. 接入 AI(MCP)
在 `~/.workbuddy/mcp.json` 中加入:
+2 -1
View File
@@ -18,7 +18,8 @@
"test:e2e": "node tests/e2e/run.mjs",
"test:windows": "node tests/e2e/windows.mjs",
"verify": "node scripts/verify.mjs",
"pack:win": "node scripts/pack.mjs"
"pack:win": "node scripts/pack.mjs",
"pack:mac": "node scripts/pack-macos.mjs"
},
"devDependencies": {
"@types/node": "^22.10.2",
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
#
# 把 nodeagent 控制端安装到 ~/.local/bin(通常已在 PATH 中)。
#
# 用法:
# pnpm pack:mac && bash scripts/install-macos.sh
# NODEAGENT_BIN_DIR=/usr/local/bin bash scripts/install-macos.sh
#
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SRC="$ROOT/release/nodeagent-macos"
BIN_DIR="${NODEAGENT_BIN_DIR:-$HOME/.local/bin}"
# 1. 检查 Node.js(Mac 作为控制端需要本机 Node;不像 Windows 被控端可自带运行时)
if ! command -v node >/dev/null 2>&1; then
echo "✗ 未找到 Node.js。请先安装 Node.js 22+(推荐: brew install node)" >&2
exit 1
fi
VER="$(node --version | tr -d 'v')"
MAJOR="${VER%%.*}"
if [ "$MAJOR" -lt 22 ]; then
echo "✗ 需要 Node.js 22+,当前 v$VER" >&2
exit 1
fi
echo "✓ Node.js v$VER"
# 2. 检查构建产物
if [ ! -f "$SRC/nodeagent" ] || [ ! -f "$SRC/nodeagent-mcp" ]; then
echo "✗ 未找到构建产物:$SRC" >&2
echo " 请先在项目目录运行: pnpm pack:mac" >&2
exit 1
fi
# 3. 安装(install 会设置 755 权限)
mkdir -p "$BIN_DIR"
install -m 755 "$SRC/nodeagent" "$BIN_DIR/nodeagent"
install -m 755 "$SRC/nodeagent-mcp" "$BIN_DIR/nodeagent-mcp"
echo "✓ 已安装到 $BIN_DIR"
echo " - nodeagent 控制端 CLI"
echo " - nodeagent-mcp MCP server(供 WorkBuddy 调用)"
# 4. PATH 检查
case ":$PATH:" in
*":$BIN_DIR:"*) ;;
*)
echo "⚠️ $BIN_DIR 不在 PATH 中,请追加到 ~/.zshrc:"
echo " export PATH=\"$BIN_DIR:\$PATH\""
;;
esac
# 5. 打印 MCP 配置片段
cat <<EOF
── 把下面这段加入 ~/.workbuddy/mcp.json ─────────────────────────
{
"mcpServers": {
"nodeagent": {
"command": "$BIN_DIR/nodeagent-mcp"
}
}
}
────────────────────────────────────────────────────────────────
验证: nodeagent --help
EOF
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env node
/**
* 构建 macOS 控制端(免 node_modules 的单文件)。
*
* 用法: node scripts/pack-macos.mjs [--out release]
*
* 产物: <out>/nodeagent-macos/
* ├── nodeagent 控制端 CLI(可执行,含 shebang)
* └── nodeagent-mcp MCP server(可执行,含 shebang)
*
* 说明: Mac 作为控制端,通常本机已装 Node.js,故不打运行时(体积从 ~50MB 降到 ~1MB)。
*/
import { execFileSync, execSync } from 'node:child_process';
import { chmodSync, mkdirSync, rmSync, statSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, '..');
const args = process.argv.slice(2);
const getArg = (k, d) => {
const i = args.indexOf(k);
return i >= 0 && args[i + 1] ? args[i + 1] : d;
};
const OUT_DIR = getArg('--out', join(root, 'release'));
const PKG_DIR = join(OUT_DIR, 'nodeagent-macos');
const esbuild = join(root, 'node_modules', '.bin', 'esbuild');
const SHEBANG = '#!/usr/bin/env node';
// MCP server 经 stdio 通信,日志必须走 stderr;banner 同时补 createRequire 兼容 CJS 依赖
const BANNER = 'import { createRequire } from "node:module"; const require = createRequire(import.meta.url);';
function bundle(entry, outfile) {
execFileSync(
esbuild,
[
join(root, entry),
'--bundle',
'--platform=node',
'--target=node22',
'--format=esm',
`--banner:js=${SHEBANG}\n${BANNER}`,
`--outfile=${outfile}`,
],
{ stdio: 'inherit' },
);
chmodSync(outfile, 0o755);
const kb = (statSync(outfile).size / 1024).toFixed(0);
console.log(` ✓ ${outfile.replace(`${root}/`, '')} (${kb}KB)`);
}
console.log('=== ① 构建 workspace ===');
execSync('pnpm -r build', { cwd: root, stdio: 'inherit' });
console.log('\n=== ② 打包控制端 ===');
rmSync(PKG_DIR, { recursive: true, force: true });
mkdirSync(PKG_DIR, { recursive: true });
bundle('apps/cli/dist/index.js', join(PKG_DIR, 'nodeagent'));
bundle('apps/mcp/dist/index.js', join(PKG_DIR, 'nodeagent-mcp'));
console.log(`\n✓ 完成: ${PKG_DIR}`);
console.log(' 下一步: bash scripts/install-macos.sh(安装到 ~/.local/bin)');