Console: ⌘K search or jump to
维护者通常 1 天内回复
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 25/100
- Issue 类型
- 功能
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- github-actions, react, typescript
调研方向
Start with ui/src/model/search.ts, ui/src/state/search.ts, and the existing ui/src/app/shell.tsx and sidebar; read the referenced action and navigation modules in #769 and #756 first. Run the Node model test and the browser tests in e2e/console/search.spec.ts, then the console test command. Done when the specified search, keyboard navigation, loading behavior, and action flows pass, including the required CI browser checks.
由索引模型根据 Issue 内容生成。
描述
Part of #756.
Scope
A search box reaches every page, item and action. After this PR an operator presses ⌘K or Ctrl+K (both work on every system) or clicks "Search or jump to…" at the top of the sidebar. They type a few letters and press Enter to open a page, a worker, a device, a lease or a request, or to run any action the ⋯ menus offer.
In short
A dialog opens with a search box and a list of results in groups: Pages, Workers, Devices, Leases, Requests, Actions.
- Typing filters the list. Both the typed text and each label are split into words at spaces,
·and—, somac-studio-2stays one word and a pasted label still matches. A result matches when every typed word is the start of some word of its label, ignoring case. For example,drain macmatches "Drain — mac-studio-2" but not "Undrain — mac-studio-2". - Groups show in the order Pages, Workers, Devices, Leases, Requests, Actions. Inside a group, results where every typed word equals a whole label word come first, then the rest, each by label alphabetically. So
drain mac-studio-2puts "Drain — mac-studio-2" before "Drain — mac-studio-20". - The first result is highlighted. ↑ and ↓ move the highlight. Enter opens or runs the highlighted result, and Escape closes.
- The list is built when the dialog opens. A group that was loading fills in when its data arrives (Actions only once workers, leases and requests have all loaded or failed); a group already shown never changes while the dialog is open. The highlight stays on the same result throughout, so a live update never moves it onto another. Reopening builds the list again.
- ⌘K does nothing while a drawer or a dialog is already open.
- An action runs exactly as from its ⋯ menu, including its confirm dialog and toast.
- With nothing typed, the list shows the pages.
- With no match, it says "No results for
<text>".
| Typed | Shows |
|---|---|
| (nothing) | Pages: Overview, Inbox, Fleet, Leases, Queue, Activity, Usage |
fleet |
Pages: Fleet |
mac-studio-2 |
Workers: mac-studio-2; Devices on it; Actions on it (e.g. Drain — mac-studio-2) |
agent-1 |
Leases: agent-1 · iPhone 17 Pro; Actions: Release lease — agent-1 · iPhone 17 Pro |
DRAIN |
every Drain action, and no Undrain (case ignored) |
drain mac-studio-2 with mac-studio-2 and mac-studio-20 |
Actions: Drain — mac-studio-2 first, then Drain — mac-studio-20 |
zzz |
No results for zzz |
drain on a single host |
No results for drain |
Labels:
- Page: its sidebar name.
- Worker: its name, the label or else the id.
- Device:
<model> · <worker>. - Lease:
<holder> · <model>. - Request:
<requester> · <device asked for>. - Action:
<action> — <item label>, for leases, requests and workers. Inbox items are not listed, since their actions are the same actions on the same worker, device, lease or request.
flowchart LR
K[⌘K or the sidebar box] --> P[dialog: search box + groups]
P -->|Enter on a page or item| N[navigate: page or drawer address]
P -->|Enter on an action| A[same as the ⋯ menu: confirm, toast]
If this goes wrong, ⌘K shows an action the item's ⋯ menu does not, or runs one without its confirm.
Technical spec
Facts
| # | Fact | Source |
|---|---|---|
| F1 | The action list per kind and its availability come from model/actions.ts |
#769 Modules touched; ADR 0037 §3 |
| F2 | Page and item addresses | #756 Shared values |
| F3 | Base UI 1.9.0 ships Dialog and Autocomplete with groups, and documents a command-palette pattern built from them |
@base-ui/[email protected] dialog/, autocomplete/ in a scratch install; base-ui.com/react/components/autocomplete |
| F4 | The console reads workers (/v1/workers), leases (/v1/leases, holder names from /v1/tokens, falling back to ids when tokens are refused) and waiting requests (/v1/lease-requests) |
ui/src/state/workers.ts, ui/src/state/leases.ts:52-56, ui/src/state/waiting.ts |
| F6 | Base UI's Autocomplete highlights nothing unless autoHighlight is set |
@base-ui/[email protected] autocomplete/root/AutocompleteRoot.d.ts:90 |
| F7 | Running an action, its confirm included, is one call: useActions().run(action) opens the action's confirm when it has one, sends it, and shows the toast |
#769 Modules touched (state/actions.ts) |
| F5 | No keyboard listener exists in the console today | git grep -n "keydown|onKeyDown" 97bc8eaf -- ui/src: no hits |
Modules touched
Searches: keydown, actionsFor, useActions, Sidebar, NavigationProvider, autoHighlight.
ui/src/model/search.ts(new): pure. Builds the result list from pages, workers, devices, leases, requests and the actions #769 offers, and filters it by the typed words.ui/src/state/search.ts(new): gathers the data, builds the list once per opening, opens and closes, runs a result throughnavigateoruseActions().run.ui/src/ds/command-palette.tsx(new): Base UI Dialog plus Autocomplete.ds/sidebar.tsx: the "Search or jump to…" button.ui/src/app/shell.tsx: the ⌘K / Ctrl+K listener and the palette.e2e/console/search.spec.ts(new),views.spec.ts.docs/CONSOLE.md(a ⌘K section),docs/internal/DESIGN.md,ui/AGENTS.md.
flowchart LR
shell["app/shell (changed)"] --> ss["state/search (new)"]
shell --> cp["ds/command-palette (new)"]
ss --> ms["model/search (new)"]
ms --> ma["model/actions (#769)"]
ss --> sa["state/actions (#769)"]
Contract and event changes
None.
Other code on the same state
The palette reads what the pages read and runs actions through #769's useActions().run, which owns the confirm and the toast (F7). Searches: useActions(, actionsFor(. With one runner, a ⌘K action and a menu action cannot differ.
- Browser shortcuts: ⌘K/Ctrl+K is taken only while the console has focus, and
preventDefaultstops the browser's own use of it.
Failure modes
| Call | Outcome | What happens | Limit, counted from |
|---|---|---|---|
| a result's action | any outcome | as from the ⋯ menu (#769 Failure modes) | as #769 |
| a result for an item gone since the list was built | not found | the drawer's "gone" message (#765, #766, #768) or the action's error toast | — |
| the data not loaded yet | loading | Pages, and "Loading…" under each other group | — |
| a read fails or is refused | error | Pages and the groups that loaded; the failed group says "Could not load ."; holders fall back to ids when /v1/tokens is refused, as Leases does |
— |
Rules in play
- ADR 0037 §3, "the row's ⋯ menu, … and ⌘K all read that list": the palette reads
model/actions.ts. - ADR 0037 §1: the dialog is Base UI under
ds/, with no<style>element. - DESIGN.md focus ring and keyboard rules: every result is reachable by keyboard, and focus returns to where it was on close.
Tests
Seam: the browser lane (new e2e/console/search.spec.ts, modelled on e2e/console/shell.spec.ts). The filter in Node in model/search.test.ts.
- every row of the In short table gives the results it lists (model test; the single-host row with mode
worker) - ⌘K and Ctrl+K open the dialog and focus the box; the sidebar button opens it too; Escape closes it and focus returns
- typing
fleetand Enter goes to/fleet; a worker result goes to/fleet/<id>; a device result opens/fleet/<workerId>/<deviceId>; a lease result opens/leases/<id>; a request result opens/queue/<id> - opened before the data loads, the groups show "Loading…", then fill in when the data arrives while the highlight stays on its result; with
/v1/workersfailing, the Workers group says "Could not load workers." (stubbed throughpage.route) - a live update while the dialog is open does not change the list or the highlight
- ↑ and ↓ move the highlight, and Enter runs the highlighted result
drain <worker>and Enter drains it with the same toast and Undo as the menu;release <holder>asks the same confirm first;cancel <requester>asks the cancel confirm;remove <worker>(a stopped worker) asks to type the name, with Remove worker disabled until it matches- ⌘K does nothing while a drawer is open
- no results shows "No results for
<text>" - axe passes with the palette open, in light and dark; no
<style>element or CSP violation (extendviews.spec.ts)
Done when
pnpm test:console --project=chromiumpasses, and CI's Console check passes in every browser.
Out of scope
- Searching event payloads or history. Fuzzy matching beyond "every word appears".
Depends on
- #769
Written by an agent.
- 主要语言
- TypeScript
- 星标
- 20
- 派生
- 2
- 平均合并
- 8 小时 10 分钟
- 30 天内合并 PR
- 354
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
callstackincubator/simlock 的其他 Issue
-
bug:new
难度 2/5 1-3 小时 新手友好度 67/100
callstackincubator/simlock#871 ·
维护者通常 1 天内回复
-
bug:new
难度 2/5 1-3 小时 新手友好度 78/100
callstackincubator/simlock#817 ·
维护者通常 1 天内回复
-
bug:triage
难度 2/5 1-3 小时 新手友好度 76/100
callstackincubator/simlock#778 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 70/100
callstackincubator/simlock#639 · 1 条评论 ·
维护者通常 1 天内回复
-
bug:new flaky-test
难度 3/5 1-2 天 新手友好度 62/100
callstackincubator/simlock#886 ·
维护者通常 1 天内回复
查看 callstackincubator/simlock 的全部 Issue
相似的 Issue
-
数据界面的横向滚动条缺失未关闭
难度 2/5 1-3 小时 新手友好度 62/100
zilliztech/attu#1037 ·
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
难度 2/5 1-3 小时 新手友好度 76/100
openclaw/openclaw#181212 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
apify/apify-mcp-server#1684 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
Automattic/data-liberation-agent#953 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
siteboon/claudecodeui#1642 ·
维护者通常 5 天内回复