feat(sproutclaw): modularize webui, extensions, and agent config layout
Some checks failed
CI / build-check-test (push) Has been cancelled

Restructure local extensions into per-feature directories, split WebUI
into backend modules with slash commands and systemd support, and track
prompts/skills under .pi/agent for portable Gitea deployment.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
root
2026-06-10 16:57:08 +08:00
parent 11c3a3a399
commit cf5edd6394
132 changed files with 9288 additions and 1971 deletions

View File

@@ -0,0 +1,107 @@
/**
* sproutclaw / mengya 命令安装扩展
*
* 启动后自动在 /usr/local/bin/ 下创建 mengya 和 sproutclaw 命令:
* - mengya源码版./pi-test.shtsx + src
* - sproutclaw构建版./pi-built.shnode dist/cli.js
*
* 命令 /install-commands 可随时手动重装。
*/
import { existsSync, writeFileSync, chmodSync, readFileSync } from "node:fs";
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
const SPROUTCLAW_DIR = "/shumengya/project/agent/sproutclaw";
const BIN_DIR = "/usr/local/bin";
const COMMAND_LAUNCHERS: Record<string, string> = {
mengya: "./pi-test.sh",
};
function commandScript(launcher: string): string {
return `#!/usr/bin/env bash
set -euo pipefail
cd ${SPROUTCLAW_DIR}
exec ${launcher} "$@"
`;
}
function sproutclawScript(): string {
return `#!/usr/bin/env bash
set -euo pipefail
cd ${SPROUTCLAW_DIR}
case "\${1:-}" in
\tbuild)
\t\tshift
\t\texec npm run build "\$@"
\t\t;;
\trun)
\t\tshift
\t\texec ./pi-built.sh "\$@"
\t\t;;
\thelp|-h|--help)
\t\tcat <<'EOF'
sproutclaw - SproutClaw pi 构建版启动器
用法:
sproutclaw 启动 pi构建版
sproutclaw run [args] 同 sproutclaw
sproutclaw build 从源码构建所有包
其余参数透传给 pi例如: sproutclaw --version
EOF
\t\t;;
\t*)
\t\texec ./pi-built.sh "\$@"
\t\t;;
esac
`;
}
/** 创建或修复命令脚本 */
function installCommand(name: string, script: string): boolean {
const path = `${BIN_DIR}/${name}`;
if (existsSync(path)) {
try {
const current = readFileSync(path, "utf-8");
if (current === script) return false;
} catch {
// Rewrite unreadable or invalid command files below.
}
}
writeFileSync(path, script, "utf-8");
chmodSync(path, 0o755);
return true;
}
export default function (pi: ExtensionAPI) {
for (const [name, launcher] of Object.entries(COMMAND_LAUNCHERS)) {
const created = installCommand(name, commandScript(launcher));
if (created) {
console.log(`[sproutclaw-setup] Created /usr/local/bin/${name}`);
}
}
const sproutclawCreated = installCommand("sproutclaw", sproutclawScript());
if (sproutclawCreated) {
console.log("[sproutclaw-setup] Created /usr/local/bin/sproutclaw");
}
pi.registerCommand("install-commands", {
description: "Install mengya (source) and sproutclaw (built) commands to /usr/local/bin",
handler: async (_args, ctx) => {
let count = 0;
for (const [name, launcher] of Object.entries(COMMAND_LAUNCHERS)) {
if (installCommand(name, commandScript(launcher))) count++;
}
if (installCommand("sproutclaw", sproutclawScript())) count++;
if (count > 0) {
ctx.ui.notify(`Installed ${count} command(s): mengya (source), sproutclaw (build/run)`, "success");
} else {
ctx.ui.notify("Commands already up to date", "info");
}
},
});
}