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
8.9 KiB
8.9 KiB
AGENTS.md — JRedisDesktop v2
Project identity
Fork of 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
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.tsdefines 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.jsonreferencestsconfig.node.json(main + preload) andtsconfig.web.json(renderer) - Node target includes
src/main/**/*,src/preload/**/*,electron.vite.config.ts - Web target includes
src/**/* @rendereralias resolves tosrc
Security
contextIsolation: true— renderer has zero Node.js accessnodeIntegration: false— no Node globals in renderersafeStorage— 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.