{"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\"XPouch\n\"XPouch\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\"XPouch\n\"XPouch\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://://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://://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\"XPouch\n\"XPouch\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\"XPouch\n\"XPouch\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"}}}}