feat(hands): restructure Hands UI with Chinese localization
Major changes: - Add HandList.tsx component for left sidebar - Add HandTaskPanel.tsx for middle content area - Restructure Sidebar tabs: 分身/HANDS/Workflow - Remove Hands tab from RightPanel - Localize all UI text to Chinese - Archive legacy OpenClaw documentation - Add Hands integration lessons document - Update feature checklist with new components UI improvements: - Left sidebar now shows Hands list with status icons - Middle area shows selected Hand's tasks and results - Consistent styling with Tailwind CSS - Chinese status labels and buttons Documentation: - Create docs/archive/openclaw-legacy/ for old docs - Add docs/knowledge-base/hands-integration-lessons.md - Update docs/knowledge-base/feature-checklist.md - Update docs/knowledge-base/README.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
48
scripts/fix-openclaw-connection.sh
Normal file
48
scripts/fix-openclaw-connection.sh
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# OpenClaw Gateway 连接修复脚本
|
||||
# 用于解决 "device signature invalid" 错误
|
||||
|
||||
set -e
|
||||
|
||||
echo "=== OpenClaw Gateway 连接修复脚本 ==="
|
||||
echo ""
|
||||
|
||||
# 1. 停止 Gateway
|
||||
echo "步骤 1: 停止 Gateway..."
|
||||
openclaw gateway stop 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# 2. 清除设备密钥
|
||||
echo "步骤 2: 清除设备密钥..."
|
||||
rm -rf ~/.openclaw/device*.json 2>/dev/null || true
|
||||
rm -rf ~/.openclaw/.device* 2>/dev/null || true
|
||||
|
||||
# 3. 检查并修复配置
|
||||
echo "步骤 3: 检查配置..."
|
||||
if [ -f ~/.openclaw/openclaw.json ]; then
|
||||
echo "当前 Gateway 配置:"
|
||||
cat ~/.openclaw/openclaw.json | grep -A5 '"gateway"' | head -10
|
||||
fi
|
||||
|
||||
# 4. 重新运行 onboarding
|
||||
echo ""
|
||||
echo "步骤 4: 重新运行 onboarding..."
|
||||
echo "请运行: openclaw onboard"
|
||||
echo ""
|
||||
|
||||
# 5. 启动 Gateway
|
||||
echo "步骤 5: 启动 Gateway..."
|
||||
openclaw gateway start 2>&1
|
||||
|
||||
sleep 5
|
||||
|
||||
# 6. 检查状态
|
||||
echo ""
|
||||
echo "步骤 6: 检查状态..."
|
||||
openclaw status 2>&1 | head -20
|
||||
|
||||
echo ""
|
||||
echo "=== 修复完成 ==="
|
||||
echo "如果问题仍然存在,请尝试:"
|
||||
echo "1. 删除 ~/.openclaw 目录并重新运行 openclaw onboard"
|
||||
echo "2. 检查防火墙是否阻止了端口 18789"
|
||||
@@ -19,6 +19,14 @@ const OPENCLAW_HOME = process.env.OPENCLAW_HOME || path.join(
|
||||
|
||||
const ZCLAW_ROOT = path.resolve(__dirname, '..');
|
||||
|
||||
function uniqueStrings(values: string[]): string[] {
|
||||
return Array.from(new Set(values.filter(Boolean)));
|
||||
}
|
||||
|
||||
function resolveRepoPaths(values: string[] | undefined): string[] {
|
||||
return (values || []).map((p) => path.resolve(ZCLAW_ROOT, p));
|
||||
}
|
||||
|
||||
function log(msg: string) {
|
||||
console.log(`[ZCLAW Setup] ${msg}`);
|
||||
}
|
||||
@@ -50,35 +58,37 @@ function checkOpenClaw(): boolean {
|
||||
function setupConfig() {
|
||||
const configDir = OPENCLAW_HOME;
|
||||
const configFile = path.join(configDir, 'openclaw.json');
|
||||
const defaultConfigPath = path.join(ZCLAW_ROOT, 'config', 'openclaw.default.json');
|
||||
|
||||
// Create directory
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
|
||||
// Copy default config if no config exists
|
||||
if (!fs.existsSync(configFile)) {
|
||||
const defaultConfig = fs.readFileSync(
|
||||
path.join(ZCLAW_ROOT, 'config', 'openclaw.default.json'),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
// Update plugin paths to absolute paths
|
||||
const config = JSON.parse(defaultConfig);
|
||||
if (config.plugins?.load?.paths) {
|
||||
config.plugins.load.paths = config.plugins.load.paths.map((p: string) =>
|
||||
path.resolve(ZCLAW_ROOT, p)
|
||||
);
|
||||
}
|
||||
if (config.skills?.load?.extraDirs) {
|
||||
config.skills.load.extraDirs = config.skills.load.extraDirs.map((p: string) =>
|
||||
path.resolve(ZCLAW_ROOT, p)
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(configFile, JSON.stringify(config, null, 2), 'utf-8');
|
||||
success(`Config written to ${configFile}`);
|
||||
} else {
|
||||
log(`Config already exists at ${configFile}, skipping`);
|
||||
}
|
||||
const defaultConfig = JSON.parse(fs.readFileSync(defaultConfigPath, 'utf-8'));
|
||||
const config = fs.existsSync(configFile)
|
||||
? JSON.parse(fs.readFileSync(configFile, 'utf-8'))
|
||||
: defaultConfig;
|
||||
|
||||
const defaultPluginPaths = resolveRepoPaths(defaultConfig.plugins?.load?.paths);
|
||||
const existingPluginPaths = Array.isArray(config.plugins?.load?.paths)
|
||||
? config.plugins.load.paths
|
||||
: [];
|
||||
const mergedPluginPaths = uniqueStrings([...existingPluginPaths, ...defaultPluginPaths]);
|
||||
|
||||
const defaultSkillDirs = resolveRepoPaths(defaultConfig.skills?.load?.extraDirs);
|
||||
const existingSkillDirs = Array.isArray(config.skills?.load?.extraDirs)
|
||||
? config.skills.load.extraDirs
|
||||
: [];
|
||||
const mergedSkillDirs = uniqueStrings([...existingSkillDirs, ...defaultSkillDirs]);
|
||||
|
||||
config.plugins = config.plugins || {};
|
||||
config.plugins.load = config.plugins.load || {};
|
||||
config.plugins.load.paths = mergedPluginPaths;
|
||||
|
||||
config.skills = config.skills || {};
|
||||
config.skills.load = config.skills.load || {};
|
||||
config.skills.load.extraDirs = mergedSkillDirs;
|
||||
|
||||
fs.writeFileSync(configFile, JSON.stringify(config, null, 2), 'utf-8');
|
||||
success(fs.existsSync(configFile) ? `Config updated at ${configFile}` : `Config written to ${configFile}`);
|
||||
|
||||
// Copy bootstrap files
|
||||
const bootstrapFiles = ['SOUL.md', 'AGENTS.md', 'IDENTITY.md', 'USER.md'];
|
||||
|
||||
Reference in New Issue
Block a user