Skip to content

feat: 指令输入框新增上下键选择历史发送#522

Open
XinJiDA wants to merge 3 commits intoSeaLantern-Studio:devfrom
XinJiDA:dev
Open

feat: 指令输入框新增上下键选择历史发送#522
XinJiDA wants to merge 3 commits intoSeaLantern-Studio:devfrom
XinJiDA:dev

Conversation

@XinJiDA
Copy link

@XinJiDA XinJiDA commented Feb 27, 2026

提交前检查清单

  • 已阅读 提交前测试必读!!!.md 并完成要求测试
  • 本地/CI 测试通过
  • 代码审查 (Self-review) 完成

变更分类(必选其一)

  • feat 新功能

影响范围(可多选)

  • 前端 Frontend
    • 组件/状态/路由逻辑

导入规范检查: 使用别名导入,避免相对路径 ../

变更详情

具体改动

修改输入框组件,使用 localStorage 存储历史发送记录,监听按键自动键入历史记录

关联 Issue


自动化审查说明

sourcery-ai 及其他 code review 工具请务必进行中英双语审查与交流。

Note: Please ensure sourcery-ai and other tools perform bilingual (Chinese & English) review.

由 Sourcery 提供的摘要

在控制台输入中添加基于服务器的命令历史记录以及键盘导航功能。

新特性:

  • localStorage 中按服务器分别持久化控制台命令历史记录,并设置历史记录数量上限。
  • 当没有自动补全建议时,允许在控制台输入中使用上下方向键导航并重新插入之前发送过的命令。
Original summary in English

Summary by Sourcery

Add per-server console command history with keyboard navigation in the console input.

New Features:

  • Persist console command history per server in localStorage with a bounded history size.
  • Allow using the up and down arrow keys in the console input to navigate and reinsert previously sent commands when no autocomplete suggestions are shown.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 27, 2026

审阅者指南

为每个服务器添加基于 localStorage 的控制台命令历史记录,并支持在控制台输入框中通过上下方向键导航之前发送过的命令。

控制台输入上下方向键历史导航的时序图

sequenceDiagram
  actor User
  participant ConsoleInputComponent
  participant LocalStorage

  User->>ConsoleInputComponent: keydown ArrowUp/ArrowDown
  ConsoleInputComponent->>ConsoleInputComponent: handleKeydown(e)
  alt showSuggestions is false and key is ArrowUp/ArrowDown
    ConsoleInputComponent->>ConsoleInputComponent: update commandHistoryIndex
    ConsoleInputComponent->>ConsoleInputComponent: clamp index within [0, commandHistoryCache.length - 1]
    ConsoleInputComponent->>ConsoleInputComponent: commandInput.value = commandHistoryCache[commandHistoryIndex]
  else other keys or suggestions visible
    ConsoleInputComponent->>ConsoleInputComponent: existing key handling
  end

  User->>ConsoleInputComponent: keydown Enter
  ConsoleInputComponent->>ConsoleInputComponent: sendCommand()
  ConsoleInputComponent->>ConsoleInputComponent: command = commandInput.value.trim()
  ConsoleInputComponent->>User: emit sendCommand(command)
  ConsoleInputComponent->>ConsoleInputComponent: commandHistoryCache.unshift(command)
  ConsoleInputComponent->>ConsoleInputComponent: trim commandHistoryCache to COMMAND_HISTORY_MAX_LENGTH
  ConsoleInputComponent->>LocalStorage: setItem(COMMAND_HISTORY_CACHE_KEY, JSON.stringify(commandHistoryCacheAll))
  ConsoleInputComponent->>ConsoleInputComponent: commandHistoryIndex = -1
  ConsoleInputComponent->>ConsoleInputComponent: reset commandInput and suggestion state
Loading

更新后的控制台输入命令历史处理类图

classDiagram
  class ConsoleInputComponent {
    +number consoleFontSize
    +Ref commandInput
    +Ref showSuggestions
    +Ref suggestionIndex
    +Ref lastTabOriginalWord
    +Ref lastTabWordIndex
    +Ref tabCycleIndex
    -boolean isCompleting
    -string serverId
    -string COMMAND_HISTORY_CACHE_KEY
    -number COMMAND_HISTORY_MAX_LENGTH
    -Record~string, string[]~ commandTree
    -any commandHistoryCacheAll
    -string[] commandHistoryCache
    -number commandHistoryIndex
    +sendCommand() void
    +handleKeydown(e KeyboardEvent) void
  }

  class ServerStore {
    +string currentServerId
  }

  class LocalStorageService {
    +getItem(key string) string
    +setItem(key string, value string) void
  }

  ConsoleInputComponent --> ServerStore : uses useServerStore
  ConsoleInputComponent --> LocalStorageService : uses localStorage
  ConsoleInputComponent ..> commandTree : autocomplete data source
  ConsoleInputComponent ..> commandHistoryCache : perServerHistory
  ConsoleInputComponent ..> commandHistoryCacheAll : allServersHistory
Loading

文件级变更

变更 详情 文件
在 localStorage 中按服务器持久化控制台命令历史,并保留一个有界的内存缓存。
  • 引入服务器 store 依赖,以获取当前服务器 ID 来限定历史范围。
  • 定义一个共享的 localStorage key,解析现有 JSON 载荷,并派生出当前服务器的历史记录数组。
  • 通过在每次新增命令时裁剪旧条目,将存储的命令历史长度限制在固定最大值。
src/components/console/ConsoleInput.vue
将历史管理集成到控制台输入的命令发送和按键处理流程中。
  • 在命令成功发送时,将命令加入历史,将更新后的缓存持久化回 localStorage,并重置历史索引和输入状态。
  • 跟踪一个 commandHistoryIndex,用于表示当前选中的历史条目。
  • 扩展 keydown 处理:当建议列表隐藏时,ArrowUp/ArrowDown 在历史中移动,并用选中的历史命令覆盖当前输入,同时短路其他按键处理逻辑。
src/components/console/ConsoleInput.vue

可能关联的议题


提示与指令

与 Sourcery 交互

  • 触发新评审: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 回复 Sourcery 的评审评论并请求从该评论创建 issue。你也可以直接回复评审评论 @sourcery-ai issue 来从中创建一个 issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 以(重新)生成标题。
  • 生成 pull request 总结: 在 pull request 正文中任意位置写上 @sourcery-ai summary,即可在该位置生成 PR 总结。你也可以在 pull request 中评论 @sourcery-ai summary 来在任意时间(重新)生成总结。
  • 生成审阅者指南: 在 pull request 中评论 @sourcery-ai guide,即可在任意时间(重新)生成审阅者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,以解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 忽略所有 Sourcery 评审: 在 pull request 中评论 @sourcery-ai dismiss,以忽略所有现有的 Sourcery 评审。特别适用于你想从一次全新的评审开始的场景——别忘了再评论 @sourcery-ai review 来触发新评审!

自定义你的体验

访问你的 dashboard 以:

  • 启用或禁用评审特性,例如 Sourcery 生成的 pull request 总结、审阅者指南等。
  • 更改评审语言。
  • 添加、移除或编辑自定义评审指令。
  • 调整其他评审设置。

获取帮助

Original review guide in English

Reviewer's Guide

Adds per-server console command history backed by localStorage and enables navigating previously sent commands in the console input using up/down arrow keys.

Sequence diagram for console input up/down history navigation

sequenceDiagram
  actor User
  participant ConsoleInputComponent
  participant LocalStorage

  User->>ConsoleInputComponent: keydown ArrowUp/ArrowDown
  ConsoleInputComponent->>ConsoleInputComponent: handleKeydown(e)
  alt showSuggestions is false and key is ArrowUp/ArrowDown
    ConsoleInputComponent->>ConsoleInputComponent: update commandHistoryIndex
    ConsoleInputComponent->>ConsoleInputComponent: clamp index within [0, commandHistoryCache.length - 1]
    ConsoleInputComponent->>ConsoleInputComponent: commandInput.value = commandHistoryCache[commandHistoryIndex]
  else other keys or suggestions visible
    ConsoleInputComponent->>ConsoleInputComponent: existing key handling
  end

  User->>ConsoleInputComponent: keydown Enter
  ConsoleInputComponent->>ConsoleInputComponent: sendCommand()
  ConsoleInputComponent->>ConsoleInputComponent: command = commandInput.value.trim()
  ConsoleInputComponent->>User: emit sendCommand(command)
  ConsoleInputComponent->>ConsoleInputComponent: commandHistoryCache.unshift(command)
  ConsoleInputComponent->>ConsoleInputComponent: trim commandHistoryCache to COMMAND_HISTORY_MAX_LENGTH
  ConsoleInputComponent->>LocalStorage: setItem(COMMAND_HISTORY_CACHE_KEY, JSON.stringify(commandHistoryCacheAll))
  ConsoleInputComponent->>ConsoleInputComponent: commandHistoryIndex = -1
  ConsoleInputComponent->>ConsoleInputComponent: reset commandInput and suggestion state
Loading

Class diagram for updated console input command history handling

classDiagram
  class ConsoleInputComponent {
    +number consoleFontSize
    +Ref commandInput
    +Ref showSuggestions
    +Ref suggestionIndex
    +Ref lastTabOriginalWord
    +Ref lastTabWordIndex
    +Ref tabCycleIndex
    -boolean isCompleting
    -string serverId
    -string COMMAND_HISTORY_CACHE_KEY
    -number COMMAND_HISTORY_MAX_LENGTH
    -Record~string, string[]~ commandTree
    -any commandHistoryCacheAll
    -string[] commandHistoryCache
    -number commandHistoryIndex
    +sendCommand() void
    +handleKeydown(e KeyboardEvent) void
  }

  class ServerStore {
    +string currentServerId
  }

  class LocalStorageService {
    +getItem(key string) string
    +setItem(key string, value string) void
  }

  ConsoleInputComponent --> ServerStore : uses useServerStore
  ConsoleInputComponent --> LocalStorageService : uses localStorage
  ConsoleInputComponent ..> commandTree : autocomplete data source
  ConsoleInputComponent ..> commandHistoryCache : perServerHistory
  ConsoleInputComponent ..> commandHistoryCacheAll : allServersHistory
Loading

File-Level Changes

Change Details Files
Persist console command history per server in localStorage and keep a bounded in-memory cache.
  • Introduce server store dependency to obtain current server ID for scoping history.
  • Define a shared localStorage key, parse existing JSON payload, and derive the per-server history array.
  • Limit stored command history length to a fixed maximum by trimming older entries on each new command.
src/components/console/ConsoleInput.vue
Integrate history management into the command send and key handling flow of the console input.
  • On successful command send, push the command into history, persist the updated cache back to localStorage, and reset the history index and input state.
  • Track a commandHistoryIndex to represent the currently selected history item.
  • Extend keydown handling so that when suggestions are hidden, ArrowUp/ArrowDown move through history and overwrite the current input with the selected historical command, short‑circuiting other key handling.
src/components/console/ConsoleInput.vue

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我这边发现了 4 个问题,并给出了一些总体性的反馈:

  • 当前的命令历史持久化逻辑会读取 commandHistoryCacheAll[serverId.value],但在字符串化之前从未把更新后的 commandHistoryCache 再写回这个 key,同时只在初始化时获取了一次 serverId.value;建议显式地在保存前执行 commandHistoryCacheAll[serverId.value] = commandHistoryCache,并且对服务器变更进行响应式处理,这样才能正确地按服务器分别存储和读取历史记录。
  • 在 setup 脚本的顶层访问 localStorage,在非浏览器或 SSR 场景中可能会出问题;建议对这些调用加保护(例如检查 window / localStorage 是否可用),或者在组件挂载时再延迟初始化历史记录。
  • 目前 commandHistoryIndex 的方向键导航逻辑会产生一些比较别扭的边界行为(例如从 -1 开始再被钳制,或者在超出最新命令时无法清空输入);你可能需要重新审视索引更新/钳制策略,并明确定义在超出历史边界时的统一交互体验。
给 AI Agent 的 Prompt
Please address the comments from this code review:

## Overall Comments
- 当前的命令历史持久化逻辑会读取 `commandHistoryCacheAll[serverId.value]`,但在字符串化之前从未把更新后的 `commandHistoryCache` 再写回这个 key,同时只在初始化时获取了一次 `serverId.value`;建议显式地在保存前执行 `commandHistoryCacheAll[serverId.value] = commandHistoryCache`,并且对服务器变更进行响应式处理,这样才能正确地按服务器分别存储和读取历史记录。
- 在 setup 脚本的顶层访问 `localStorage`,在非浏览器或 SSR 场景中可能会出问题;建议对这些调用加保护(例如检查 `window` / `localStorage` 是否可用),或者在组件挂载时再延迟初始化历史记录。
- 目前 `commandHistoryIndex` 的方向键导航逻辑会产生一些比较别扭的边界行为(例如从 -1 开始再被钳制,或者在超出最新命令时无法清空输入);你可能需要重新审视索引更新/钳制策略,并明确定义在超出历史边界时的统一交互体验。

## Individual Comments

### Comment 1
<location path="src/components/console/ConsoleInput.vue" line_range="10" />
<code_context>
+// 获取服务器ID,定义历史指令缓存参数
+const serverStore = useServerStore();
+const serverId = computed(() => serverStore.currentServerId || "");
+const COMMAND_HISTORY_CACHE_KEY = "commond_history";
+const COMMAND_HISTORY_MAX_LENGTH = 20;
+
</code_context>
<issue_to_address>
**suggestion (typo):** 历史缓存 key 存在拼写错误,后续可能造成困惑或不一致。

字符串 `"commond_history"` 很可能是想写成 `"command_history"`。现在就进行重命名能让 key 更一致、易理解;如果已经在使用旧 key,可以考虑做一个简单的数据迁移。

建议实现:

```
 // 获取服务器ID,定义历史指令缓存参数
const serverStore = useServerStore();
const serverId = computed(() => serverStore.currentServerId || "");
const COMMAND_HISTORY_CACHE_KEY = "command_history";
const COMMAND_HISTORY_MAX_LENGTH = 20;

```

如果 `"commond_history"` 已经写入过 localStorage 或其他持久化存储,你应该在首次读取历史记录的地方加入一个小迁移逻辑:
1. 初始化时,如果在 `"command_history"` 下没有数据,但在 `"commond_history"` 下有数据,则读取旧 key 的数据并存入新的 `"command_history"` key,然后删除旧 key。
2. 这段逻辑应放在首次通过 `COMMAND_HISTORY_CACHE_KEY` 加载历史记录的地方(本文件或相关文件中)。
</issue_to_address>

### Comment 2
<location path="src/components/console/ConsoleInput.vue" line_range="33-34" />
<code_context>
 const tabCycleIndex = ref(0);
+
 let isCompleting = false;
+const commandHistoryCacheAll = JSON.parse(localStorage.getItem(COMMAND_HISTORY_CACHE_KEY) || "{}");
+const commandHistoryCache = commandHistoryCacheAll[serverId.value] || [];
+let commandHistoryIndex = -1;

</code_context>
<issue_to_address>
**issue (bug_risk):** 当前在持久化历史记录时,没有把当前服务器对应的 `commandHistoryCache` 更新回 `commandHistoryCacheAll`,因此按服务器区分的历史可能无法被正确保存。

当当前服务器的 key 不存在时,`commandHistoryCache` 会是一个单独的数组,对它的修改不会反映到 `commandHistoryCacheAll` 上。在调用 `localStorage.setItem` 之前,应先执行 `commandHistoryCacheAll[serverId.value] = commandHistoryCache`,这样序列化后的对象中才会包含该服务器更新后的历史记录。
</issue_to_address>

### Comment 3
<location path="src/components/console/ConsoleInput.vue" line_range="249-256" />
<code_context>
   }

+  // 上下键选择历史指令
+  if (showSuggestions.value == false && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
+    commandHistoryIndex += e.key === "ArrowUp" ? 1 : -1;
+    if (commandHistoryCache.length <= commandHistoryIndex) {
+      commandHistoryIndex = commandHistoryCache.length - 1;
+    } else if (commandHistoryIndex < 0) {
+      commandHistoryIndex = 0;
+    }
+    commandInput.value = commandHistoryCache[commandHistoryIndex];
+    return;
+  }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** 上/下方向键导航逻辑存在一些潜在的异常行为,并且在历史记录为空时没有安全处理。

主要问题:
-`commandHistoryIndex` 初始为 `-1` 的情况下,第一次按下 ArrowDown 会将其设为 `-2`,然后被钳制为 `0`,因此 ArrowUp 和 ArrowDown 第一次都会落在索引 `0`,违反了预期的「向上 = 更旧,向下 = 更新」的语义。
-`commandHistoryCache.length === 0` 时,索引会被钳制到 `0`,此时 `commandInput.value` 会变成 `undefined`。在历史为空时,最好直接提前返回。
- 建议重构索引钳制逻辑,使方向语义更明确,例如:
  - Up:`index = Math.min(index + 1, maxIndex)`
  - Down:`index = Math.max(index - 1, -1)`
  并且在索引为 `-1` 时恢复原始输入内容,而不是强制跳到索引 0。
</issue_to_address>

### Comment 4
<location path="src/components/console/ConsoleInput.vue" line_range="9-15" />
<code_context>

+// 获取服务器ID,定义历史指令缓存参数
+const serverStore = useServerStore();
+const serverId = computed(() => serverStore.currentServerId || "");
+const COMMAND_HISTORY_CACHE_KEY = "commond_history";
+const COMMAND_HISTORY_MAX_LENGTH = 20;
</code_context>
<issue_to_address>
**issue (bug_risk):** 命令历史缓存和初始化时的 `serverId` 绑定在一起,当当前服务器发生变化时不会更新。

由于 `serverId` 是一个可能变化的 computed,`commandHistoryCache` 必须从它中以响应式方式派生出来。否则,在切换服务器后,命令仍然会在原服务器的历史下读写。请让 `commandHistoryCache` 依赖 `serverId`(例如使用另一个 computed,或 watcher 重新解析底层数组),以确保始终使用当前服务器对应的历史数据。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你觉得这些 Review 有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进 Review 质量。
Original comment in English

Hey - I've found 4 issues, and left some high level feedback:

  • The command history persistence currently reads commandHistoryCacheAll[serverId.value] but never writes the updated commandHistoryCache back under that key before stringifying, and also only captures serverId.value once at setup; consider explicitly assigning commandHistoryCacheAll[serverId.value] = commandHistoryCache and handling server changes reactively so per-server history is actually stored and retrieved correctly.
  • Accessing localStorage at the top level of the setup script can cause issues in non-browser or SSR contexts; consider guarding these calls (e.g. checking for window/localStorage availability) or lazily initializing the history when the component is mounted.
  • The arrow key navigation logic for commandHistoryIndex can produce awkward edge behavior (e.g., starting from -1 and clamping, or not allowing clearing the input when navigating past the newest command); you may want to revisit the index update/clamping strategy and define a consistent UX for navigating beyond the bounds of the history.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The command history persistence currently reads `commandHistoryCacheAll[serverId.value]` but never writes the updated `commandHistoryCache` back under that key before stringifying, and also only captures `serverId.value` once at setup; consider explicitly assigning `commandHistoryCacheAll[serverId.value] = commandHistoryCache` and handling server changes reactively so per-server history is actually stored and retrieved correctly.
- Accessing `localStorage` at the top level of the setup script can cause issues in non-browser or SSR contexts; consider guarding these calls (e.g. checking for `window`/`localStorage` availability) or lazily initializing the history when the component is mounted.
- The arrow key navigation logic for `commandHistoryIndex` can produce awkward edge behavior (e.g., starting from -1 and clamping, or not allowing clearing the input when navigating past the newest command); you may want to revisit the index update/clamping strategy and define a consistent UX for navigating beyond the bounds of the history.

## Individual Comments

### Comment 1
<location path="src/components/console/ConsoleInput.vue" line_range="10" />
<code_context>
+// 获取服务器ID,定义历史指令缓存参数
+const serverStore = useServerStore();
+const serverId = computed(() => serverStore.currentServerId || "");
+const COMMAND_HISTORY_CACHE_KEY = "commond_history";
+const COMMAND_HISTORY_MAX_LENGTH = 20;
+
</code_context>
<issue_to_address>
**suggestion (typo):** The history cache key has a typo that may cause confusion or inconsistency later.

The string `"commond_history"` is likely meant to be `"command_history"`. Renaming it now will keep the key consistent and easier to understand; if this is already in use, consider a simple migration for existing data.

Suggested implementation:

```
 // 获取服务器ID,定义历史指令缓存参数
const serverStore = useServerStore();
const serverId = computed(() => serverStore.currentServerId || "");
const COMMAND_HISTORY_CACHE_KEY = "command_history";
const COMMAND_HISTORY_MAX_LENGTH = 20;

```

If `"commond_history"` has already been written to localStorage or another persistence layer, you should add a small migration where the history is first read:
1. On initialization, if there is no data under `"command_history"` but data exists under `"commond_history"`, read it and store it under the new `"command_history"` key, then remove the old key.
2. This logic should be placed wherever the history is initially loaded using `COMMAND_HISTORY_CACHE_KEY` in this or related files.
</issue_to_address>

### Comment 2
<location path="src/components/console/ConsoleInput.vue" line_range="33-34" />
<code_context>
 const tabCycleIndex = ref(0);
+
 let isCompleting = false;
+const commandHistoryCacheAll = JSON.parse(localStorage.getItem(COMMAND_HISTORY_CACHE_KEY) || "{}");
+const commandHistoryCache = commandHistoryCacheAll[serverId.value] || [];
+let commandHistoryIndex = -1;

</code_context>
<issue_to_address>
**issue (bug_risk):** History is persisted without updating `commandHistoryCacheAll` for the current server, so per-server history may not be saved correctly.

Because `commandHistoryCache` is a separate array when the server key is missing, mutations to it are not reflected in `commandHistoryCacheAll`. Before calling `localStorage.setItem`, you should assign `commandHistoryCacheAll[serverId.value] = commandHistoryCache` so the serialized object includes the updated history for this server.
</issue_to_address>

### Comment 3
<location path="src/components/console/ConsoleInput.vue" line_range="249-256" />
<code_context>
   }

+  // 上下键选择历史指令
+  if (showSuggestions.value == false && (e.key === "ArrowUp" || e.key === "ArrowDown")) {
+    commandHistoryIndex += e.key === "ArrowUp" ? 1 : -1;
+    if (commandHistoryCache.length <= commandHistoryIndex) {
+      commandHistoryIndex = commandHistoryCache.length - 1;
+    } else if (commandHistoryIndex < 0) {
+      commandHistoryIndex = 0;
+    }
+    commandInput.value = commandHistoryCache[commandHistoryIndex];
+    return;
+  }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Arrow up/down navigation logic can behave unexpectedly and does not handle an empty history safely.

Key issues:
- With `commandHistoryIndex` starting at `-1`, the first ArrowDown sets it to `-2`, then it’s clamped to `0`, so both ArrowUp and ArrowDown first land on index `0`. This breaks the expected "Up = older, Down = newer" behavior.
- When `commandHistoryCache.length === 0`, the index is clamped to `0` and `commandInput.value` becomes `undefined`. It’s safer to early-return when the history is empty.
- Refactor the clamping so the direction semantics are explicit, e.g.:
  - Up: `index = Math.min(index + 1, maxIndex)`
  - Down: `index = Math.max(index - 1, -1)`
  and when at `-1`, restore the original input instead of forcing index 0.
</issue_to_address>

### Comment 4
<location path="src/components/console/ConsoleInput.vue" line_range="9-15" />
<code_context>

+// 获取服务器ID,定义历史指令缓存参数
+const serverStore = useServerStore();
+const serverId = computed(() => serverStore.currentServerId || "");
+const COMMAND_HISTORY_CACHE_KEY = "commond_history";
+const COMMAND_HISTORY_MAX_LENGTH = 20;
</code_context>
<issue_to_address>
**issue (bug_risk):** The command history cache is bound to the initial `serverId` value and won’t update if the current server changes.

Because `serverId` is a computed that can change, `commandHistoryCache` must be derived reactively from it. Otherwise, after a server switch, commands will still be read/written under the original server’s history. Please make `commandHistoryCache` depend on `serverId` (e.g., another computed or a watcher that re-resolves the underlying array) so it always uses the current server’s history.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@LingyeNBird
Copy link
Collaborator

改成db添加命令历史,使用查询更好

即服务器日志新增一个input或者command类型

@xingwangzhe xingwangzhe added the suspend merger Suspend merger | 暂缓合并 label Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

suspend merger Suspend merger | 暂缓合并

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 命令历史和上下键补全

3 participants