feat: 导出 SproutClaw .sproutclaw 配置

包含 extensions、skills、prompts、settings、auth、models、mcp 等配置。
排除 node_modules、npm 缓存、sessions 等运行时数据。
This commit is contained in:
2026-06-26 15:48:56 +08:00
commit 50edff80f5
13904 changed files with 411646 additions and 0 deletions

View File

@@ -0,0 +1,186 @@
/**
* 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");
}
},
});
}