Repository navigation
feat(webui): let the settings page rebind the composer's send and newline keys - #265
Open
stevenjj33 wants to merge 2 commits into
Open
stevenjj33 wants to merge 2 commits into
stevenjj33 wants to merge 2 commits into
Conversation
…line keys The 快捷键 tab was a label with `disabled: true` behind it, and the composer decided in code what Enter meant. The tab is now a page: it lists the composer's keyboard actions, shows the key each one is bound to, and changes the binding. - The notation is one canonical string (`Control+Shift+Enter`) shared by the page and the composer, in `client/projection/common/shortcuts.ts`. - 发送消息 (built-in `Enter`) and 换行 (built-in `Shift+Enter`) are rebindable; 停止生成 is listed as 仅按钮,无快捷键, because `Escape` is already claimed by the menus it closes. - The binding is stored under `webui-shortcuts.v1`, a key of its own, and the composer reads it when a key is pressed, so a rebinding takes effect at once. - A capture refuses a bare modifier and a combination another action already holds, and names the action that holds it. - `resolveWebuiComposerEnterAction` is retired: the rule it encoded is the default configuration, expressed as the values the page shows. ADR 0026 records the decision.
The settings shortcut storage key reads like a credential to gitleaks' generic-api-key rule, so the release audit rejected this branch. It is a localStorage key name, not a secret, so allowlist it next to the other documented non-credentials.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
The settings page's 快捷键 tab was a label with
disabled: truebehind it, and the composer decided in code whatEntermeant. This PR makes the tab a real page:Enter) and 换行 (break the line, built-inShift+Enter) are rebindable.Escapeis already claimed by the mention menu, the slash menu, the permission menu, goal mode and plan mode, so a shortcut for it would fight them. NoEscbinding was added, per the task book.webui-shortcuts.v1— a key of its own, so it cannot collide with feat(webui): let the settings page switch between Chinese and English #250'smavis-locale.The built-in behaviour is unchanged: with nothing stored,
Entersends andShift+Enterbreaks the line.How it is put together
packages/webui/src/client/projection/common/shortcuts.ts— one canonical string (Control+Shift+Enter) that the page stores, shows and the composer matches againstpackages/webui/src/client/features/settings/projection/settings-shortcuts.tspackages/webui/src/client/features/settings/ui/ShortcutsSettings.tsxresolveWebuiComposerShortcutActioninpackages/webui/src/client/features/composer/projection/composer-state.tsresolveWebuiComposerEnterActionis retired: the rule it encoded is the default configuration, expressed as the values the page shows. The three-valued answer (submit/newline/ignore) is what lets a press that names no binding fall through to the browser's own behaviour — which is how a key the user unbound stops doing the composer's business.ADR
packages/webui/docs/adr/0026-the-composer-follows-the-bindings-the-settings-page-stores.mdrecords the decision.Evidence
pnpm --filter @mavis/webui typecheck:client/pnpm typecheck:webuipnpm exec vitest run … settings-shortcuts.test.ts composer-intent.test.ts settings-modal.test.tsx browser-settings-page.test.tsxpnpm exec playwright test … settings-shortcuts.spec.mjspnpm exec playwright test … settings-account-tab.spec.mjs settings-theme.spec.mjs composer.spec.mjspnpm build:webuinode scripts/source-inventory.mjs --write+pnpm check:sourcepnpm check:webui-dependencyThe browser suite covers the six acceptance points one by one: the tab opens and lists the actions with their current keys; a captured combination becomes the binding the page shows; the binding survives closing the settings and coming back; the binding survives a reload; the composer sends on the new key and no longer on the old one (the draft keeps the text and the line break, and nothing was sent for it); 恢复默认 returns to
Enterand the behaviour follows it back. A seventh case covers a newline bound to a key the browser does not break the line on (Control+J), which the composer breaks itself.Negative controls (mutation, then restore)
Control+J"webui-shortcuts.v1Control+JnewlineBoth mutations were reverted and the suite was re-run green.
CI
changesverify (windows-latest, 24)verify (ubuntu-latest, 24)check:webui-dependency, on the baseline's two violations — see belowverify (macos-latest, 24)check:source(PASS) andtypecheck:webui(PASS) both passed before itverificationsuccess, so it fails because of the two abovesource-history-artifact(Release audit)no leaks foundon all three gitleaks stepsperformancedocsThe
check:webui-dependencyfailure is the baseline'sThe gate reports exactly two violations, both of them the same one on the baseline:
git diff --name-only origin/webui...HEADdoes not list it.void document.fonts.ready.then(() => {in the untouchedorigin/webui(e2de9a1), and runningpnpm check:webui-dependencyon a cleanorigin/webuiworktree fails identically.check:webui-dependencywith the same twodocumentaccesses (atWorkspacePanels.tsx:489and:534in their tree, because they edited that file).This PR adds zero direction, cycle, role or publication violations. Fixing the baseline's
documentaccess inWorkspacePanels.tsxis a separate change to a file this PR does not touch.The gitleaks failure was mine, and it is fixed
The first run of the Release audit failed with
leaks found: 1. It was this branch's commit, not somebody else's:webui-shortcuts.v1is a localStorage key name, but it is high-entropy enough (generic-api-keywants entropy > 3.5; this one is 3.84) to read as a credential to gitleaks'generic-api-keyrule. The fix is the one this repository already uses for exactly this class of false positive: a documented entry in.gitleaks.toml, next to the other "not a credential" entries:Re-run of the official
gitleaks v8.24.3(the version the release audit pins) against this branch's history and against the wholeoriginref set:no leaks found— and the release audit's three steps (history, source snapshot, built distribution) are green.Pre-existing failures on the baseline (not this PR)
pnpm test:webuion this branch: 12 failed / 3305 passed / 63 skipped. Every failure is present on the untouched baselinee2de9a1as well:No Chrome executable was found(browser-core-agent-actions×5,agent-transcript×1). This machine has no system Chrome; the CI runners do.webui-w0-css-structure(the suite cannot read the new@xterm/xterm/css/xterm.cssimport),browser-web-tab-toolbar,workspace-tab-strip,workspace-panel-state×2,webui-shell, and thecheck:webui-dependencygate's browser-globals case (WorkspacePanels.tsxreaches fordocumentdirectly). Running the same files on a cleanorigin/webuiworktree fails identically.Two assertions that said 快捷键 was still disabled were updated, because it no longer is:
packages/webui/test/unit/settings-modal.test.tsxandpackages/webui/test/browser/settings-account-tab.spec.mjs.Scope, and the boundary with #250
packages/webuiis touched, no new dependency, no i18n framework. The one file outsidepackages/webuiis.gitleaks.toml, which only gains an allowlist entry (above).webuie2de9a1, which does not contain feat(webui): let the settings page switch between Chinese and English #250, and this PR does not add, change or read any language pack: the page's strings are hard-coded Chinese, like the rest of the settings page on this baseline. The two PRs share exactly two files —settings-view.ts(the tab table, onedisabled: trueremoved) andSettingsModal.public.tsx(the page mount, the state and the storage write) — and both changes are mechanical to reconcile.Not verified here