fix: chat scroll, add sidebar logo, WSL2 docs

- Fix chat panel not scrolling by adding overflow-hidden to ScrollArea
- Add 36x36 app logo next to "ClawPal" title in sidebar
- Add WSL2 SSH setup guide to README

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
zhixian
2026-02-19 16:00:40 +09:00
parent e7eb99380e
commit bed34f9d69
4 changed files with 78 additions and 25 deletions

View File

@@ -1,42 +1,91 @@
# ClawPal MVP (Tauri) # ClawPal
ClawPal is a local helper for OpenClaw configuration: A desktop companion app for [OpenClaw](https://github.com/openclaw/openclaw) — manage your AI agents, models, and configurations with a visual interface instead of editing JSON by hand.
- install scenarios via Recipes
- one-click rollback for every config change
- local doctor checks with basic auto-fixes
## Quick start ## Features
- **Recipes** — Browse and apply pre-built configuration templates with parameter forms, live diffs, and automatic rollback on failure
- **Agent Management** — Create, configure, and monitor your OpenClaw agents at a glance
- **Model Profiles** — Set up API keys, browse the model catalog, and switch the global default model in one click
- **Channel Bindings** — Connect Discord channels to agents with per-channel model overrides
- **Doctor** — Run diagnostics, auto-fix common issues, and clean up stale sessions
- **History & Rollback** — Every config change is snapshotted; roll back to any point in time
- **Remote Management** — Connect to remote OpenClaw instances over SSH and manage them the same way
- **Auto-Update** — ClawPal checks for new versions and updates itself in-app
## Install
Download the latest release for your platform from [GitHub Releases](https://github.com/zhixianio/clawpal/releases):
| Platform | Format |
|----------|--------|
| macOS (Apple Silicon) | `.dmg` |
| macOS (Intel) | `.dmg` |
| Windows | `.exe` installer or portable |
| Linux | `.deb` / `.AppImage` |
## Development
Prerequisites: [Node.js](https://nodejs.org/) 20+, [Rust](https://www.rust-lang.org/tools/install), and [Tauri CLI](https://v2.tauri.app/start/prerequisites/)
```bash ```bash
npm install npm install
npm run dev npm run dev # Vite dev server + Tauri window
``` ```
### Override folders outside `~/.openclaw` ### Build
You can place ClawPal-managed files outside `~/.openclaw` with env vars:
```bash
export CLAWPAL_OPENCLAW_DIR="$HOME/.openclaw" # OpenClaw 配置来源目录(默认)
export CLAWPAL_DATA_DIR="$HOME/.clawpal" # ClawPal 元数据目录(默认: $CLAWPAL_OPENCLAW_DIR/.clawpal
```
## Build
```bash ```bash
npm run build npm run build
cd src-tauri && cargo build cd src-tauri && cargo build
``` ```
## Release ### Release
```bash ```bash
npm run release:dry-run npm run release:dry-run # Preview version bump + tag
npm run release npm run release # Tag and push (triggers CI)
``` ```
### Environment overrides
```bash
export CLAWPAL_OPENCLAW_DIR="$HOME/.openclaw" # OpenClaw config directory (default)
export CLAWPAL_DATA_DIR="$HOME/.clawpal" # ClawPal metadata directory
```
## WSL2 (Windows Subsystem for Linux)
If you have OpenClaw installed inside WSL2, you can manage it from ClawPal using the built-in SSH Remote feature:
1. Enable SSH inside your WSL2 distro:
```bash
sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
```
2. In ClawPal, add a new SSH host:
- **Host**: `localhost`
- **Port**: the SSH port (default `22`, or check with `ss -tlnp | grep ssh`)
- **User**: your WSL2 username
3. Connect — ClawPal will manage the WSL2 OpenClaw instance the same as any remote server.
## Tech stack
- **Frontend** — React, TypeScript, Tailwind CSS, Radix UI
- **Backend** — Rust, Tauri 2
- **Remote** — russh (SSH/SFTP)
## Project layout ## Project layout
- `src/` React + TypeScript UI ```
- `src-tauri/` Rust + Tauri host and command APIs src/ React + TypeScript UI
- `docs/plans/` design and implementation plan src-tauri/ Rust + Tauri backend
docs/plans/ Design and implementation plans
```
## License
Proprietary. All rights reserved.

View File

@@ -7,6 +7,7 @@ import { Settings } from "./pages/Settings";
import { Doctor } from "./pages/Doctor"; import { Doctor } from "./pages/Doctor";
import { Channels } from "./pages/Channels"; import { Channels } from "./pages/Channels";
import { Chat } from "./components/Chat"; import { Chat } from "./components/Chat";
import logoUrl from "./assets/logo.png";
import { DiffViewer } from "./components/DiffViewer"; import { DiffViewer } from "./components/DiffViewer";
import { InstanceTabBar } from "./components/InstanceTabBar"; import { InstanceTabBar } from "./components/InstanceTabBar";
import { InstanceContext } from "./lib/instance-context"; import { InstanceContext } from "./lib/instance-context";
@@ -218,7 +219,10 @@ export function App() {
/> />
<div className="flex flex-1 overflow-hidden"> <div className="flex flex-1 overflow-hidden">
<aside className="w-[200px] min-w-[200px] bg-muted border-r border-border flex flex-col py-4"> <aside className="w-[200px] min-w-[200px] bg-muted border-r border-border flex flex-col py-4">
<h1 className="px-4 text-lg font-bold mb-4">ClawPal</h1> <h1 className="px-4 text-lg font-bold mb-4 flex items-center gap-2">
<img src={logoUrl} alt="" className="w-9 h-9 rounded-lg" />
ClawPal
</h1>
<nav className="flex flex-col gap-1 px-2 flex-1"> <nav className="flex flex-col gap-1 px-2 flex-1">
<Button <Button
variant="ghost" variant="ghost"

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -126,7 +126,7 @@ export function Chat() {
New New
</Button> </Button>
</div> </div>
<ScrollArea className="flex-1 mb-2"> <ScrollArea className="flex-1 mb-2 overflow-hidden">
{messages.map((msg, i) => ( {messages.map((msg, i) => (
<div key={i} className={cn("mb-2", msg.role === "user" ? "text-right" : "text-left")}> <div key={i} className={cn("mb-2", msg.role === "user" ? "text-right" : "text-left")}>
<div className={cn( <div className={cn(