Files
JRedisDesktop/AGENTS.md
T
Jokul bf0bccb19f refactor: patch all P3 code quality issues, complete full audit
- string.ts: remove dead rejsonDel function (P3#38)
- AGENTS.md: add batchMemoryUsage and executeUnsafe to IPC channels table (P3#41)
- connection.ts: add console.warn to silent TLS/SSH catch blocks (P3#44)
- i18n: replace hardcoded strings in KeyDetail/TitleBar/Sidebar with t() (P3#37)
- composables/useTypeColor.ts: extract shared typeColor, replace in 7 editors (P3#39)
- CliView: extract formatRedisResult function to deduplicate (P3#39)
- SetEditor/ZsetEditor/CommandLog: watch+ref -> computed (P3#40)
- preload/index.d.ts: replace 15+ any types with concrete types (P3#36, P3#42)
- store.ts: add ConnectionConfig version field + migrateConnections() (P3#43)
- docs: update PROJECT_REVIEW.md - all 54 issues processed
2026-07-12 14:42:17 +08:00

13 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 33 (src/main/index.ts)
  • Preload: src/preload/index.ts (contextBridge, typed API)
  • Renderer: Vue 3 + Pinia + Element Plus + Vue Router (src/renderer/src/)
  • IPC types: src/preload/index.d.ts (ElectronAPI interface, global Window augmentation)
  • Build: electron-vite + Vite 6 + TypeScript 5
  • Module system: "type": "module" (ESM) — main outputs .js, preload outputs .mjs
  • 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 -> out/
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
npm run lint           # eslint --fix

Architecture

Electron main (src/main/)
  ├── index.ts            # Window creation, app lifecycle
  ├── ipc-handlers.ts     # all IPC channel handlers
  ├── store.ts            # electron-store (connections, settings)
  ├── credential.ts       # safeStorage encrypt/decrypt
  ├── win-state.ts        # window position persistence
  ├── updater.ts          # electron-updater (check/download/install)
  └── 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

Preload (src/preload/)
  ├── index.ts            # contextBridge.exposeInMainWorld
  └── index.d.ts          # ElectronAPI type declarations

Renderer (src/renderer/)
  ├── index.html          # Vite entry HTML
  └── src/
      ├── main.ts         # Vue 3 bootstrap (Pinia, Element Plus)
      ├── App.vue         # Shell layout (TitleBar + Sidebar + MainArea + StatusBar)
      ├── env.d.ts        # Vite client + *.vue / *.css module declarations
      ├── 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/
      │   ├── layout/                   # App shell
      │   │   ├── TitleBar.vue          # window controls
      │   │   ├── StatusBar.vue         # connection status
      │   │   ├── Sidebar.vue           # connection list host, keyboard shortcuts
      │   │   └── MainArea.vue          # tab host (Status/Keys/CLI/SlowLog/Settings)
      │   ├── connection/               # Connection management
      │   │   ├── ConnectionList.vue    # search, import/export, context menu
      │   │   ├── ConnectionCard.vue    # single connection card
      │   │   └── NewConnectionDialog.vue # create/edit/test connection
      │   ├── key/                      # Key browsing
      │   │   ├── KeyBrowser.vue        # split pane (KeyList + KeyDetail)
      │   │   ├── KeyList.vue           # tree view, SCAN, filter, multi-select
      │   │   ├── KeyDetail.vue         # type dispatch, TTL, rename, copy
      │   │   └── DbSelector.vue        # database 0-15 dropdown
      │   ├── editors/                  # Type-specific value editors
      │   │   ├── 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
      │   │   └── ReJsonEditor.vue      # JSON.GET / JSON.SET editing
      │   └── views/                    # Tab content views
      │       ├── StatusView.vue        # INFO dashboard with stat cards
      │       ├── CliView.vue           # interactive terminal
      │       ├── SlowLogView.vue       # slow log table
      │       ├── MemoryAnalysis.vue    # MEMORY USAGE scan & sort
      │       ├── CommandLog.vue        # command execution history
      │       └── SettingsView.vue      # theme, language, font
      ├── i18n/
      │   ├── index.ts           # useI18n composable
      │   └── locales/
      │       ├── en.ts          # English
      │       ├── zh-CN.ts       # 中文
      │       ├── ja.ts          # 日本語
      │       ├── ko.ts          # 한국어
      │       └── de.ts          # Deutsch
      ├── 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:getInfo invoke INFO server info
redis:ping invoke Health check ping
redis:isConnected invoke Check connection status
redis:scanKeys invoke SCAN with pattern
redis:getKeyType invoke TYPE of a key
redis:getKeyTTL invoke TTL of a key
redis:deleteKey invoke DEL a single key
redis:existsKey invoke EXISTS check
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:listLength invoke LLEN
redis:listPush invoke RPUSH elements
redis:listSet invoke LSET element
redis:listRemove invoke LREM elements
redis:setMembers invoke SMEMBERS
redis:setSize invoke SCARD
redis:setAdd invoke SADD members
redis:setRemove invoke SREM members
redis:zsetRange invoke ZRANGE with scores
redis:zsetSize invoke ZCARD
redis:zsetAdd invoke ZADD member
redis:zsetRemove invoke ZREM members
redis:streamInfo invoke XINFO STREAM
redis:streamRange invoke XRANGE entries
redis:streamAdd invoke XADD entry
redis:streamTrim invoke XTRIM
redis:streamDel invoke XDEL entries
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: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:slowLogLen invoke SLOWLOG LEN
redis:memoryUsage invoke MEMORY USAGE
redis:batchMemoryUsage invoke Pipeline MEMORY USAGE multiple keys
redis:subscribe invoke SUBSCRIBE to channels
redis:unsubscribe invoke UNSUBSCRIBE from channels
redis:subscribeMessage send Push subscribed message to renderer
redis:monitor invoke Start MONITOR stream
redis:monitorStop invoke Stop MONITOR stream
redis:monitorMessage send Push monitored command to renderer
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: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
storage:reorderConnections invoke Reorder connections
storage:getSettings invoke Read settings
storage:saveSettings invoke Save settings
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
theme:os-updated send Push OS theme change to renderer
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
updater:status send Push updater status to renderer
redis:executeUnsafe invoke Execute arbitrary command (CLI bypass for blocked commands)

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
  • Entry points auto-detected (zero-config): src/main/index.ts, src/preload/index.ts, src/renderer/index.html
  • Build output: out/main/index.js, out/preload/index.mjs, out/renderer/ (index.html + assets/)
  • package.json "main" points to ./out/main/index.js
  • electron-builder packages into release/
  • Renderer dev server runs on port 5173
  • Main/preload use externalizeDepsPlugin() to keep node_modules external
  • @renderer alias resolves to src/renderer/src

Runtime paths in main process

src/main/index.ts uses __dirname (resolved to out/main/ at runtime) to locate siblings:

Target Expression
Preload script join(__dirname, '../preload/index.mjs')
Renderer HTML join(__dirname, '../renderer/index.html')
App icon join(__dirname, '../../build/icons/icon_256.png')

If output directory or file extensions change, update these paths accordingly.

TypeScript

  • Root tsconfig.json references tsconfig.node.json (main + preload) and tsconfig.web.json (renderer)
  • Node target (tsconfig.node.json) includes src/main/**/*, src/preload/**/*.ts, electron.vite.config.ts
  • Web target (tsconfig.web.json) includes src/renderer/src/**/*, src/preload/**/*.d.ts
  • Both use verbatimModuleSyntax (type-only imports required) and moduleResolution: "bundler"
  • src/preload/index.d.ts declares the ElectronAPI interface and augments global Window

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.

Known issues

Electron binary not installed after npm install

The allowScripts field in package.json blocks electron's postinstall script (node install.js), so npm install only fetches the npm package without downloading the ~100 MB binary. npm run dev then fails with Error: Electron failed to install correctly or spawn ... ENOENT.

Fix: Run the install script manually after npm install:

node node_modules/electron/install.js

If the download is slow (GitHub releases), use a mirror:

ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/" node node_modules/electron/install.js

package.json references scripts/fix-electron.sh (npm run fix:electron) but the script does not exist yet.