Files
sproutclaw-data/agent/extensions/sproutclaw-setup/index.ts
shumengya 50edff80f5 feat: 导出 SproutClaw .sproutclaw 配置
包含 extensions、skills、prompts、settings、auth、models、mcp 等配置。
排除 node_modules、npm 缓存、sessions 等运行时数据。
2026-06-26 15:48:56 +08:00

187 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* sproutclaw / mengya 命令安装扩展
*
* 在 Linux 和 Windows 上分别创建/更新以下命令:
* - mengya源码版Linux: ./test.shWindows: test.bat
* - sproutclaw构建版Linux: ./build.shWindows: build.bat
*
* 不再安装 `pi` 命令,避免与原版 pi 冲突。
*
* Linux 命令安装到 /usr/local/bin/。
* Windows 批处理文件创建在项目根目录,需要把项目根目录加入 PATH 后全局使用。
*
* 命令 /install-commands 可随时手动重装。
*/
import { existsSync, writeFileSync, chmodSync, readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const extensionDir = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
const SPROUTCLAW_DIR = dirname(dirname(dirname(dirname(extensionDir))));
const LINUX_BIN_DIR = "/usr/local/bin";
function linuxMengyaScript(): string {
return `#!/usr/bin/env bash
set -euo pipefail
SPROUTCLAW_DIR="${SPROUTCLAW_DIR}"
exec "$SPROUTCLAW_DIR/test.sh" "$@"
`;
}
function linuxSproutclawScript(): string {
return `#!/usr/bin/env bash
set -euo pipefail
SPROUTCLAW_DIR="${SPROUTCLAW_DIR}"
BUILD_SH="$SPROUTCLAW_DIR/build.sh"
case "\${1:-}" in
\tbuild)
\t\tshift
\t\tcd "$SPROUTCLAW_DIR"
\t\texec npm run build "$@"
\t\t;;
\trun)
\t\tshift
\t\texec "$BUILD_SH" "$@"
\t\t;;
\thelp|-h|--help)
\t\tcat <<'EOF'
sproutclaw - SproutClaw 构建版启动器
用法:
sproutclaw 启动 SproutClaw构建版
sproutclaw run [args] 同 sproutclaw
sproutclaw build 从源码构建所有包
在工作目录中启动agent 配置仍使用安装目录下的 .sproutclaw/agent。
其余参数透传给 SproutClaw例如: sproutclaw --version
EOF
\t\t;;
\t*)
\t\texec "$BUILD_SH" "$@"
\t\t;;
esac
`;
}
function windowsMengyaBat(): string {
return `@echo off
setlocal
set "SCRIPT_DIR=%~dp0"
if "%SCRIPT_DIR:~-1%"=="\\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
if not defined SPROUTCLAW_CODING_AGENT_DIR (
set "SPROUTCLAW_CODING_AGENT_DIR=%SCRIPT_DIR%\\.sproutclaw\\agent"
)
call "%SCRIPT_DIR%\\test.bat" %*
exit /b %ERRORLEVEL%
`;
}
function windowsSproutclawBat(): string {
return `@echo off
setlocal
set "SCRIPT_DIR=%~dp0"
if "%SCRIPT_DIR:~-1%"=="\\" set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
if not defined SPROUTCLAW_CODING_AGENT_DIR (
set "SPROUTCLAW_CODING_AGENT_DIR=%SCRIPT_DIR%\\.sproutclaw\\agent"
)
if "%~1"=="" goto run
if /I "%~1"=="run" (
shift
goto run
)
if /I "%~1"=="build" (
shift
npm run build %*
exit /b %ERRORLEVEL%
)
if /I "%~1"=="help" goto help
if "%~1"=="-h" goto help
if "%~1"=="--help" goto help
:run
call "%SCRIPT_DIR%\\build.bat" %*
exit /b %ERRORLEVEL%
:help
echo sproutclaw - SproutClaw 构建版启动器
echo.
echo 用法:
echo sproutclaw 启动 SproutClaw构建版
echo sproutclaw run [args] 同 sproutclaw
echo sproutclaw build 从源码构建所有包
echo.
echo 其余参数透传给 SproutClaw例如: sproutclaw --version
exit /b 0
`;
}
function writeIfChanged(path: string, content: string, mode?: number): boolean {
if (existsSync(path)) {
try {
const current = readFileSync(path, "utf-8");
if (current === content) return false;
} catch {
// Rewrite unreadable or invalid files below.
}
}
writeFileSync(path, content, "utf-8");
if (mode !== undefined) chmodSync(path, mode);
return true;
}
function installLinuxCommands(): string[] {
const created: string[] = [];
if (writeIfChanged(join(LINUX_BIN_DIR, "mengya"), linuxMengyaScript(), 0o755)) {
created.push("/usr/local/bin/mengya");
}
if (writeIfChanged(join(LINUX_BIN_DIR, "sproutclaw"), linuxSproutclawScript(), 0o755)) {
created.push("/usr/local/bin/sproutclaw");
}
return created;
}
function installWindowsCommands(): string[] {
const created: string[] = [];
if (writeIfChanged(join(SPROUTCLAW_DIR, "mengya.bat"), windowsMengyaBat())) {
created.push(join(SPROUTCLAW_DIR, "mengya.bat"));
}
if (writeIfChanged(join(SPROUTCLAW_DIR, "sproutclaw.bat"), windowsSproutclawBat())) {
created.push(join(SPROUTCLAW_DIR, "sproutclaw.bat"));
}
return created;
}
export default function (pi: ExtensionAPI) {
const isWindows = process.platform === "win32";
function install(): string[] {
return isWindows ? installWindowsCommands() : installLinuxCommands();
}
const created = install();
for (const path of created) {
console.log(`[sproutclaw-setup] Created/updated ${path}`);
}
pi.registerCommand("install-commands", {
description: isWindows
? "Install mengya.bat (source) and sproutclaw.bat (built) to the repo root"
: "Install mengya (source) and sproutclaw (built) to /usr/local/bin",
handler: async (_args, ctx) => {
const paths = install();
if (paths.length > 0) {
ctx.ui.notify(`Installed/updated ${paths.length} command(s):\n${paths.join("\n")}`, "success");
} else {
ctx.ui.notify("Commands already up to date", "info");
}
if (isWindows) {
ctx.ui.notify(`请把项目目录加入 PATH 以全局使用:\n${SPROUTCLAW_DIR}`, "info");
}
},
});
}