AI Newsletter Digest improvements: fixed QP soft line break decoding, URL extraction, and content cleaning

This commit is contained in:
Krilly
2026-03-04 13:29:22 +00:00
parent 29a98137a7
commit 57dd294675
13706 changed files with 2114953 additions and 237629 deletions

View File

@@ -0,0 +1,58 @@
---
name: "openclaw-toolbox"
description: "Integrated OpenClaw management suite for environment initialization, maintenance, and multi-mode backup (Full/Skills)."
author: "Wilsonsliu95 (https://github.com/WilsonLiu95)"
---
# OpenClaw Toolbox
OpenClaw 综合管理工具箱,集成环境初始化、系统维护及多模式备份功能。
## Quick Start
### 1. 环境初始化 (Setup)
```bash
# 适合新设备首次部署或环境修复
"~/.openclaw/workspace/skills/openclaw-toolbox/scripts/setup.sh"
```
### 2. 系统备份 (Backup)
```bash
# 备份整个 OpenClaw 仓库(系统配置、人设、记忆等)
"~/.openclaw/workspace/skills/openclaw-toolbox/scripts/backup-now.sh" --full "定期备份"
# 备份 Skills 开发仓库
"~/.openclaw/workspace/skills/openclaw-toolbox/scripts/backup-now.sh" --skills "更新技能库"
# 备份并升级(先拉取再备份)
"~/.openclaw/workspace/skills/openclaw-toolbox/scripts/backup-now.sh" --pull
```
## 常用命令与参数
### Setup 脚本参数
- `--update`: 拉取最新仓库(工作区干净时)
- `--verify-only`: 仅验证安装状态
- `--reset-env`: 重新生成 `.env`(自动备份旧文件)
- `--skip-node` / `--skip-packages` / `--skip-env` / `--skip-mcp`
### Backup 脚本参数
- `--full`: 备份整个 OpenClaw 仓库 (默认)
- `--skills`: 备份 `workspace/projects/openclaw-skills` 仓库
- `--pull`: 备份前先执行 `git pull --rebase` (升级同步)
- `--no-push`: 只提交,不推送
- `--dry-run`: 仅显示变更预览
- `-m, --message`: 自定义提交信息
## 环境要求
- 已设置 `OPENCLAW_SKILLS_GITHUB_URL` 环境变量(用于 Skills 备份)
- 已安装 Git 且配置好 GitHub 访问权限SSH 或 PAT
## 运行逻辑
- **Setup**: 自动化配置 Node.js、安装核心 CLI、生成配置文件模板并验证环境。
- **Backup**: 智能识别仓库类型,处理 Git 暂存、提交及远程推送。
---
*🦐 虾宝宝工具箱 —— 守护刘家 AI 环境*

View File

@@ -0,0 +1,6 @@
{
"ownerId": "kn7fy1v71qjr44t45px34w2a0580mmfz",
"slug": "openclaw-toolbox",
"version": "1.0.0",
"publishedAt": 1770414272979
}

View File

@@ -0,0 +1,4 @@
interface:
display_name: "OpenClaw Setup"
short_description: "Initialize OpenClaw environment"
default_prompt: "Run the OpenClaw setup script and summarize the results."

View File

@@ -0,0 +1,207 @@
#!/bin/bash
# OpenClaw 立即备份脚本
# 使用方法: ./backup-now.sh ["自定义提交信息"]
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 尝试寻找 OpenClaw 根目录 (~/.openclaw)
# 逻辑:从脚本目录向上查找,直到找到 openclaw.json 或 .env 文件
FIND_ROOT="$SCRIPT_DIR"
ROOT_DIR=""
while [ "$FIND_ROOT" != "/" ]; do
if [ -f "$FIND_ROOT/openclaw.json" ] || [ -f "$FIND_ROOT/.env" ]; then
ROOT_DIR="$FIND_ROOT"
break
fi
FIND_ROOT="$(dirname "$FIND_ROOT")"
done
# 如果没找到,退回到预设的相对路径
if [ -z "$ROOT_DIR" ]; then
ROOT_DIR="$(cd "$SCRIPT_DIR/../../../../" && pwd)"
fi
SKILLS_DIR="$ROOT_DIR/workspace/projects/openclaw-skills"
# 加载 .env 环境变量
if [ -f "$ROOT_DIR/.env" ]; then
# 使用 grep 和 sed 处理 .env 文件,避免直接 source 可能带来的安全风险或语法错误
export $(grep -v '^#' "$ROOT_DIR/.env" | xargs)
fi
BACKUP_TYPE="full"
BACKUP_DIR="$ROOT_DIR"
GIT_REMOTE="origin"
NO_PUSH=0
DRY_RUN=0
PULL_BEFORE=0
COMMIT_MSG=""
# 颜色输出
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
usage() {
cat <<'USAGE'
Usage:
backup-now.sh [message] [options]
Options:
--full 备份整个 OpenClaw 仓库 (默认)
--skills 备份 openclaw-skills 仓库
--pull 备份前先 git pull --rebase要求工作区干净
--no-push 只提交,不推送
--dry-run 仅显示变更,不提交
-m, --message 提交信息
-h, --help 显示帮助
USAGE
}
parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
--full)
BACKUP_TYPE="full"
BACKUP_DIR="$ROOT_DIR"
;;
--skills)
BACKUP_TYPE="skills"
BACKUP_DIR="$SKILLS_DIR"
;;
--pull) PULL_BEFORE=1 ;;
--no-push) NO_PUSH=1 ;;
--dry-run) DRY_RUN=1 ;;
-m|--message)
shift
COMMIT_MSG="$1"
;;
-h|--help)
usage
exit 0
;;
*)
if [ -z "$COMMIT_MSG" ]; then
COMMIT_MSG="$1"
else
COMMIT_MSG="$COMMIT_MSG $1"
fi
;;
esac
shift
done
}
parse_args "$@"
echo -e "${BLUE}🔄 开始 ${BACKUP_TYPE} 备份...${NC}"
if [ ! -d "$BACKUP_DIR" ]; then
if [ "$BACKUP_TYPE" == "skills" ] && [ -n "$OPENCLAW_SKILLS_GITHUB_URL" ]; then
echo -e "${YELLOW}⚠️ Skills 目录不存在,尝试克隆...${NC}"
mkdir -p "$(dirname "$SKILLS_DIR")"
git clone "$OPENCLAW_SKILLS_GITHUB_URL" "$SKILLS_DIR"
else
echo -e "${RED}✗ 备份目录不存在: $BACKUP_DIR${NC}"
exit 1
fi
fi
cd "$BACKUP_DIR"
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo -e "${RED}✗ 当前目录不是 Git 仓库: $BACKUP_DIR${NC}"
exit 1
fi
if ! git remote get-url "$GIT_REMOTE" >/dev/null 2>&1; then
GIT_REMOTE="$(git remote | head -n1)"
fi
if [ -z "$GIT_REMOTE" ]; then
echo -e "${YELLOW}⚠️ 未找到 Git 远端${NC}"
fi
REPO_URL=""
if [ -n "$GIT_REMOTE" ]; then
REPO_URL="$(git remote get-url "$GIT_REMOTE" 2>/dev/null || true)"
fi
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
echo -e "${BLUE}🔄 开始 ${BACKUP_TYPE} 备份...${NC}"
if [ "$PULL_BEFORE" -eq 1 ]; then
if git diff --quiet && git diff --staged --quiet; then
echo -e "${BLUE}⬇️ 拉取最新代码...${NC}"
git pull --rebase || echo -e "${YELLOW}⚠️ git pull 失败,请手动处理${NC}"
else
echo -e "${YELLOW}⚠️ 工作区有未提交变更,跳过 git pull${NC}"
fi
fi
# 检查是否有更改
if [ -z "$(git status --porcelain)" ]; then
echo -e "${YELLOW}⚠️ 没有需要备份的更改${NC}"
exit 0
fi
if [ "$DRY_RUN" -eq 1 ]; then
echo -e "${BLUE}📄 变更预览:${NC}"
git status --short
exit 0
fi
# 统计更改的文件
CHANGED_FILES=$(git status --short | wc -l | tr -d ' ')
echo -e "${BLUE}📁 发现 ${CHANGED_FILES} 个文件有更改${NC}"
# 默认提交信息
if [ -z "$COMMIT_MSG" ]; then
case "$BACKUP_TYPE" in
full) DISPLAY_TYPE="Full" ;;
skills) DISPLAY_TYPE="Skills" ;;
*) DISPLAY_TYPE="Manual" ;;
esac
COMMIT_MSG="$DISPLAY_TYPE backup: $(date '+%Y-%m-%d %H:%M:%S')"
fi
# 添加所有更改
echo -e "${BLUE} 添加更改到暂存区...${NC}"
git add -A
# 提交
echo -e "${BLUE}💾 提交更改...${NC}"
git commit -m "$COMMIT_MSG"
# 推送到 GitHub
if [ "$NO_PUSH" -eq 0 ]; then
echo -e "${BLUE}☁️ 推送到 GitHub...${NC}"
if [ -n "$GIT_REMOTE" ] && [ -n "$CURRENT_BRANCH" ]; then
if ! git push "$GIT_REMOTE" "$CURRENT_BRANCH"; then
echo -e "${RED}✗ 推送失败:可能需要先 git pull --rebase${NC}"
exit 1
fi
else
if ! git push; then
echo -e "${RED}✗ 推送失败:请检查 Git 远端或设置上游分支${NC}"
exit 1
fi
fi
else
echo -e "${YELLOW}⚠️ 跳过推送(--no-push${NC}"
fi
echo -e "${GREEN}✅ 备份完成!${NC}"
echo -e "${BLUE}📦 仓库地址: ${REPO_URL:-N/A}${NC}"
if [ -n "$CURRENT_BRANCH" ]; then
echo -e "${BLUE}🌿 分支: ${GIT_REMOTE:-?}/${CURRENT_BRANCH}${NC}"
fi
echo -e "${BLUE}📝 提交信息: ${COMMIT_MSG}${NC}"
echo ""
echo -e "${YELLOW}💡 提示: 可以设置定时自动备份${NC}"

View File

@@ -0,0 +1,136 @@
#!/bin/bash
# OpenClaw 自动备份脚本
# 使用方法: ./backup.sh [commit message]
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_DIR="$(cd "$SCRIPT_DIR/../../.." && pwd)"
GIT_REMOTE="origin"
NO_PUSH=0
DRY_RUN=0
PULL_BEFORE=0
COMMIT_MSG=""
usage() {
cat <<'USAGE'
Usage:
backup.sh [message]
Options:
--pull 备份前先 git pull --rebase要求工作区干净
--no-push 只提交,不推送
--dry-run 仅显示变更,不提交
-m, --message 提交信息
-h, --help 显示帮助
USAGE
}
parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
--pull) PULL_BEFORE=1 ;;
--no-push) NO_PUSH=1 ;;
--dry-run) DRY_RUN=1 ;;
-m|--message)
shift
COMMIT_MSG="$1"
;;
-h|--help)
usage
exit 0
;;
*)
if [ -z "$COMMIT_MSG" ]; then
COMMIT_MSG="$1"
else
COMMIT_MSG="$COMMIT_MSG $1"
fi
;;
esac
shift
done
}
parse_args "$@"
cd "$BACKUP_DIR"
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "✗ 当前目录不是 Git 仓库: $BACKUP_DIR"
exit 1
fi
if ! git remote get-url "$GIT_REMOTE" >/dev/null 2>&1; then
GIT_REMOTE="$(git remote | head -n1)"
fi
if [ -z "$GIT_REMOTE" ]; then
echo "⚠️ 未找到 Git 远端"
fi
REPO_URL=""
if [ -n "$GIT_REMOTE" ]; then
REPO_URL="$(git remote get-url "$GIT_REMOTE" 2>/dev/null || true)"
fi
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
echo "🔄 开始备份 OpenClaw 配置..."
if [ "$PULL_BEFORE" -eq 1 ]; then
if git diff --quiet && git diff --staged --quiet; then
echo "⬇️ 拉取最新代码..."
git pull --rebase || echo "⚠️ git pull 失败,请手动处理"
else
echo "⚠️ 工作区有未提交变更,跳过 git pull"
fi
fi
# 检查是否有更改
if [ -z "$(git status --porcelain)" ]; then
echo "✅ 没有需要备份的更改"
exit 0
fi
if [ "$DRY_RUN" -eq 1 ]; then
echo "📄 变更预览:"
git status --short
exit 0
fi
# 默认提交信息
if [ -z "$COMMIT_MSG" ]; then
COMMIT_MSG="Backup: $(date '+%Y-%m-%d %H:%M:%S')"
fi
echo " 添加更改到暂存区..."
git add -A
echo "💾 提交更改..."
git commit -m "$COMMIT_MSG"
if [ "$NO_PUSH" -eq 0 ]; then
echo "☁️ 推送到 GitHub..."
if [ -n "$GIT_REMOTE" ] && [ -n "$CURRENT_BRANCH" ]; then
if ! git push "$GIT_REMOTE" "$CURRENT_BRANCH"; then
echo "✗ 推送失败:可能需要先 git pull --rebase"
exit 1
fi
else
if ! git push; then
echo "✗ 推送失败:请检查 Git 远端或设置上游分支"
exit 1
fi
fi
else
echo "⚠️ 跳过推送(--no-push"
fi
echo "✅ 备份完成!"
echo "📦 仓库地址: ${REPO_URL:-N/A}"
if [ -n "$CURRENT_BRANCH" ]; then
echo "🌿 分支: ${GIT_REMOTE:-?}/${CURRENT_BRANCH}"
fi
echo "📝 提交信息: $COMMIT_MSG"

View File

@@ -0,0 +1,487 @@
#!/bin/bash
#
# OpenClaw 一键初始化脚本
# 用于在新电脑上快速部署 OpenClaw 环境
# 作者: 虾宝宝 🦐
# 创建时间: 2026-02-05
#
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# OpenClaw 根目录(基于脚本位置)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/../../../../" && pwd)"
# 执行开关(可通过参数控制)
SKIP_NODE=0
SKIP_PACKAGES=0
SKIP_ENV=0
SKIP_MCP=0
SKIP_CLAUDE=0
SKIP_VERIFY=0
VERIFY_ONLY=0
UPDATE_REPO=0
RESET_ENV=0
# 打印函数
print_header() {
echo -e "${BLUE}================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
usage() {
cat <<'USAGE'
OpenClaw Setup Script
Usage:
setup.sh [options]
Options:
--update 拉取最新仓库git pull --rebase工作区需干净
--verify-only 仅做验证,不执行安装
--reset-env 重新生成 .env会备份旧文件
--skip-node 跳过 Node.js 安装
--skip-packages 跳过全局 CLI 安装
--skip-env 跳过 .env 配置
--skip-mcp 跳过 MCP 检查/配置
--skip-claude 跳过 Claude MCP 配置
--skip-verify 跳过安装验证
-h, --help 显示帮助
USAGE
}
# 检查命令是否存在
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# 解析参数
parse_args() {
while [ $# -gt 0 ]; do
case "$1" in
--update) UPDATE_REPO=1 ;;
--verify-only) VERIFY_ONLY=1 ;;
--reset-env) RESET_ENV=1 ;;
--skip-node) SKIP_NODE=1 ;;
--skip-packages) SKIP_PACKAGES=1 ;;
--skip-env) SKIP_ENV=1 ;;
--skip-mcp) SKIP_MCP=1 ;;
--skip-claude) SKIP_CLAUDE=1 ;;
--skip-verify) SKIP_VERIFY=1 ;;
-h|--help) usage; exit 0 ;;
*)
print_error "未知参数: $1"
usage
exit 1
;;
esac
shift
done
}
# 检查基础依赖
check_prereqs() {
print_header "检查基础依赖"
if command_exists git; then
print_success "Git 已安装"
else
print_error "未安装 Git请先安装"
exit 1
fi
if command_exists curl; then
print_success "curl 已安装"
else
print_error "未安装 curl请先安装"
exit 1
fi
}
# 检查 Node.js 版本
check_node_version() {
if command_exists node; then
NODE_VERSION=$(node --version | cut -d'v' -f2)
REQUIRED_VERSION="22.0.0"
if [ "$(printf '%s\n' "$REQUIRED_VERSION" "$NODE_VERSION" | sort -V | head -n1)" = "$REQUIRED_VERSION" ]; then
print_success "Node.js 版本符合要求: $NODE_VERSION"
return 0
else
print_warning "Node.js 版本过低: $NODE_VERSION,需要 >= $REQUIRED_VERSION"
return 1
fi
else
print_error "Node.js 未安装"
return 1
fi
}
# 安装 Node.js
install_node() {
print_header "安装 Node.js"
if command_exists nvm; then
print_success "nvm 已安装"
else
print_warning "安装 nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
fi
nvm install 22
nvm use 22
nvm alias default 22
print_success "Node.js $(node --version) 安装完成"
}
# 安装全局 npm 包
install_global_packages() {
print_header "安装全局 CLI"
if ! command_exists npm; then
print_error "npm 未安装,无法安装全局 CLI"
return 1
fi
# package:command
PACKAGES=(
"openclaw:openclaw"
"@openclaw/mcporter:mcporter"
"codex:codex"
"@anthropic-ai/claude-code:claude"
"@google/gemini-cli:gemini"
)
for entry in "${PACKAGES[@]}"; do
IFS=':' read -r pkg cmd <<< "$entry"
if command_exists "$cmd"; then
print_success "$cmd 已安装"
else
print_warning "安装 $pkg..."
npm install -g "$pkg" || print_error "$pkg 安装失败"
fi
done
print_success "全局 CLI 安装完成"
}
backup_file() {
local file_path="$1"
if [ -f "$file_path" ]; then
local ts
ts=$(date '+%Y%m%d-%H%M%S')
cp "$file_path" "${file_path}.bak.${ts}"
print_warning "已备份: ${file_path}.bak.${ts}"
fi
}
check_env_placeholders() {
if [ -f ".env" ]; then
if grep -n "your_\\|YOUR_" .env >/dev/null 2>&1; then
print_warning "发现未替换的 .env 占位符,请尽快填写"
grep -n "your_\\|YOUR_" .env || true
else
print_success ".env 已填写(未发现占位符)"
fi
fi
}
# 配置环境变量
setup_environment() {
print_header "配置环境变量"
if [ -f ".env" ] && [ "$RESET_ENV" -eq 0 ]; then
print_warning ".env 文件已存在,跳过创建"
print_warning "请检查 .env 文件中的 API Keys 是否正确配置"
check_env_placeholders
return 0
fi
if [ -f ".env" ] && [ "$RESET_ENV" -eq 1 ]; then
backup_file ".env"
rm -f .env
fi
if [ -f ".env.example" ]; then
cp .env.example .env
print_warning "已从 .env.example 创建 .env 文件"
print_warning "⚠️ 请编辑 .env 文件,填入你的实际 API Keys"
else
cat > .env << 'EOF'
# ============================================
# 模型/厂商 API Keys按需填写
# ============================================
ARK_API_KEY=your_ark_api_key_here
ZAI_API_KEY=your_zai_api_key_here
Z_AI_API_KEY=your_zai_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
OPENCODE_API_KEY=your_opencode_api_key_here
ANTHROPIC_API_KEY=your_anthropic_api_key_here
GEMINI_API_KEY=your_gemini_api_key_here
# ============================================
# 飞书 (Feishu)
# ============================================
FEISHU_APP_ID=your_feishu_app_id_main
FEISHU_APP_SECRET=your_feishu_app_secret_main
FEISHU_APP_ID_TEST=your_feishu_app_id_test
FEISHU_APP_SECRET_TEST=your_feishu_app_secret_test
# ============================================
# Telegram
# ============================================
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
# ============================================
# OpenClaw Gateway
# ============================================
OPENCLAW_GATEWAY_TOKEN=your_gateway_token
EOF
print_warning "已创建默认 .env 文件"
print_warning "⚠️ 请编辑 .env 文件,填入你的实际 API Keys"
fi
# 加载环境变量
export $(cat .env | grep -v '^#' | xargs) 2>/dev/null || true
check_env_placeholders
print_success "环境变量配置完成"
}
# 配置 MCP 服务器
setup_mcp_servers() {
print_header "配置 MCP 服务器"
if ! command_exists mcporter; then
print_warning "mcporter 未安装,跳过 MCP 检查"
return 0
fi
# 确保配置目录存在
mkdir -p "$ROOT_DIR/config"
# 检查 mcporter 配置
if [ -f "config/mcporter.json" ]; then
print_success "发现 mcporter.json 配置"
# 验证配置
if mcporter list >/dev/null 2>&1; then
print_success "MCP 服务器验证通过"
mcporter list
else
print_error "MCP 服务器验证失败,请检查配置和 API Keys"
fi
else
print_warning "未找到 config/mcporter.json跳过 MCP 配置"
fi
print_success "MCP 服务器配置完成"
}
# 配置 Claude Code MCP
setup_claude_mcp() {
print_header "配置 Claude Code MCP"
mkdir -p ~/.claude
# 从仓库配置复制
if [ -f ".claude/mcp.json" ]; then
if [ -f ~/.claude/mcp.json ]; then
backup_file ~/.claude/mcp.json
fi
cp .claude/mcp.json ~/.claude/mcp.json
print_success "已复制 Claude Code MCP 配置"
else
# 创建默认配置
if [ -f ~/.claude/mcp.json ]; then
print_warning "~/.claude/mcp.json 已存在,跳过创建"
else
cat > ~/.claude/mcp.json << 'EOF'
{
"mcpServers": {
"zai-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@z_ai/mcp-server"],
"env": {
"Z_AI_API_KEY": "your_zai_api_key_here",
"Z_AI_MODE": "ZHIPU"
}
}
}
}
EOF
print_warning "已创建默认 Claude Code MCP 配置"
print_warning "⚠️ 请编辑 ~/.claude/mcp.json填入你的实际 API Keys"
fi
fi
print_success "Claude Code MCP 配置完成"
}
# 更新仓库
update_repo() {
if [ "$UPDATE_REPO" -eq 0 ]; then
return 0
fi
print_header "更新仓库"
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
print_warning "当前目录不是 Git 仓库,跳过更新"
return 0
fi
if ! git diff --quiet || ! git diff --staged --quiet; then
print_warning "工作区有未提交变更,跳过 git pull"
return 0
fi
print_warning "拉取最新代码..."
git pull --rebase || print_error "git pull 失败,请手动处理"
}
# 验证安装
verify_installation() {
print_header "验证安装"
CHECKS=(
"node:Node.js"
"npm:npm"
"git:Git"
"openclaw:OpenClaw CLI"
"mcporter:McPorter"
"codex:Codex CLI"
"claude:Claude Code"
"gemini:Gemini CLI"
)
for check in "${CHECKS[@]}"; do
IFS=':' read -r cmd name <<< "$check"
if command_exists "$cmd"; then
version=$($cmd --version 2>/dev/null | head -n1 | tr -d '\n')
print_success "$name: $version"
else
print_error "$name: 未安装"
fi
done
print_success "安装验证完成"
}
# 主函数
main() {
parse_args "$@"
print_header "OpenClaw 一键初始化脚本"
echo ""
echo "项目名称: OpenClaw AI Assistant Environment"
echo "主人: 深圳刘家(虾宝宝 🦐)"
echo "仓库: https://github.com/YOUR_USERNAME/YOUR_REPO"
echo ""
# 切到 OpenClaw 根目录
if [ ! -d "$ROOT_DIR" ]; then
print_error "未找到 OpenClaw 根目录: $ROOT_DIR"
print_error "请确认此脚本位于 OpenClaw 仓库中"
exit 1
fi
cd "$ROOT_DIR"
# 检查是否在正确的目录
if [ ! -f "openclaw.json" ]; then
print_error "请在 OpenClaw 根目录运行此脚本"
print_error "请运行: cd $ROOT_DIR && ./workspace/skills/openclaw-toolbox/scripts/setup.sh"
exit 1
fi
check_prereqs
update_repo
if [ "$VERIFY_ONLY" -eq 1 ]; then
check_node_version || true
verify_installation
exit 0
fi
# 执行安装步骤
if [ "$SKIP_NODE" -eq 0 ]; then
if ! check_node_version; then
install_node
fi
else
print_warning "跳过 Node.js 安装"
fi
if [ "$SKIP_PACKAGES" -eq 0 ]; then
install_global_packages
else
print_warning "跳过全局 CLI 安装"
fi
if [ "$SKIP_ENV" -eq 0 ]; then
setup_environment
else
print_warning "跳过 .env 配置"
fi
if [ "$SKIP_MCP" -eq 0 ]; then
setup_mcp_servers
else
print_warning "跳过 MCP 配置"
fi
if [ "$SKIP_CLAUDE" -eq 0 ]; then
setup_claude_mcp
else
print_warning "跳过 Claude MCP 配置"
fi
if [ "$SKIP_VERIFY" -eq 0 ]; then
verify_installation
else
print_warning "跳过安装验证"
fi
print_header "初始化完成!"
echo ""
echo "🎉 OpenClaw 环境已成功初始化!"
echo ""
echo "下一步操作:"
echo "1. 编辑 .env 文件,填入你的 API Keys"
echo "2. 启动 OpenClaw: openclaw gateway start"
echo "3. 查看状态: openclaw status"
echo ""
echo "详细文档: $ROOT_DIR/workspace/skills/openclaw-setup/SETUP.md"
echo "🦐 虾宝宝为刘家服务"
echo ""
}
# 运行主函数
main "$@"

View File

@@ -0,0 +1,60 @@
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const SCRIPT_DIR = path.join(__dirname, '../scripts');
const ROOT_DIR = path.join(__dirname, '../../../../');
console.log(`ROOT_DIR: ${ROOT_DIR}`);
const testResults = {
total: 0,
passed: 0,
failed: []
};
function runTest(name, command) {
testResults.total++;
console.log(`\n▶️ Running Test: ${name}`);
try {
const output = execSync(command, {
encoding: 'utf8',
stdio: 'pipe',
cwd: ROOT_DIR // Run from project root
});
console.log(`✅ Passed: ${name}`);
testResults.passed++;
return true;
} catch (error) {
console.log(`❌ Failed: ${name}`);
console.log(`Error: ${error.message}`);
if (error.stdout) console.log(`Stdout: ${error.stdout}`);
if (error.stderr) console.log(`Stderr: ${error.stderr}`);
testResults.failed.push({ name, error: error.message });
return false;
}
}
console.log('🦐 OpenClaw Toolbox Sanity Tests');
console.log('=================================');
// Test 1: Backup Dry Run (Full)
runTest('Backup Full (Dry Run)', `bash ${path.join(SCRIPT_DIR, 'backup-now.sh')} --full --dry-run`);
// Test 2: Backup Dry Run (Skills)
runTest('Backup Skills (Dry Run)', `bash ${path.join(SCRIPT_DIR, 'backup-now.sh')} --skills --dry-run`);
// Test 3: Setup Verify Only
runTest('Setup Verification', `bash ${path.join(SCRIPT_DIR, 'setup.sh')} --verify-only`);
// Summary
console.log('\n=================================');
console.log(`📊 Test Summary: ${testResults.passed}/${testResults.total} passed`);
if (testResults.failed.length > 0) {
console.log('❌ Failures:');
testResults.failed.forEach(f => console.log(` - ${f.name}: ${f.error}`));
process.exit(1);
} else {
console.log('✅ All sanity tests passed!');
process.exit(0);
}