Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/alex1987chn_xpouch-vault.json
T

1 line
125 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "alex1987chn/xpouch-vault", "files": {"README.md": {"0c0984b9ac11416746947894a0dd58e5789d5414": {"t": 1785746397.8837652, "n": 10446, "h": "d917448fa3c7a3c7", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n[**中文文档**](./README_zh.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n<img src=\"https://github.com/user-attachments/assets/21eb77a8-c6f0-4270-b054-7d6558c46e4c\" alt=\"XPouch Vault - Key Vault\" width=\"900\">\n<img src=\"https://github.com/user-attachments/assets/fc80092f-1a80-4c32-a799-369902519460\" alt=\"XPouch Vault - Lobster Monitor\" width=\"900\">\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 20+\n- [pnpm](https://pnpm.io/) 9+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n### Installation Notes\n\nThis app is **not code-signed** (no paid certificate). You may encounter OS warnings on first launch:\n\n- **Windows**: SmartScreen may show \"Windows protected your PC\" — click **More info** → **Run anyway**\n- **macOS**: You may see \"cannot be opened because it is from an unidentified developer\" — **right-click** the app → **Open**, or go to **System Settings → Privacy & Security → Open Anyway**\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "cc95a226becdfb25b5cc6924e904e28ca56d4e0b": {"t": 1785763297.197132, "n": 10446, "h": "d917448fa3c7a3c7", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n[**中文文档**](./README_zh.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n<img src=\"https://github.com/user-attachments/assets/21eb77a8-c6f0-4270-b054-7d6558c46e4c\" alt=\"XPouch Vault - Key Vault\" width=\"900\">\n<img src=\"https://github.com/user-attachments/assets/fc80092f-1a80-4c32-a799-369902519460\" alt=\"XPouch Vault - Lobster Monitor\" width=\"900\">\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 20+\n- [pnpm](https://pnpm.io/) 9+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n### Installation Notes\n\nThis app is **not code-signed** (no paid certificate). You may encounter OS warnings on first launch:\n\n- **Windows**: SmartScreen may show \"Windows protected your PC\" — click **More info** → **Run anyway**\n- **macOS**: You may see \"cannot be opened because it is from an unidentified developer\" — **right-click** the app → **Open**, or go to **System Settings → Privacy & Security → Open Anyway**\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "1bd11f09df5c253dd5771ec17ba5858fa28874c5": {"t": 1785763319.9852757, "n": 10169, "h": "09819a45b68b5050", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n[**中文文档**](./README_zh.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n### Installation Notes\n\nThis app is **not code-signed** (no paid certificate). You may encounter OS warnings on first launch:\n\n- **Windows**: SmartScreen may show \"Windows protected your PC\" — click **More info** → **Run anyway**\n- **macOS**: You may see \"cannot be opened because it is from an unidentified developer\" — **right-click** the app → **Open**, or go to **System Settings → Privacy & Security → Open Anyway**\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "8d6c4510ecff83bf6c72b69994d53b256f25e096": {"t": 1785763322.4710648, "n": 10141, "h": "fd35fdd788d0d533", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n### Installation Notes\n\nThis app is **not code-signed** (no paid certificate). You may encounter OS warnings on first launch:\n\n- **Windows**: SmartScreen may show \"Windows protected your PC\" — click **More info** → **Run anyway**\n- **macOS**: You may see \"cannot be opened because it is from an unidentified developer\" — **right-click** the app → **Open**, or go to **System Settings → Privacy & Security → Open Anyway**\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "53081027361d21622149bddd845a75805a736546": {"t": 1785763324.1615684, "n": 9784, "h": "a36c754bd52b21e2", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n### Installation Notes\n\nThis app is **not code-signed** (no paid certificate). You may encounter OS warnings on first launch:\n\n- **Windows**: SmartScreen may show \"Windows protected your PC\" — click **More info** → **Run anyway**\n- **macOS**: You may see \"cannot be opened because it is from an unidentified developer\" — **right-click** the app → **Open**, or go to **System Settings → Privacy & Security → Open Anyway**\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "101e0aa37e4cedf4e40f886d964525fa9677fa01": {"t": 1785763326.8125405, "n": 9362, "h": "1ecd74f1cb5bab78", "c": "# XPouch Vault\n\nA secure, elegant desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n> **Design Philosophy** — Inspired by Claude's warm, minimal aesthetic: stone whites, tawny orange accents, generous spacing, and subtle shadows.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **9 AI Providers** — OpenAI, Anthropic, Google AI, DeepSeek, MiniMax, Kimi, Qwen, Doubao, GLM + custom\n- **Brand Icons** — Authentic provider logos via `@lobehub/icons`\n- **Health Ping** — Async key validation via Rust backend; results persisted to database\n- **Validity Badge** — Cards show Valid / Invalid / Untested based on real ping results\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **i18n** — Trilingual support: Chinese, English, Japanese\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Full details: channels (running/error), agents (model/sessions), cron jobs, online devices\n\n### Shared\n\n- **Local-First** — All data stored in local SQLite (WAL mode); no cloud sync, no telemetry\n- **Claude-Inspired UI** — Warm stone whites, tawny orange accent, generous spacing, subtle shadows\n- **CSS Custom Properties** — Theming via `--accent`, `--bg-base`, `--text-primary`, etc.\n- **Component Library** — Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form, Toast, StatCard\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Icons | @lobehub/icons (brand) + Lucide (UI) |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| i18n | Custom (zh/en/ja) |\n| Build | Vite 8 + pnpm |\n| CI | GitHub Actions (Windows + macOS) |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`:\n\n| Platform | Output Formats |\n|----------|---------------|\n| Windows | `.msi`, `.exe` (NSIS) |\n| macOS | `.dmg`, `.app` |\n| Linux | `.deb`, `.AppImage` |\n\n> **Note:** You must build on the target platform. Use GitHub Actions CI for cross-platform releases.\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── NodeDetailPanel.tsx # Node detail sidebar\n│ │ ├── VaultLogo.tsx # Animated vault door logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja switcher\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # Route pages\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider, PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── i18n/ # Internationalization\n│ │ ├── index.ts # useI18n hook\n│ │ └── translations.ts # zh/en/ja translation table\n│ ├── utils/ # Utility functions\n│ │ └── format.ts # formatDateTime, formatUptime\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ ├── lib.rs # Module registration + setup\n│ │ └── main.rs # Entry point\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI: cross-platform build + release\n└── package.json\n```\n\n## Design System\n\n### Color Tokens (CSS Custom Properties)\n\n```css\n--bg-base: #faf9f7; /* stone-50 warm white */\n--bg-surface: #ffffff; /* pure white cards */\n--bg-muted: #f5f4f0; /* stone-100 subtle bg */\n--border-default: #e7e5e0; /* stone-200 */\n--text-primary: #1c1917; /* stone-900 */\n--text-secondary: #57534e; /* stone-600 */\n--text-tertiary: #a8a29e; /* stone-400 */\n--accent: #c96442; /* tawny orange */\n--accent-light: #fef3ee; /* accent bg tint */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### Provider Ping Endpoints\n\n| Provider | Method | Endpoint | Auth |\n|----------|--------|----------|------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query param |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}` (min chat) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}` (min chat) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **Note:** Some providers (MiniMax, Doubao) don't support the standard `/v1/models` endpoint. For these, the ping sends a minimal `POST /chat/completions` request with `max_tokens: 1` — any non-401/403 response means the key is authenticated. This consumes at most 1 token per ping.\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → DB + Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- Database file is stored in the Tauri app data directory\n\n## Releasing\n\nPush a version tag to trigger automatic cross-platform builds:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions will build Windows (.msi/.exe) and macOS (.dmg) installers and create a Release with download links.\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart: `openclaw gateway restart`\n\n## License\n\nMIT\n"}, "0c398b4e9218c1e43d58046bd02a666277b432a0": {"t": 1785763332.1624205, "n": 6829, "h": "fe71f1cb985fa131", "c": "# XPouch Vault\n\nA secure desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Health Ping** — Async key validation via Rust backend (supports OpenAI, Anthropic, Google AI, DeepSeek)\n- **Multi-Provider** — Supports OpenAI, Anthropic, Google AI, DeepSeek, and custom providers\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Rename Keys** — Inline edit dialog to rename keys without re-creating\n- **Masked Display** — Keys are shown as masked strings (e.g., `sk-...7xYz`) in the UI\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, agents, cron jobs, presence, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Select a node card to see full details in a wide sidebar (channels with running/error status, agent list with model/sessions, cron jobs with schedule, online devices)\n\n### Shared\n\n- **Local-First** — All data stored in a local SQLite database (WAL mode); no cloud sync, no telemetry\n- **Dark Theme** — Built-in dark UI optimized for developers\n- **Component Library** — Reusable UI primitives: Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| Build | Vite 8 + pnpm |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`.\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/edit/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ └── Form.tsx # Input + Select\n│ ├── pages/ # Route pages (lazy loaded)\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter + lazy loading)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ └── lib.rs # Module registration + setup\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n└── package.json\n```\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- WS handshake requires `Origin` header for CORS validation\n- Database file is stored in the Tauri app data directory\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, you must configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`** — Add/modify the config file:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart the gateway:\n\n```bash\nopenclaw gateway restart\n```\n\n> Without this change, the gateway only accepts connections from localhost/LAN, and XPouch Vault will show the node as offline.\n\n## OpenClaw WebSocket Protocol\n\n```\n1. Connect: ws://<IP>:<PORT>/<shareCode>/ws (with Origin header)\n2. Receive: connect.challenge event\n3. Send: connect request (client.id: \"openclaw-control-ui\", client.mode: \"ui\")\n4. Receive: hello-ok (with snapshot.uptimeMs)\n5. Send: health request → channels (with running/configured/error), agents (name/model/sessions), sessions, skills, tokens, nodes\n6. Send: cron.list request → cron jobs (name/schedule/enabled/nextRun)\n7. Send: status request → runtimeVersion, heartbeat, tasks\n8. Responses matched by request ID (skip interleaved event pushes)\n```\n\n## License\n\nMIT\n"}, "cd3e72b02b135482ab17d564a88bb30d1170bcc6": {"t": 1785763333.8527198, "n": 6475, "h": "b6bf898a4c29c305", "c": "# XPouch Vault\n\nA secure desktop vault for managing AI API keys and monitoring OpenClaw gateway nodes. Built with Tauri 2.x, React 19, and Rust.\n\n## Features\n\n### Vault — API Key Management\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **Key Reveal & Copy** — Toggle masked/plaintext display; copy to clipboard with one click\n- **Health Ping** — Async key validation via Rust backend (supports OpenAI, Anthropic, Google AI, DeepSeek)\n- **Multi-Provider** — Supports OpenAI, Anthropic, Google AI, DeepSeek, and custom providers\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys are shown as masked strings (e.g., `sk-...7xYz`) in the UI\n\n### Lobster — OpenClaw Gateway Monitoring\n\n- **WebSocket Real-time Monitoring** — Connects to OpenClaw gateways via WS protocol (health + status methods)\n- **Node CRUD** — Add, edit, delete gateway nodes with encrypted token storage\n- **Dashboard** — Online/offline status, gateway version, uptime, channels, sessions, skills, tasks, heartbeat\n- **Auto Refresh** — 30-second interval auto-refresh for all node statuses\n- **Detail Sidebar** — Select a node card to see full details in the sidebar\n\n### Shared\n\n- **Local-First** — All data stored in a local SQLite database (WAL mode); no cloud sync, no telemetry\n- **Dark Theme** — Built-in dark UI optimized for developers\n- **Component Library** — Reusable UI primitives: Dialog, ConfirmDialog, EmptyState, PageHeader, ActionButton, Form\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| HTTP Client | reqwest 0.12 (async, for health ping) |\n| WebSocket | tokio-tungstenite 0.26 (async, for OpenClaw monitoring) |\n| Build | Vite 8 + pnpm |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\npnpm install\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`.\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # Business components\n│ │ ├── KeyCard.tsx # Key card (copy/reveal/ping/delete)\n│ │ ├── AddKeyDialog.tsx # Add key dialog\n│ │ ├── NodeCard.tsx # Node card (online status/channels/tasks)\n│ │ ├── AddNodeDialog.tsx # Add/edit node dialog\n│ │ ├── Toast.tsx # Global toast notifications\n│ │ └── ui/ # Reusable UI primitives\n│ │ ├── Dialog.tsx # Modal shell\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ └── Form.tsx # Input + Select\n│ ├── pages/ # Route pages (lazy loaded)\n│ │ ├── VaultPage.tsx # Vault (home)\n│ │ └── LobsterPage.tsx # Lobster monitoring\n│ ├── store/ # Zustand stores\n│ │ ├── vaultStore.ts # Vault state + actions\n│ │ ├── nodeStore.ts # Node monitoring state + actions\n│ │ └── toastStore.ts # Toast state\n│ ├── types/ # TypeScript type definitions\n│ │ ├── vault.ts # VaultEntry, KeyProvider\n│ │ └── node.ts # OpenClawNode, NodeStatus, ChannelInfo, TasksInfo\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter + lazy loading)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (Vault CRUD + ping + Node CRUD + WS probe)\n│ │ ├── node.rs # Node data model + CRUD + decrypt token\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + vault queries\n│ │ └── lib.rs # Module registration + setup\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n└── package.json\n```\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n\n[Health Ping] → Rust decrypts key → reqwest async HTTP → result → Toast\n[WS Probe] → Rust decrypts token → tokio-tungstenite WS → status → UI\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- All external HTTP/WS requests are made from Rust, keys/tokens never pass through the frontend network stack\n- WS handshake requires `Origin` header for CORS validation\n- Database file is stored in the Tauri app data directory\n\n## OpenClaw Gateway Prerequisites\n\nBy default, OpenClaw gateway binds to `localhost` (LAN mode) and rejects external client connections. To allow XPouch Vault to connect from another machine, you must configure the gateway to listen on `0.0.0.0`:\n\n**Option 1: Via OpenClaw UI** — Settings → Gateway:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**Option 2: Via `openclaw.json`** — Add/modify the config file:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\nThen restart the gateway:\n\n```bash\nopenclaw gateway restart\n```\n\n> Without this change, the gateway only accepts connections from localhost/LAN, and XPouch Vault will show the node as offline.\n\n## OpenClaw WebSocket Protocol\n\n```\n1. Connect: ws://<IP>:<PORT>/<shareCode>/ws (with Origin header)\n2. Receive: connect.challenge event\n3. Send: connect request (client.id: \"openclaw-control-ui\", client.mode: \"ui\")\n4. Receive: hello-ok (with snapshot.uptimeMs)\n5. Send: health request → channels, sessions, skills, tokens, nodes\n6. Send: status request → runtimeVersion, heartbeat, tasks\n7. Responses matched by request ID (skip interleaved event pushes)\n```\n\n## License\n\nMIT\n"}, "e2d0a8e7e836e2cc2b8476d275b87ba5d7fbec64": {"t": 1785763336.21938, "n": 2888, "h": "8ea918c4c7bdc918", "c": "# XPouch Vault\n\nA secure desktop vault for managing AI API keys. Built with Tauri 2.x, React 19, and Rust.\n\n## Features\n\n- **AES-256-GCM Encryption** — API keys are encrypted at rest with field-level encryption; keys never touch the frontend in plaintext\n- **Local-First** — All data stored in a local SQLite database (WAL mode); no cloud sync, no telemetry\n- **Multi-Provider** — Supports OpenAI, Anthropic, Google AI, DeepSeek, and custom providers\n- **Categorized Management** — Organize keys by environment (production, dev/test, personal, backup)\n- **Masked Display** — Keys are shown as masked strings (e.g., `sk-...7xYz`) in the UI\n- **Dark Theme** — Built-in dark UI optimized for developers\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| Desktop Runtime | Tauri 2.x |\n| Frontend | React 19 + TypeScript + TailwindCSS v4 |\n| State Management | Zustand 5 |\n| Backend | Rust (native Tauri commands) |\n| Database | SQLite (via rusqlite, bundled) |\n| Encryption | AES-256-GCM (field-level) |\n| Build | Vite 8 + pnpm |\n\n## Getting Started\n\n### Prerequisites\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install) (stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### Install Dependencies\n\n```bash\n# Frontend\npnpm install\n\n# Rust (handled automatically by Tauri)\n```\n\n### Development\n\n```bash\npnpm tauri dev\n```\n\nThis starts the Vite dev server on `http://localhost:1420` and launches the Tauri window.\n\n### Build\n\n```bash\npnpm tauri build\n```\n\nProduces platform-specific installers in `src-tauri/target/release/bundle/`.\n\n## Project Structure\n\n```\nxpouch-vault/\n├── src/ # Frontend (React + TypeScript)\n│ ├── components/ # UI components\n│ ├── pages/ # Route pages\n│ ├── store/ # Zustand stores\n│ ├── types/ # TypeScript type definitions\n│ ├── App.tsx # Root layout + sidebar\n│ └── main.tsx # Entry point (HashRouter + lazy loading)\n├── src-tauri/ # Backend (Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri commands (CRUD API)\n│ │ ├── crypto.rs # AES-256-GCM encrypt/decrypt\n│ │ ├── db.rs # SQLite schema + queries\n│ │ └── lib.rs # Module registration + setup\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n└── package.json\n```\n\n## Security Architecture\n\n```\n[User Input] → Frontend (plaintext in memory only)\n ↓\n[Tauri Command] → Rust backend\n ↓\n[AES-256-GCM Encrypt] → nonce + ciphertext → base64 → SQLite\n```\n\n- Encryption key is derived from machine characteristics (hostname + username) as an interim solution\n- **TODO**: Integrate OS Keychain (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)\n- Database file is stored in the Tauri app data directory\n\n## License\n\nMIT\n"}, "9f84ec64b972446990aabbd685021024ae98a83c": {"t": 1785763341.7842634, "n": 378, "h": "6e3169b612055eb4", "c": "# Tauri + React + Typescript\n\nThis template should help get you started developing with Tauri, React and Typescript in Vite.\n\n## Recommended IDE Setup\n\n- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)\n"}}, "README_zh.md": {"0c0984b9ac11416746947894a0dd58e5789d5414": {"t": 1785746398.2000842, "n": 7531, "h": "129283cac55e24ad", "c": "# XPouch Vault\n\n安全、优雅的桌面密钥保险箱,管理 AI API Key 并监控 OpenClaw 节点。基于 Tauri 2.x、React 19 和 Rust 构建。\n\n[**English**](./README.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n<img src=\"https://github.com/user-attachments/assets/21eb77a8-c6f0-4270-b054-7d6558c46e4c\" alt=\"XPouch Vault - 密钥库\" width=\"900\">\n<img src=\"https://github.com/user-attachments/assets/fc80092f-1a80-4c32-a799-369902519460\" alt=\"XPouch Vault - 龙虾监控\" width=\"900\">\n\n> **设计理念** — 源自 Claude 的温暖极简美学:石白底色、赤陶橙点缀、留白呼吸感、细腻阴影。\n\n## 功能特性\n\n### 保险箱 — API Key 管理\n\n- **AES-256-GCM 加密** — API Key 字段级加密存储,密钥永不经过前端明文\n- **9 家 AI 服务商** — OpenAI、Anthropic、Google AI、DeepSeek、MiniMax、Kimi、Qwen、Doubao、GLM + 自定义\n- **品牌图标** — 通过 `@lobehub/icons` 展示服务商真实 Logo\n- **连通性测试** — Rust 后端异步验证 Key 有效性,结果持久化到数据库\n- **状态徽章** — 卡片显示 有效 / 失效 / 未测试 三种状态\n- **显示与复制** — 一键切换脱敏/明文显示,一键复制到剪贴板\n- **重命名** — 内联编辑弹窗,无需重建即可修改名称\n- **分类管理** — 按环境分类:生产环境、开发测试、个人项目、备用\n- **脱敏展示** — Key 以脱敏形式展示(如 `sk-...7xYz`)\n- **多语言** — 支持中文、英文、日文\n\n### 龙虾 — OpenClaw 节点监控\n\n- **WebSocket 实时监控** — 通过 WS 协议连接 OpenClaw(health + status 方法)\n- **节点增删改** — 添加、编辑、删除网关节点,Token 加密存储\n- **仪表盘** — 在线/离线状态、版本、运行时间、渠道、Agent、定时任务、在线设备、会话、技能、任务、心跳\n- **自动刷新** — 30 秒间隔自动刷新所有节点状态\n- **详情面板** — 完整信息:渠道(运行/错误)、Agent(模型/会话)、定时任务、在线设备\n\n### 通用\n\n- **本地优先** — 所有数据存储在本地 SQLite(WAL 模式),无云同步、无遥测\n- **Claude 风格 UI** — 温暖石白、赤陶橙点缀、留白呼吸感、细腻阴影\n- **CSS 变量主题** — 通过 `--accent`、`--bg-base`、`--text-primary` 等控制主题\n- **组件库** — Dialog、ConfirmDialog、EmptyState、PageHeader、ActionButton、Form、Toast、StatCard\n\n## 技术栈\n\n| 层级 | 技术 |\n|------|------|\n| 桌面运行时 | Tauri 2.x |\n| 前端 | React 19 + TypeScript + TailwindCSS v4 |\n| 状态管理 | Zustand 5 |\n| 图标 | @lobehub/icons(品牌)+ Lucide(UI) |\n| 后端 | Rust(Tauri 原生命令) |\n| 数据库 | SQLite(rusqlite,内嵌) |\n| 加密 | AES-256-GCM(字段级) |\n| HTTP 客户端 | reqwest 0.12(异步,用于连通性测试) |\n| WebSocket | tokio-tungstenite 0.26(异步,用于 OpenClaw 监控) |\n| 国际化 | 自研(zh/en/ja) |\n| 构建 | Vite 8 + pnpm |\n| CI | GitHub Actions(Windows + macOS) |\n\n## 快速开始\n\n### 环境要求\n\n- [Node.js](https://nodejs.org/) 20+\n- [pnpm](https://pnpm.io/) 9+\n- [Rust](https://www.rust-lang.org/tools/install)(stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 开发\n\n```bash\npnpm tauri dev\n```\n\n启动 Vite 开发服务器(`http://localhost:1420`)并打开 Tauri 窗口。\n\n### 构建\n\n```bash\npnpm tauri build\n```\n\n在 `src-tauri/target/release/bundle/` 生成平台安装包:\n\n| 平台 | 输出格式 |\n|------|---------|\n| Windows | `.msi`、`.exe`(NSIS) |\n| macOS | `.dmg`、`.app` |\n| Linux | `.deb`、`.AppImage` |\n\n> **注意:** 需在目标平台上构建。跨平台发布请使用 GitHub Actions CI。\n\n### 安装须知\n\n本应用**未做代码签名**(无付费证书),首次启动可能会遇到系统警告:\n\n- **Windows**:SmartScreen 可能提示\"Windows 已保护你的电脑\" — 点击**更多信息** → **仍要运行**\n- **macOS**:可能提示\"无法验证开发者\" — **右键点击**应用 → **打开**,或前往**系统设置 → 隐私与安全性 → 仍要打开**\n\n## 项目结构\n\n```\nxpouch-vault/\n├── src/ # 前端(React + TypeScript)\n│ ├── components/ # 业务组件\n│ │ ├── KeyCard.tsx # Key 卡片(复制/显示/测试/编辑/删除)\n│ │ ├── AddKeyDialog.tsx # 添加 Key 弹窗\n│ │ ├── NodeCard.tsx # 节点卡片(在线状态/渠道/任务)\n│ │ ├── AddNodeDialog.tsx # 添加/编辑节点弹窗\n│ │ ├── NodeDetailPanel.tsx # 节点详情面板\n│ │ ├── VaultLogo.tsx # 动画金库门 Logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja 切换器\n│ │ ├── Toast.tsx # 全局 Toast 通知\n│ │ └── ui/ # 可复用 UI 原子组件\n│ │ ├── Dialog.tsx # 弹窗壳\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # 路由页面\n│ │ ├── VaultPage.tsx # 保险箱(首页)\n│ │ └── LobsterPage.tsx # 龙虾监控\n│ ├── store/ # Zustand 状态\n│ │ ├── vaultStore.ts # 保险箱状态 + 操作\n│ │ ├── nodeStore.ts # 节点监控状态 + 操作\n│ │ └── toastStore.ts # Toast 状态\n│ ├── types/ # TypeScript 类型定义\n│ │ ├── vault.ts # VaultEntry、KeyProvider、PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode、NodeStatus、ChannelInfo、TasksInfo\n│ ├── i18n/ # 国际化\n│ │ ├── index.ts # useI18n Hook\n│ │ └── translations.ts # zh/en/ja 翻译表\n│ ├── utils/ # 工具函数\n│ │ └── format.ts # formatDateTime、formatUptime\n│ ├── App.tsx # 根布局 + 侧边栏\n│ └── main.tsx # 入口(HashRouter)\n├── src-tauri/ # 后端(Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri 命令(保险箱 CRUD + 测试 + 节点 CRUD + WS 探测)\n│ │ ├── node.rs # 节点数据模型 + CRUD + 解密 Token\n│ │ ├── crypto.rs # AES-256-GCM 加密/解密\n│ │ ├── db.rs # SQLite Schema + 保险箱查询\n│ │ ├── lib.rs # 模块注册 + 初始化\n│ │ └── main.rs # 入口\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI:跨平台构建 + 发布\n└── package.json\n```\n\n## 设计系统\n\n### 色彩变量(CSS 自定义属性)\n\n```css\n--bg-base: #faf9f7; /* 石白暖底 */\n--bg-surface: #ffffff; /* 纯白卡片 */\n--bg-muted: #f5f4f0; /* 石色微底 */\n--border-default: #e7e5e0; /* 石色边框 */\n--text-primary: #1c1917; /* 主文字 */\n--text-secondary: #57534e; /* 次文字 */\n--text-tertiary: #a8a29e; /* 辅助文字 */\n--accent: #c96442; /* 赤陶橙 */\n--accent-light: #fef3ee; /* 橙色淡底 */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### 服务商连通性测试端点\n\n| 服务商 | 方法 | 端点 | 认证方式 |\n|--------|------|------|----------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query 参数 |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}`(最小对话) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}`(最小对话) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **注意:** 部分服务商(MiniMax、Doubao)不支持标准 `/v1/models` 端点,连通性测试会发送最小化的 `POST /chat/completions` 请求(`max_tokens: 1`),非 401/403 响应即视为认证通过,每次测试最多消耗 1 token。\n\n## 安全架构\n\n```\n[用户输入] → 前端(仅内存中明文)\n ↓\n[Tauri 命令] → Rust 后端\n ↓\n[AES-256-GCM 加密] → nonce + 密文 → base64 → SQLite\n\n[连通性测试] → Rust 解密 Key → reqwest 异步 HTTP → 结果 → DB + Toast\n[WS 探测] → Rust 解密 Token → tokio-tungstenite WS → 状态 → UI\n```\n\n- 加密密钥暂由机器特征(主机名 + 用户名)派生\n- **计划**:集成操作系统 Keychain(macOS Keychain、Windows Credential Manager、Linux Secret Service)\n- 所有外部 HTTP/WS 请求均在 Rust 侧完成,Key/Token 不经过前端网络栈\n- 数据库文件存储在 Tauri 应用数据目录\n\n## 发布\n\n推送版本标签触发自动跨平台构建:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions 会构建 Windows(.msi/.exe)和 macOS(.dmg)安装包,并创建 Release 下载链接。\n\n## OpenClaw 接入前提\n\n默认情况下,OpenClaw 绑定 `localhost`(LAN 模式),拒绝外部客户端连接。要让 XPouch Vault 从其他机器连接,需将监听地址配置为 `0.0.0.0`:\n\n**方式一:通过 OpenClaw 界面** — 设置 → 网关:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**方式二:通过 `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n然后重启:`openclaw gateway restart`\n\n## 许可证\n\n[MIT](./LICENSE)\n"}, "cc95a226becdfb25b5cc6924e904e28ca56d4e0b": {"t": 1785763292.3538458, "n": 7531, "h": "129283cac55e24ad", "c": "# XPouch Vault\n\n安全、优雅的桌面密钥保险箱,管理 AI API Key 并监控 OpenClaw 节点。基于 Tauri 2.x、React 19 和 Rust 构建。\n\n[**English**](./README.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n<img src=\"https://github.com/user-attachments/assets/21eb77a8-c6f0-4270-b054-7d6558c46e4c\" alt=\"XPouch Vault - 密钥库\" width=\"900\">\n<img src=\"https://github.com/user-attachments/assets/fc80092f-1a80-4c32-a799-369902519460\" alt=\"XPouch Vault - 龙虾监控\" width=\"900\">\n\n> **设计理念** — 源自 Claude 的温暖极简美学:石白底色、赤陶橙点缀、留白呼吸感、细腻阴影。\n\n## 功能特性\n\n### 保险箱 — API Key 管理\n\n- **AES-256-GCM 加密** — API Key 字段级加密存储,密钥永不经过前端明文\n- **9 家 AI 服务商** — OpenAI、Anthropic、Google AI、DeepSeek、MiniMax、Kimi、Qwen、Doubao、GLM + 自定义\n- **品牌图标** — 通过 `@lobehub/icons` 展示服务商真实 Logo\n- **连通性测试** — Rust 后端异步验证 Key 有效性,结果持久化到数据库\n- **状态徽章** — 卡片显示 有效 / 失效 / 未测试 三种状态\n- **显示与复制** — 一键切换脱敏/明文显示,一键复制到剪贴板\n- **重命名** — 内联编辑弹窗,无需重建即可修改名称\n- **分类管理** — 按环境分类:生产环境、开发测试、个人项目、备用\n- **脱敏展示** — Key 以脱敏形式展示(如 `sk-...7xYz`)\n- **多语言** — 支持中文、英文、日文\n\n### 龙虾 — OpenClaw 节点监控\n\n- **WebSocket 实时监控** — 通过 WS 协议连接 OpenClaw(health + status 方法)\n- **节点增删改** — 添加、编辑、删除网关节点,Token 加密存储\n- **仪表盘** — 在线/离线状态、版本、运行时间、渠道、Agent、定时任务、在线设备、会话、技能、任务、心跳\n- **自动刷新** — 30 秒间隔自动刷新所有节点状态\n- **详情面板** — 完整信息:渠道(运行/错误)、Agent(模型/会话)、定时任务、在线设备\n\n### 通用\n\n- **本地优先** — 所有数据存储在本地 SQLite(WAL 模式),无云同步、无遥测\n- **Claude 风格 UI** — 温暖石白、赤陶橙点缀、留白呼吸感、细腻阴影\n- **CSS 变量主题** — 通过 `--accent`、`--bg-base`、`--text-primary` 等控制主题\n- **组件库** — Dialog、ConfirmDialog、EmptyState、PageHeader、ActionButton、Form、Toast、StatCard\n\n## 技术栈\n\n| 层级 | 技术 |\n|------|------|\n| 桌面运行时 | Tauri 2.x |\n| 前端 | React 19 + TypeScript + TailwindCSS v4 |\n| 状态管理 | Zustand 5 |\n| 图标 | @lobehub/icons(品牌)+ Lucide(UI) |\n| 后端 | Rust(Tauri 原生命令) |\n| 数据库 | SQLite(rusqlite,内嵌) |\n| 加密 | AES-256-GCM(字段级) |\n| HTTP 客户端 | reqwest 0.12(异步,用于连通性测试) |\n| WebSocket | tokio-tungstenite 0.26(异步,用于 OpenClaw 监控) |\n| 国际化 | 自研(zh/en/ja) |\n| 构建 | Vite 8 + pnpm |\n| CI | GitHub Actions(Windows + macOS) |\n\n## 快速开始\n\n### 环境要求\n\n- [Node.js](https://nodejs.org/) 20+\n- [pnpm](https://pnpm.io/) 9+\n- [Rust](https://www.rust-lang.org/tools/install)(stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 开发\n\n```bash\npnpm tauri dev\n```\n\n启动 Vite 开发服务器(`http://localhost:1420`)并打开 Tauri 窗口。\n\n### 构建\n\n```bash\npnpm tauri build\n```\n\n在 `src-tauri/target/release/bundle/` 生成平台安装包:\n\n| 平台 | 输出格式 |\n|------|---------|\n| Windows | `.msi`、`.exe`(NSIS) |\n| macOS | `.dmg`、`.app` |\n| Linux | `.deb`、`.AppImage` |\n\n> **注意:** 需在目标平台上构建。跨平台发布请使用 GitHub Actions CI。\n\n### 安装须知\n\n本应用**未做代码签名**(无付费证书),首次启动可能会遇到系统警告:\n\n- **Windows**:SmartScreen 可能提示\"Windows 已保护你的电脑\" — 点击**更多信息** → **仍要运行**\n- **macOS**:可能提示\"无法验证开发者\" — **右键点击**应用 → **打开**,或前往**系统设置 → 隐私与安全性 → 仍要打开**\n\n## 项目结构\n\n```\nxpouch-vault/\n├── src/ # 前端(React + TypeScript)\n│ ├── components/ # 业务组件\n│ │ ├── KeyCard.tsx # Key 卡片(复制/显示/测试/编辑/删除)\n│ │ ├── AddKeyDialog.tsx # 添加 Key 弹窗\n│ │ ├── NodeCard.tsx # 节点卡片(在线状态/渠道/任务)\n│ │ ├── AddNodeDialog.tsx # 添加/编辑节点弹窗\n│ │ ├── NodeDetailPanel.tsx # 节点详情面板\n│ │ ├── VaultLogo.tsx # 动画金库门 Logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja 切换器\n│ │ ├── Toast.tsx # 全局 Toast 通知\n│ │ └── ui/ # 可复用 UI 原子组件\n│ │ ├── Dialog.tsx # 弹窗壳\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # 路由页面\n│ │ ├── VaultPage.tsx # 保险箱(首页)\n│ │ └── LobsterPage.tsx # 龙虾监控\n│ ├── store/ # Zustand 状态\n│ │ ├── vaultStore.ts # 保险箱状态 + 操作\n│ │ ├── nodeStore.ts # 节点监控状态 + 操作\n│ │ └── toastStore.ts # Toast 状态\n│ ├── types/ # TypeScript 类型定义\n│ │ ├── vault.ts # VaultEntry、KeyProvider、PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode、NodeStatus、ChannelInfo、TasksInfo\n│ ├── i18n/ # 国际化\n│ │ ├── index.ts # useI18n Hook\n│ │ └── translations.ts # zh/en/ja 翻译表\n│ ├── utils/ # 工具函数\n│ │ └── format.ts # formatDateTime、formatUptime\n│ ├── App.tsx # 根布局 + 侧边栏\n│ └── main.tsx # 入口(HashRouter)\n├── src-tauri/ # 后端(Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri 命令(保险箱 CRUD + 测试 + 节点 CRUD + WS 探测)\n│ │ ├── node.rs # 节点数据模型 + CRUD + 解密 Token\n│ │ ├── crypto.rs # AES-256-GCM 加密/解密\n│ │ ├── db.rs # SQLite Schema + 保险箱查询\n│ │ ├── lib.rs # 模块注册 + 初始化\n│ │ └── main.rs # 入口\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI:跨平台构建 + 发布\n└── package.json\n```\n\n## 设计系统\n\n### 色彩变量(CSS 自定义属性)\n\n```css\n--bg-base: #faf9f7; /* 石白暖底 */\n--bg-surface: #ffffff; /* 纯白卡片 */\n--bg-muted: #f5f4f0; /* 石色微底 */\n--border-default: #e7e5e0; /* 石色边框 */\n--text-primary: #1c1917; /* 主文字 */\n--text-secondary: #57534e; /* 次文字 */\n--text-tertiary: #a8a29e; /* 辅助文字 */\n--accent: #c96442; /* 赤陶橙 */\n--accent-light: #fef3ee; /* 橙色淡底 */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### 服务商连通性测试端点\n\n| 服务商 | 方法 | 端点 | 认证方式 |\n|--------|------|------|----------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query 参数 |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}`(最小对话) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}`(最小对话) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **注意:** 部分服务商(MiniMax、Doubao)不支持标准 `/v1/models` 端点,连通性测试会发送最小化的 `POST /chat/completions` 请求(`max_tokens: 1`),非 401/403 响应即视为认证通过,每次测试最多消耗 1 token。\n\n## 安全架构\n\n```\n[用户输入] → 前端(仅内存中明文)\n ↓\n[Tauri 命令] → Rust 后端\n ↓\n[AES-256-GCM 加密] → nonce + 密文 → base64 → SQLite\n\n[连通性测试] → Rust 解密 Key → reqwest 异步 HTTP → 结果 → DB + Toast\n[WS 探测] → Rust 解密 Token → tokio-tungstenite WS → 状态 → UI\n```\n\n- 加密密钥暂由机器特征(主机名 + 用户名)派生\n- **计划**:集成操作系统 Keychain(macOS Keychain、Windows Credential Manager、Linux Secret Service)\n- 所有外部 HTTP/WS 请求均在 Rust 侧完成,Key/Token 不经过前端网络栈\n- 数据库文件存储在 Tauri 应用数据目录\n\n## 发布\n\n推送版本标签触发自动跨平台构建:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions 会构建 Windows(.msi/.exe)和 macOS(.dmg)安装包,并创建 Release 下载链接。\n\n## OpenClaw 接入前提\n\n默认情况下,OpenClaw 绑定 `localhost`(LAN 模式),拒绝外部客户端连接。要让 XPouch Vault 从其他机器连接,需将监听地址配置为 `0.0.0.0`:\n\n**方式一:通过 OpenClaw 界面** — 设置 → 网关:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**方式二:通过 `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n然后重启:`openclaw gateway restart`\n\n## 许可证\n\n[MIT](./LICENSE)\n"}, "67cf4dd022cdccc3e3126516b441c448791d0b07": {"t": 1785763294.98922, "n": 7271, "h": "a512019052b0a9a5", "c": "# XPouch Vault\n\n安全、优雅的桌面密钥保险箱,管理 AI API Key 并监控 OpenClaw 节点。基于 Tauri 2.x、React 19 和 Rust 构建。\n\n[**English**](./README.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n> **设计理念** — 源自 Claude 的温暖极简美学:石白底色、赤陶橙点缀、留白呼吸感、细腻阴影。\n\n## 功能特性\n\n### 保险箱 — API Key 管理\n\n- **AES-256-GCM 加密** — API Key 字段级加密存储,密钥永不经过前端明文\n- **9 家 AI 服务商** — OpenAI、Anthropic、Google AI、DeepSeek、MiniMax、Kimi、Qwen、Doubao、GLM + 自定义\n- **品牌图标** — 通过 `@lobehub/icons` 展示服务商真实 Logo\n- **连通性测试** — Rust 后端异步验证 Key 有效性,结果持久化到数据库\n- **状态徽章** — 卡片显示 有效 / 失效 / 未测试 三种状态\n- **显示与复制** — 一键切换脱敏/明文显示,一键复制到剪贴板\n- **重命名** — 内联编辑弹窗,无需重建即可修改名称\n- **分类管理** — 按环境分类:生产环境、开发测试、个人项目、备用\n- **脱敏展示** — Key 以脱敏形式展示(如 `sk-...7xYz`)\n- **多语言** — 支持中文、英文、日文\n\n### 龙虾 — OpenClaw 节点监控\n\n- **WebSocket 实时监控** — 通过 WS 协议连接 OpenClaw(health + status 方法)\n- **节点增删改** — 添加、编辑、删除网关节点,Token 加密存储\n- **仪表盘** — 在线/离线状态、版本、运行时间、渠道、Agent、定时任务、在线设备、会话、技能、任务、心跳\n- **自动刷新** — 30 秒间隔自动刷新所有节点状态\n- **详情面板** — 完整信息:渠道(运行/错误)、Agent(模型/会话)、定时任务、在线设备\n\n### 通用\n\n- **本地优先** — 所有数据存储在本地 SQLite(WAL 模式),无云同步、无遥测\n- **Claude 风格 UI** — 温暖石白、赤陶橙点缀、留白呼吸感、细腻阴影\n- **CSS 变量主题** — 通过 `--accent`、`--bg-base`、`--text-primary` 等控制主题\n- **组件库** — Dialog、ConfirmDialog、EmptyState、PageHeader、ActionButton、Form、Toast、StatCard\n\n## 技术栈\n\n| 层级 | 技术 |\n|------|------|\n| 桌面运行时 | Tauri 2.x |\n| 前端 | React 19 + TypeScript + TailwindCSS v4 |\n| 状态管理 | Zustand 5 |\n| 图标 | @lobehub/icons(品牌)+ Lucide(UI) |\n| 后端 | Rust(Tauri 原生命令) |\n| 数据库 | SQLite(rusqlite,内嵌) |\n| 加密 | AES-256-GCM(字段级) |\n| HTTP 客户端 | reqwest 0.12(异步,用于连通性测试) |\n| WebSocket | tokio-tungstenite 0.26(异步,用于 OpenClaw 监控) |\n| 国际化 | 自研(zh/en/ja) |\n| 构建 | Vite 8 + pnpm |\n| CI | GitHub Actions(Windows + macOS) |\n\n## 快速开始\n\n### 环境要求\n\n- [Node.js](https://nodejs.org/) 20+\n- [pnpm](https://pnpm.io/) 9+\n- [Rust](https://www.rust-lang.org/tools/install)(stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 开发\n\n```bash\npnpm tauri dev\n```\n\n启动 Vite 开发服务器(`http://localhost:1420`)并打开 Tauri 窗口。\n\n### 构建\n\n```bash\npnpm tauri build\n```\n\n在 `src-tauri/target/release/bundle/` 生成平台安装包:\n\n| 平台 | 输出格式 |\n|------|---------|\n| Windows | `.msi`、`.exe`(NSIS) |\n| macOS | `.dmg`、`.app` |\n| Linux | `.deb`、`.AppImage` |\n\n> **注意:** 需在目标平台上构建。跨平台发布请使用 GitHub Actions CI。\n\n### 安装须知\n\n本应用**未做代码签名**(无付费证书),首次启动可能会遇到系统警告:\n\n- **Windows**:SmartScreen 可能提示\"Windows 已保护你的电脑\" — 点击**更多信息** → **仍要运行**\n- **macOS**:可能提示\"无法验证开发者\" — **右键点击**应用 → **打开**,或前往**系统设置 → 隐私与安全性 → 仍要打开**\n\n## 项目结构\n\n```\nxpouch-vault/\n├── src/ # 前端(React + TypeScript)\n│ ├── components/ # 业务组件\n│ │ ├── KeyCard.tsx # Key 卡片(复制/显示/测试/编辑/删除)\n│ │ ├── AddKeyDialog.tsx # 添加 Key 弹窗\n│ │ ├── NodeCard.tsx # 节点卡片(在线状态/渠道/任务)\n│ │ ├── AddNodeDialog.tsx # 添加/编辑节点弹窗\n│ │ ├── NodeDetailPanel.tsx # 节点详情面板\n│ │ ├── VaultLogo.tsx # 动画金库门 Logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja 切换器\n│ │ ├── Toast.tsx # 全局 Toast 通知\n│ │ └── ui/ # 可复用 UI 原子组件\n│ │ ├── Dialog.tsx # 弹窗壳\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # 路由页面\n│ │ ├── VaultPage.tsx # 保险箱(首页)\n│ │ └── LobsterPage.tsx # 龙虾监控\n│ ├── store/ # Zustand 状态\n│ │ ├── vaultStore.ts # 保险箱状态 + 操作\n│ │ ├── nodeStore.ts # 节点监控状态 + 操作\n│ │ └── toastStore.ts # Toast 状态\n│ ├── types/ # TypeScript 类型定义\n│ │ ├── vault.ts # VaultEntry、KeyProvider、PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode、NodeStatus、ChannelInfo、TasksInfo\n│ ├── i18n/ # 国际化\n│ │ ├── index.ts # useI18n Hook\n│ │ └── translations.ts # zh/en/ja 翻译表\n│ ├── utils/ # 工具函数\n│ │ └── format.ts # formatDateTime、formatUptime\n│ ├── App.tsx # 根布局 + 侧边栏\n│ └── main.tsx # 入口(HashRouter)\n├── src-tauri/ # 后端(Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri 命令(保险箱 CRUD + 测试 + 节点 CRUD + WS 探测)\n│ │ ├── node.rs # 节点数据模型 + CRUD + 解密 Token\n│ │ ├── crypto.rs # AES-256-GCM 加密/解密\n│ │ ├── db.rs # SQLite Schema + 保险箱查询\n│ │ ├── lib.rs # 模块注册 + 初始化\n│ │ └── main.rs # 入口\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI:跨平台构建 + 发布\n└── package.json\n```\n\n## 设计系统\n\n### 色彩变量(CSS 自定义属性)\n\n```css\n--bg-base: #faf9f7; /* 石白暖底 */\n--bg-surface: #ffffff; /* 纯白卡片 */\n--bg-muted: #f5f4f0; /* 石色微底 */\n--border-default: #e7e5e0; /* 石色边框 */\n--text-primary: #1c1917; /* 主文字 */\n--text-secondary: #57534e; /* 次文字 */\n--text-tertiary: #a8a29e; /* 辅助文字 */\n--accent: #c96442; /* 赤陶橙 */\n--accent-light: #fef3ee; /* 橙色淡底 */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### 服务商连通性测试端点\n\n| 服务商 | 方法 | 端点 | 认证方式 |\n|--------|------|------|----------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query 参数 |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}`(最小对话) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}`(最小对话) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **注意:** 部分服务商(MiniMax、Doubao)不支持标准 `/v1/models` 端点,连通性测试会发送最小化的 `POST /chat/completions` 请求(`max_tokens: 1`),非 401/403 响应即视为认证通过,每次测试最多消耗 1 token。\n\n## 安全架构\n\n```\n[用户输入] → 前端(仅内存中明文)\n ↓\n[Tauri 命令] → Rust 后端\n ↓\n[AES-256-GCM 加密] → nonce + 密文 → base64 → SQLite\n\n[连通性测试] → Rust 解密 Key → reqwest 异步 HTTP → 结果 → DB + Toast\n[WS 探测] → Rust 解密 Token → tokio-tungstenite WS → 状态 → UI\n```\n\n- 加密密钥暂由机器特征(主机名 + 用户名)派生\n- **计划**:集成操作系统 Keychain(macOS Keychain、Windows Credential Manager、Linux Secret Service)\n- 所有外部 HTTP/WS 请求均在 Rust 侧完成,Key/Token 不经过前端网络栈\n- 数据库文件存储在 Tauri 应用数据目录\n\n## 发布\n\n推送版本标签触发自动跨平台构建:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions 会构建 Windows(.msi/.exe)和 macOS(.dmg)安装包,并创建 Release 下载链接。\n\n## OpenClaw 接入前提\n\n默认情况下,OpenClaw 绑定 `localhost`(LAN 模式),拒绝外部客户端连接。要让 XPouch Vault 从其他机器连接,需将监听地址配置为 `0.0.0.0`:\n\n**方式一:通过 OpenClaw 界面** — 设置 → 网关:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**方式二:通过 `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n然后重启:`openclaw gateway restart`\n\n## 许可证\n\n[MIT](./LICENSE)\n"}, "1bd11f09df5c253dd5771ec17ba5858fa28874c5": {"t": 1785763297.7629359, "n": 7271, "h": "a7c6c22aad10e717", "c": "# XPouch Vault\n\n安全、优雅的桌面密钥保险箱,管理 AI API Key 并监控 OpenClaw 节点。基于 Tauri 2.x、React 19 和 Rust 构建。\n\n[**English**](./README.md)\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Tauri](https://img.shields.io/badge/Tauri-2.x-24C8D8?logo=tauri)](https://v2.tauri.app)\n[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev)\n[![Rust](https://img.shields.io/badge/Rust-Stable-000000?logo=rust)](https://www.rust-lang.org)\n\n> **设计理念** — 源自 Claude 的温暖极简美学:石白底色、赤陶橙点缀、留白呼吸感、细腻阴影。\n\n## 功能特性\n\n### 保险箱 — API Key 管理\n\n- **AES-256-GCM 加密** — API Key 字段级加密存储,密钥永不经过前端明文\n- **9 家 AI 服务商** — OpenAI、Anthropic、Google AI、DeepSeek、MiniMax、Kimi、Qwen、Doubao、GLM + 自定义\n- **品牌图标** — 通过 `@lobehub/icons` 展示服务商真实 Logo\n- **连通性测试** — Rust 后端异步验证 Key 有效性,结果持久化到数据库\n- **状态徽章** — 卡片显示 有效 / 失效 / 未测试 三种状态\n- **显示与复制** — 一键切换脱敏/明文显示,一键复制到剪贴板\n- **重命名** — 内联编辑弹窗,无需重建即可修改名称\n- **分类管理** — 按环境分类:生产环境、开发测试、个人项目、备用\n- **脱敏展示** — Key 以脱敏形式展示(如 `sk-...7xYz`)\n- **多语言** — 支持中文、英文、日文\n\n### 龙虾 — OpenClaw 节点监控\n\n- **WebSocket 实时监控** — 通过 WS 协议连接 OpenClaw(health + status 方法)\n- **节点增删改** — 添加、编辑、删除网关节点,Token 加密存储\n- **仪表盘** — 在线/离线状态、版本、运行时间、渠道、Agent、定时任务、在线设备、会话、技能、任务、心跳\n- **自动刷新** — 30 秒间隔自动刷新所有节点状态\n- **详情面板** — 完整信息:渠道(运行/错误)、Agent(模型/会话)、定时任务、在线设备\n\n### 通用\n\n- **本地优先** — 所有数据存储在本地 SQLite(WAL 模式),无云同步、无遥测\n- **Claude 风格 UI** — 温暖石白、赤陶橙点缀、留白呼吸感、细腻阴影\n- **CSS 变量主题** — 通过 `--accent`、`--bg-base`、`--text-primary` 等控制主题\n- **组件库** — Dialog、ConfirmDialog、EmptyState、PageHeader、ActionButton、Form、Toast、StatCard\n\n## 技术栈\n\n| 层级 | 技术 |\n|------|------|\n| 桌面运行时 | Tauri 2.x |\n| 前端 | React 19 + TypeScript + TailwindCSS v4 |\n| 状态管理 | Zustand 5 |\n| 图标 | @lobehub/icons(品牌)+ Lucide(UI) |\n| 后端 | Rust(Tauri 原生命令) |\n| 数据库 | SQLite(rusqlite,内嵌) |\n| 加密 | AES-256-GCM(字段级) |\n| HTTP 客户端 | reqwest 0.12(异步,用于连通性测试) |\n| WebSocket | tokio-tungstenite 0.26(异步,用于 OpenClaw 监控) |\n| 国际化 | 自研(zh/en/ja) |\n| 构建 | Vite 8 + pnpm |\n| CI | GitHub Actions(Windows + macOS) |\n\n## 快速开始\n\n### 环境要求\n\n- [Node.js](https://nodejs.org/) 18+\n- [pnpm](https://pnpm.io/) 8+\n- [Rust](https://www.rust-lang.org/tools/install)(stable)\n- [Tauri CLI](https://v2.tauri.app/start/prerequisites/)\n\n### 安装依赖\n\n```bash\npnpm install\n```\n\n### 开发\n\n```bash\npnpm tauri dev\n```\n\n启动 Vite 开发服务器(`http://localhost:1420`)并打开 Tauri 窗口。\n\n### 构建\n\n```bash\npnpm tauri build\n```\n\n在 `src-tauri/target/release/bundle/` 生成平台安装包:\n\n| 平台 | 输出格式 |\n|------|---------|\n| Windows | `.msi`、`.exe`(NSIS) |\n| macOS | `.dmg`、`.app` |\n| Linux | `.deb`、`.AppImage` |\n\n> **注意:** 需在目标平台上构建。跨平台发布请使用 GitHub Actions CI。\n\n### 安装须知\n\n本应用**未做代码签名**(无付费证书),首次启动可能会遇到系统警告:\n\n- **Windows**:SmartScreen 可能提示\"Windows 已保护你的电脑\" — 点击**更多信息** → **仍要运行**\n- **macOS**:可能提示\"无法验证开发者\" — **右键点击**应用 → **打开**,或前往**系统设置 → 隐私与安全性 → 仍要打开**\n\n## 项目结构\n\n```\nxpouch-vault/\n├── src/ # 前端(React + TypeScript)\n│ ├── components/ # 业务组件\n│ │ ├── KeyCard.tsx # Key 卡片(复制/显示/测试/编辑/删除)\n│ │ ├── AddKeyDialog.tsx # 添加 Key 弹窗\n│ │ ├── NodeCard.tsx # 节点卡片(在线状态/渠道/任务)\n│ │ ├── AddNodeDialog.tsx # 添加/编辑节点弹窗\n│ │ ├── NodeDetailPanel.tsx # 节点详情面板\n│ │ ├── VaultLogo.tsx # 动画金库门 Logo\n│ │ ├── LanguageSwitcher.tsx # zh/en/ja 切换器\n│ │ ├── Toast.tsx # 全局 Toast 通知\n│ │ └── ui/ # 可复用 UI 原子组件\n│ │ ├── Dialog.tsx # 弹窗壳\n│ │ ├── ConfirmDialog.tsx\n│ │ ├── EmptyState.tsx\n│ │ ├── PageHeader.tsx\n│ │ ├── ActionButton.tsx\n│ │ ├── DialogActions.tsx\n│ │ ├── Form.tsx # Input + Select\n│ │ └── StatCard.tsx # StatCard + StatSection + ChannelBadge\n│ ├── pages/ # 路由页面\n│ │ ├── VaultPage.tsx # 保险箱(首页)\n│ │ └── LobsterPage.tsx # 龙虾监控\n│ ├── store/ # Zustand 状态\n│ │ ├── vaultStore.ts # 保险箱状态 + 操作\n│ │ ├── nodeStore.ts # 节点监控状态 + 操作\n│ │ └── toastStore.ts # Toast 状态\n│ ├── types/ # TypeScript 类型定义\n│ │ ├── vault.ts # VaultEntry、KeyProvider、PROVIDER_LABELS/COLORS\n│ │ └── node.ts # OpenClawNode、NodeStatus、ChannelInfo、TasksInfo\n│ ├── i18n/ # 国际化\n│ │ ├── index.ts # useI18n Hook\n│ │ └── translations.ts # zh/en/ja 翻译表\n│ ├── utils/ # 工具函数\n│ │ └── format.ts # formatDateTime、formatUptime\n│ ├── App.tsx # 根布局 + 侧边栏\n│ └── main.tsx # 入口(HashRouter)\n├── src-tauri/ # 后端(Rust)\n│ ├── src/\n│ │ ├── commands.rs # Tauri 命令(保险箱 CRUD + 测试 + 节点 CRUD + WS 探测)\n│ │ ├── node.rs # 节点数据模型 + CRUD + 解密 Token\n│ │ ├── crypto.rs # AES-256-GCM 加密/解密\n│ │ ├── db.rs # SQLite Schema + 保险箱查询\n│ │ ├── lib.rs # 模块注册 + 初始化\n│ │ └── main.rs # 入口\n│ ├── Cargo.toml\n│ └── tauri.conf.json\n├── .github/\n│ └── workflows/\n│ └── build.yml # CI:跨平台构建 + 发布\n└── package.json\n```\n\n## 设计系统\n\n### 色彩变量(CSS 自定义属性)\n\n```css\n--bg-base: #faf9f7; /* 石白暖底 */\n--bg-surface: #ffffff; /* 纯白卡片 */\n--bg-muted: #f5f4f0; /* 石色微底 */\n--border-default: #e7e5e0; /* 石色边框 */\n--text-primary: #1c1917; /* 主文字 */\n--text-secondary: #57534e; /* 次文字 */\n--text-tertiary: #a8a29e; /* 辅助文字 */\n--accent: #c96442; /* 赤陶橙 */\n--accent-light: #fef3ee; /* 橙色淡底 */\n--success: #16a34a;\n--error: #dc2626;\n--warning: #ca8a04;\n```\n\n### 服务商连通性测试端点\n\n| 服务商 | 方法 | 端点 | 认证方式 |\n|--------|------|------|----------|\n| OpenAI | GET | `api.openai.com/v1/models` | `Bearer {key}` |\n| Anthropic | GET | `api.anthropic.com/v1/models` | `x-api-key` + `anthropic-version: 2023-06-01` |\n| Google AI | GET | `generativelanguage.googleapis.com/v1beta/models?key={key}` | Query 参数 |\n| DeepSeek | GET | `api.deepseek.com/v1/models` | `Bearer {key}` |\n| MiniMax | POST | `api.minimaxi.com/v1/chat/completions` | `Bearer {key}`(最小对话) |\n| Kimi | GET | `api.moonshot.cn/v1/models` | `Bearer {key}` |\n| Qwen | GET | `dashscope.aliyuncs.com/compatible-mode/v1/models` | `Bearer {key}` |\n| Doubao | POST | `ark.cn-beijing.volces.com/api/v3/chat/completions` | `Bearer {key}`(最小对话) |\n| GLM | GET | `open.bigmodel.cn/api/paas/v4/models` | `Bearer {key}` |\n\n> **注意:** 部分服务商(MiniMax、Doubao)不支持标准 `/v1/models` 端点,连通性测试会发送最小化的 `POST /chat/completions` 请求(`max_tokens: 1`),非 401/403 响应即视为认证通过,每次测试最多消耗 1 token。\n\n## 安全架构\n\n```\n[用户输入] → 前端(仅内存中明文)\n ↓\n[Tauri 命令] → Rust 后端\n ↓\n[AES-256-GCM 加密] → nonce + 密文 → base64 → SQLite\n\n[连通性测试] → Rust 解密 Key → reqwest 异步 HTTP → 结果 → DB + Toast\n[WS 探测] → Rust 解密 Token → tokio-tungstenite WS → 状态 → UI\n```\n\n- 加密密钥暂由机器特征(主机名 + 用户名)派生\n- **计划**:集成操作系统 Keychain(macOS Keychain、Windows Credential Manager、Linux Secret Service)\n- 所有外部 HTTP/WS 请求均在 Rust 侧完成,Key/Token 不经过前端网络栈\n- 数据库文件存储在 Tauri 应用数据目录\n\n## 发布\n\n推送版本标签触发自动跨平台构建:\n\n```bash\ngit tag v0.3.0\ngit push origin v0.3.0\n```\n\nGitHub Actions 会构建 Windows(.msi/.exe)和 macOS(.dmg)安装包,并创建 Release 下载链接。\n\n## OpenClaw 接入前提\n\n默认情况下,OpenClaw 绑定 `localhost`(LAN 模式),拒绝外部客户端连接。要让 XPouch Vault 从其他机器连接,需将监听地址配置为 `0.0.0.0`:\n\n**方式一:通过 OpenClaw 界面** — 设置 → 网关:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n**方式二:通过 `openclaw.json`**:\n\n```json\n{\n \"gateway\": {\n \"bind\": \"custom\",\n \"customBindHost\": \"0.0.0.0\"\n }\n}\n```\n\n然后重启:`openclaw gateway restart`\n\n## 许可证\n\n[MIT](./LICENSE)\n"}}}}