71b2bd1771
- Page zoom control (0.5-2.0x, localStorage) - Custom monospace font selector (6 presets + custom) - Element Plus dark mode final fixes (dropdown, message-box, switch, popper) - AGENTS.md updated with correct paths + new modules/components/IPC channels - ROADMAP: window state persistence already done via win-state.ts - ROADMAP: tech debt items marked done
198 lines
8.9 KiB
Markdown
198 lines
8.9 KiB
Markdown
# AGENTS.md — JRedisDesktop v2
|
|
|
|
## Project identity
|
|
|
|
Fork of [AnotherRedisDesktopManager](https://github.com/qishibo/AnotherRedisDesktopManager). The legacy Vue 2 codebase lives in `legacy/` and is gitignored. Work only in the root project.
|
|
|
|
## Stack
|
|
|
|
- **Shell:** Electron 43 (`electron/main/index.ts`)
|
|
- **Preload:** `electron/preload/index.ts` (contextBridge, typed API)
|
|
- **Renderer:** Vue 3 + Pinia + Element Plus + Vue Router (`src/`)
|
|
- **Shared:** `electron/shared/types.ts` (cross-process types)
|
|
- **Build:** electron-vite + Vite 6 + TypeScript 5
|
|
- **Redis client:** ioredis 5 (main process only)
|
|
- **Persistence:** electron-store + safeStorage (credentials)
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
npm run dev # electron-vite dev (HMR, renderer on :5173)
|
|
npm run build # production build → electron-dist/
|
|
npm start # preview built app
|
|
npm run build:unpack # build + electron-builder --dir
|
|
npm run build:win # build + electron-builder --win
|
|
npm run build:mac # build + electron-builder --mac
|
|
npm run build:linux # build + electron-builder --linux
|
|
```
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Electron main (electron/main/)
|
|
├── index.ts # Window creation, app lifecycle
|
|
├── redis/ # Redis service modules
|
|
│ ├── index.ts # Unified export
|
|
│ ├── connection.ts # connect, disconnect, isClientConnected
|
|
│ ├── keys.ts # scan, delete, rename, ttl, batchDelete
|
|
│ ├── string.ts # get, set
|
|
│ ├── hash.ts # hscan, hset, hdel
|
|
│ ├── list.ts # range, push, set, remove
|
|
│ ├── set.ts # members, add, remove
|
|
│ ├── zset.ts # range, add, remove
|
|
│ ├── stream.ts # info, range, add, trim
|
|
│ ├── server.ts # info, select, ping, slowlog
|
|
│ ├── pubsub.ts # SUBSCRIBE/UNSUBSCRIBE
|
|
│ ├── commandLogger.ts # command execution log
|
|
│ └── format.ts # value decode/format detection
|
|
├── store.ts # electron-store (connections, settings)
|
|
├── credential.ts # safeStorage encrypt/decrypt
|
|
├── win-state.ts # window position persistence
|
|
├── updater.ts # electron-updater (check/download/install)
|
|
└── ipc-handlers.ts # all IPC channel handlers
|
|
|
|
Preload (electron/preload/)
|
|
├── index.ts # contextBridge.exposeInMainWorld
|
|
└── index.d.ts # ElectronAPI type declarations
|
|
|
|
Renderer (src/)
|
|
├── main.ts # Vue 3 bootstrap (Pinia, Element Plus)
|
|
├── App.vue # Shell layout (TitleBar + Sidebar + MainArea + StatusBar)
|
|
├── stores/
|
|
│ ├── app.ts # theme, fontSize, scanCount
|
|
│ ├── connection.ts # connections CRUD, connect/disconnect, health check
|
|
│ └── key.ts # key list, scan, tree view, selected key data
|
|
├── components/
|
|
│ ├── TitleBar.vue # window controls
|
|
│ ├── StatusBar.vue # connection status, DB selector
|
|
│ ├── Sidebar.vue # keyboard shortcuts, dialog host
|
|
│ ├── ConnectionList.vue # search, import/export, new button
|
|
│ ├── ConnectionCard.vue # single connection card
|
|
│ ├── NewConnectionDialog.vue # create/edit/test connection
|
|
│ ├── DbSelector.vue # database 0-15 dropdown
|
|
│ ├── MainArea.vue # tab host (Status/Keys/CLI/SlowLog/Settings)
|
|
│ ├── StatusView.vue # INFO dashboard with stat cards
|
|
│ ├── KeyBrowser.vue # split pane (KeyList + KeyDetail)
|
|
│ ├── KeyList.vue # pattern search, filter, SCAN, multi-select
|
|
│ ├── KeyDetail.vue # type dispatch, TTL, rename, copy
|
|
│ ├── StringEditor.vue # view/edit with JSON format
|
|
│ ├── HashEditor.vue # field table CRUD
|
|
│ ├── ListEditor.vue # paginated elements
|
|
│ ├── SetEditor.vue # member list
|
|
│ ├── ZsetEditor.vue # sorted set with scores
|
|
│ ├── StreamEditor.vue # stream entries
|
|
│ ├── CliView.vue # interactive terminal
|
|
│ ├── SlowLogView.vue # slow log table
|
|
│ ├── SettingsView.vue # theme, language, scan count
|
|
│ ├── MemoryAnalysis.vue # MEMORY USAGE scan & sort
|
|
│ ├── CommandLog.vue # command execution history
|
|
│ └── ReJsonEditor.vue # JSON.GET / JSON.SET editing
|
|
├── i18n/
|
|
│ ├── index.ts # useI18n composable
|
|
│ └── locales/
|
|
│ ├── en.ts # English
|
|
│ └── zh-CN.ts # 中文
|
|
├── composables/
|
|
│ └── useKeyboard.ts # keyboard shortcut handler
|
|
├── styles/
|
|
│ ├── variables.css # CSS custom properties
|
|
│ └── global.css # global overrides
|
|
├── data/
|
|
│ └── commands.ts # Redis command definitions
|
|
└── utils/
|
|
└── binary.ts # hex ↔ buffer conversion
|
|
```
|
|
|
|
## IPC Channels
|
|
|
|
| Channel | Type | Purpose |
|
|
|---------|------|---------|
|
|
| `redis:connect` | invoke | Create Redis connection |
|
|
| `redis:disconnect` | invoke | Close connection |
|
|
| `redis:execute` | invoke | Execute arbitrary command |
|
|
| `redis:ping` | invoke | Health check ping |
|
|
| `redis:isConnected` | invoke | Check connection status |
|
|
| `redis:scanKeys` | invoke | SCAN with pattern |
|
|
| `redis:getString` | invoke | GET string value |
|
|
| `redis:setString` | invoke | SET string value |
|
|
| `redis:hashScan` | invoke | HSCAN fields |
|
|
| `redis:hashSet` | invoke | HSET field |
|
|
| `redis:hashDel` | invoke | HDEL field |
|
|
| `redis:listRange` | invoke | LRANGE elements |
|
|
| `redis:listPush` | invoke | RPUSH elements |
|
|
| `redis:setMembers` | invoke | SMEMBERS |
|
|
| `redis:zsetRange` | invoke | ZRANGE with scores |
|
|
| `redis:streamRange` | invoke | XRANGE entries |
|
|
| `redis:streamAdd` | invoke | XADD entry |
|
|
| `redis:batchDelete` | invoke | Pipeline DEL multiple keys |
|
|
| `redis:renameKey` | invoke | RENAME key |
|
|
| `redis:setTTL` | invoke | EXPIRE/PERSIST |
|
|
| `redis:selectDb` | invoke | SELECT database |
|
|
| `redis:dbSize` | invoke | DBSIZE |
|
|
| `redis:slowLogGet` | invoke | SLOWLOG GET |
|
|
| `redis:memoryUsage` | invoke | MEMORY USAGE |
|
|
| `redis:subscribe` | invoke | SUBSCRIBE to channels |
|
|
| `redis:unsubscribe` | invoke | UNSUBSCRIBE from channels |
|
|
| `redis:monitor` | invoke | Start MONITOR stream |
|
|
| `redis:monitorStop` | invoke | Stop MONITOR stream |
|
|
| `redis:getCommandLog` | invoke | Get command execution log |
|
|
| `redis:clearCommandLog` | invoke | Clear command log |
|
|
| `redis:decodeValue` | invoke | Decode value by format |
|
|
| `redis:detectFormat` | invoke | Auto-detect value format |
|
|
| `redis:customFormat` | invoke | Custom external formatter |
|
|
| `redis:streamGroups` | invoke | XINFO GROUPS |
|
|
| `redis:streamConsumers` | invoke | XINFO CONSUMERS |
|
|
| `redis:streamGroupCreate` | invoke | XGROUP CREATE |
|
|
| `redis:streamGroupDestroy` | invoke | XGROUP DESTROY |
|
|
| `redis:streamAck` | invoke | XACK messages |
|
|
| `redis:rejsonGet` | invoke | JSON.GET value |
|
|
| `redis:rejsonSet` | invoke | JSON.SET value |
|
|
| `storage:getConnections` | invoke | Read connections |
|
|
| `storage:saveConnection` | invoke | Save connection |
|
|
| `storage:deleteConnection` | invoke | Delete connection |
|
|
| `credential:encrypt` | invoke | safeStorage encrypt |
|
|
| `credential:decrypt` | invoke | safeStorage decrypt |
|
|
| `dialog:openFile` | invoke | Open file picker |
|
|
| `theme:get` | invoke | Get OS dark mode |
|
|
| `theme:set` | send | Set theme source |
|
|
| `window:minimize` | send | Minimize window |
|
|
| `window:maximize` | send | Toggle maximize |
|
|
| `window:close` | send | Close window |
|
|
| `updater:check` | invoke | Check for updates |
|
|
| `updater:download` | invoke | Download update |
|
|
| `updater:install` | invoke | Quit and install update |
|
|
|
|
## Keyboard Shortcuts
|
|
|
|
| Shortcut | Action | Scope |
|
|
|----------|--------|-------|
|
|
| `Ctrl+N` | New connection | Global |
|
|
| `Ctrl+R` | Refresh keys | Global |
|
|
| `F5` | Refresh keys | Global |
|
|
| `Delete` | Delete selected key | Global |
|
|
| `Escape` | Deselect key | Global |
|
|
|
|
## Build config
|
|
|
|
- `electron.vite.config.ts` defines three build targets: main, preload, renderer
|
|
- Renderer dev server runs on port 5173
|
|
- Main/preload use `externalizeDepsPlugin()` to keep node_modules external
|
|
|
|
## TypeScript
|
|
|
|
- Root `tsconfig.json` references `tsconfig.node.json` (main + preload) and `tsconfig.web.json` (renderer)
|
|
- Node target includes `src/main/**/*`, `src/preload/**/*`, `electron.vite.config.ts`
|
|
- Web target includes `src/**/*`
|
|
- `@renderer` alias resolves to `src`
|
|
|
|
## Security
|
|
|
|
- `contextIsolation: true` — renderer has zero Node.js access
|
|
- `nodeIntegration: false` — no Node globals in renderer
|
|
- `safeStorage` — OS-level encryption for credentials
|
|
- All Redis operations go through typed IPC to main process
|
|
|
|
## Legacy
|
|
|
|
The `legacy/` directory contains the old Vue 2 + Webpack 4 codebase. It is gitignored and not part of the v2 build. See `legacy/AGENTS.md` for its documentation.
|