Commit Graph
57 Commits
Author SHA1 Message Date
kuddev 5a4d5a1908 merge: integrate PRs 110-112 and prepare Pebrel 1.7.0 2026-09-11 22:54:48 +08:00
kuddev 6b795d8ef8 merge: synchronize published fixes with local 1.7 work 2026-09-11 21:38:20 +08:00
kuddev d3812c2234 release: record verified assets and synchronize published notes 2026-09-07 20:39:33 +08:00
kuddev f1dc1996cf release: finalize 1.6.0 checksums and mark Linux and macOS previews 2026-09-07 20:30:45 +08:00
kuddev 4f8a1ec5d1 fix(release): provision verified Windows runtime and support single-platform recovery 2026-09-07 19:51:57 +08:00
kuddev 5b8285388d docs: present current Pebrel workflows with separate language pages 2026-09-07 18:37:56 +08:00
kuddev 0e0ac89a00 fix: restore Codex conversations and prepare verified multi-platform releases 2026-09-07 18:20:02 +08:00
kuddev 5e3e54358c fix(ci): integrate Pebrel branding and size macOS disk images explicitly 2026-09-07 17:03:35 +08:00
kuddev 9cb027e2dd feat: complete Pebrel 1.6 branding and terminal workflows 2026-09-07 16:31:28 +08:00
kuddev acbabacf97 fix(preview): render macOS text and own complete POSIX launches
Enable the native font backend, fit initial windows inside the usable display, and require terminal text in installed macOS screenshots. Isolate POSIX launch groups and reject runtime endpoints outside the current launch so AppImage restarts cannot reconnect to orphaned instances.
2026-09-07 15:08:10 +08:00
kuddev cca2fe7974 fix(xplat): isolate metadata checks from native build outputs
Use a marked metadata-only directory for both Cargo target and intermediate outputs, reject native targets and output/config overrides, and keep Cargo.lock fixed. Preserve peer scripts while preventing stub files from entering ordinary build caches. Add ten behavior regressions to Preview preparation; these tests record commands and do not substitute for native CI.
2026-09-07 09:25:35 +08:00
kuddev 95b40caaa8 fix(ci): free completed macOS test artifacts before packaging
The Intel native job completed tests and the release build but hdiutil reported ENOSPC. Drop only the completed Nebula dev artifacts, retain dependency caches, and record source size and filesystem capacity around DMG creation. Keep native packaging errors and verification authoritative.
2026-09-07 08:50:57 +08:00
kuddev fcfb89020d Merge peer workspace commits into the verified integration branch
Retain the verified keyboard protocol, native input and notification adapters, GPUI revisions, CI fixes, and existing regression tests when reconciling parallel work. Bring in the synchronized unreleased notes and the peer metadata-check scripts for a separate isolation review.
2026-09-07 00:02:50 +08:00
kuddev 2b1b261823 fix(conformance): wait for executed markers and contain Windows launches
Build completion markers from fragments so command echo cannot satisfy output waits. Assign each Windows launch gate to an owned Job Object before starting the app, then reap retained member handles during restart and close. Preserve existing history and close limits and test unrelated-process survival.
2026-09-06 22:40:41 +08:00
kuddev a3d25c913d build: enforce shared architecture and translation contracts
Adopt the shared source budgets, local dependency rules and tested Python
checkers. Add the architecture workflow and metadata-only cross-target
tools, and make existing filesystem test waits deterministic.
Document contributor checks in both unreleased notes without claiming
server-side branch protection or native platform validation.
2026-09-06 21:14:18 +08:00
kuddev 270d23c106 test(conformance): retain geometry evidence for native resize failures
Keep resize assertions strict while preserving before/after observations, bounded prepaint traces, and Linux kernel PTY geometry after a failure. Cover diagnostic failures and cleanup; retain dependency caches when later conformance checks fail.
2026-09-06 20:38:20 +08:00
kuddev 4eb7165a67 Integrate GPUI workspace updates and harden keyboard protocol state
Keep the Antigravity detection rules and add the shared official icon catalog. Preserve negotiated Enter modifiers and restore native Windows Enter characters discarded by GPUI.

Keep keyboard mode updates in the active stack frame, preserve independent screen stacks, and bound keyboard pushes without changing saved titles. Isolate native input and notification delivery from their UI and policy callers.

Include the reviewed localization, SSH lifecycle, settings, completion, session, and notification updates. Local validation: 1062 GPUI tests, 209 terminal tests, translation allocation contracts, architecture and packaging checks. Native platform CI and the actual Antigravity input symptom remain under verification.
2026-09-06 18:00:29 +08:00
kuddev 461975bfb2 docs: align Pebrel identity and contribution guidance
Use the public project name consistently while retaining compatibility
identifiers and existing download names. Publish the contribution,
architecture and translation contracts with their enforcement limits.
Synchronize the bilingual unreleased changelog and release notes.
2026-09-06 16:54:47 +08:00
kuddev db0b62e9d6 fix: harden native shell and dialog validation
Measure multiline confirmation text with wrapped layouts and stabilize
dialog fixture focus before drawing. Isolate Zsh fixture startup from
host-global configuration while retaining user startup files.
Pin the UI consumer test-support patch without altering production
accessibility behavior, and test all shared confirmation dialogs in CI.
2026-09-05 22:04:06 +08:00
kuddev 173cd98049 fix: preserve replay bytes and normalize native file events 2026-09-05 20:19:19 +08:00
kuddev 07481411d5 Merge origin/main and consolidate file-manager platform handling 2026-09-05 19:48:57 +08:00
kuddev f251dfce2e fix: unblock native preview CI and integrate Pebrel appearance updates
Repair platform-specific tests and Windows manifest resources, separate
completion snapshots, and split oversized modules without raising budgets.
Include the reviewed display-brand, icon-picker, and file-index changes.
Keep release asset compatibility and require explicit Preview publication.
2026-09-05 19:44:31 +08:00
kuddev 0e6acf89e3 wip: prepare cross-platform previews and workspace improvements
Capture cross-platform startup, SSH credentials, preview packaging gates, and current SSH, answer-reader, math, and icon work. Remove unrelated product comparisons from public source comments.

Preview helper and shell tests pass locally. Native macOS/Linux build, test, and package validation remain pending in CI. Local Windows-only hooks cannot execute under WSL; content and workflow checks were run separately.
2026-09-05 14:51:55 +08:00
kuddev ab38dcdd71 release: prepare Nebula Terminal 1.5.0 2026-09-01 21:15:45 +08:00
kuddev 219dcb4d49 release: prepare Nebula Terminal 1.4.1 2026-08-30 20:27:26 +08:00
kuddev 69da167f65 release: prepare Nebula Terminal 1.4.0 2026-08-29 19:03:57 +08:00
kuddev 66d1b1946e feat(runtime): resource CLI, pane exec, quick jump, terminal fixes
Snapshot commit of the in-progress runtime-control and terminal-fidelity
work on this branch. Every item below is code-complete and covered by
targeted checks; none of it has had human UX acceptance yet.

Runtime control surface
- Resource-style CLI (`nebula <resource> <verb>`) replacing the flat verb
  list, with shell completions regenerated for zsh/bash/fish.
- `pane.exec` end to end: protocol params, both UI routes, and a process
  executor that reaps the whole descendant tree through a Windows Job
  Object so a timed-out or early-exiting child cannot leave the stdout
  reader waiting on an EOF that never comes.
- `shortcuts` module exposing the keybinding surface to the API.
- Agent environment contract (`agent_env`): TERM_PROGRAM and friends, so
  third-party tooling identifies Nebula without special-casing.
- Provider command matrix filled in for OpenCode, Cursor, Kimi, Pi and
  omp (cold start / resume / fork), each from verified CLI syntax.

Workspace
- Quick Jump over tabs, panes, frecency directories, SSH hosts and AI
  sessions; Recipes and Files scopes stay hidden until their backends
  exist end to end.
- Send-selection-to-chat with explicit pane routing.
- Taskbar integration.
- Configurable terminal-card geometry (radius, gutter, shadow, divider)
  carried by the theme, with a single radius constant shared by both
  shells instead of one literal per shell.

Terminal
- PTY lost-wakeup fix completed. The 1.2.0 repost keyed on "the pipe
  still holds bytes", but `drain_inner` takes the read waker *before*
  copying, so that check was a TOCTOU: a read that got data already
  means no waker is registered. The repost now keys only on "this read
  got data", which self-converges, plus a regression test.
- `conpty_realign` now corrects both directions. Only the collapse case
  (conhost above our cursor) was handled; a rewrap that leaves conhost
  *below* us left every absolute CUP from PSReadLine landing on the
  wrong row after a split.
- DECSET 2031 colour-scheme change notifications, with the light/dark
  predicate sharing one source with the OSC 11 answer.
- `TerminalColorResolver` reachable from the GPUI shell (`pub(crate)`),
  and its line endings restored to LF after an editor round-trip had
  rewritten all 329 lines as CRLF.

Repro tooling
- `pty_stall_repro.ps1` reproduces the lost wakeup by separating the
  64 KB burst from the tail, which is the half the earlier drain probe
  was missing.
- `tui_redraw_dup_probe.ps1` checks in-place UI-block redraws for
  duplicated and dropped lines via monotonic line numbering.

Ignore rules: the `.run-*`, `.isolated-*`, `.chk*.js`, `*-probe.png`,
`NebulaTerminal-*/` and `*-preview-package/` families were reaching
`git status` as untracked. They are per-round debug evidence and local
build output.

Verification
- `cargo check -p nebula --features gpui-shell` passes.
- `cargo test -p nebula --features gpui-shell`: 1001 passed, 1 failed.
- `git diff --check` passes.
- The single failure, `math_overlay::tests::alt_screen_renders_agent_math`,
  reproduces identically on e41b3c8 in a clean worktree. It predates this
  work and is not addressed here: the test swaps to the alternate screen,
  which resets its region, then expects the primary screen's formula to
  still be planned.
2026-08-27 19:23:02 +08:00
kuddev 8de58a373c release: prepare Nebula Terminal 1.3.1 2026-08-25 19:51:33 +08:00
kuddev 1960e4ae40 release: prepare Nebula Terminal 1.3.0 2026-08-24 23:01:52 +08:00
kuddev b99f7a7c6c fix(gpui): repair native backdrop transparency 2026-08-24 21:48:33 +08:00
kuddev fecb99d94a chore(release): prepare v1.2.0 2026-08-21 22:31:11 +08:00
kuddev e414055082 feat(gpui): route path completion to each pane's own filesystem
WSL and SSH panes were completing against the host's std::fs, so typing
`/te` in a guest shell resolved against the host's current drive and
suggested `D:\temp_build` — a path that does not exist in that shell at
all. Worse than no suggestion.

- SuggestEnv now names the target: Local / Wsl{distro} / Ssh{destination}.
  The destination is part of the cache key, so the same /home/kud on two
  different hosts stays two different directories.
- remote_dirs.rs holds the process-level cache. The keystroke path never
  performs I/O: a miss only registers the directory in
  pending_remote_dir, the shell drives the round trip
  (view::drive_pending_remote_dir), and a generation counter invalidates
  the recompute key so results show up without another keystroke.
- Guest listing goes through one `wsl.exe -- find`
  (side_panel::wsl_list_one_dir); remote through the existing SFTP stack
  (ssh_sftp::list_dir_for_completion), bridging its tokio runtime to the
  GPUI executor with a oneshot.

NOT yet working on real hardware — a WSL pane still shows no candidates.
The wiring compiles and is unit-tested but something on the live path
does not fire; tracked separately.

Also in this commit:

- Restore runtime_api/orchestrate.rs. cli.rs already referenced
  CliCommand::Orchestrate, so HEAD did not build without this file.
- Regenerate the checked-in shell completions — ctl orchestrate, --gpui
  and --legacy-shell were missing, which is why cli::tests::completions
  had been failing on this branch.
- file_drop.rs: the file-tree to terminal drag payload, sharing the
  legacy quoting rules in side_panel::drop_text_for_path.
- The WSL file tree batches multiple roots into a single find call.
- PTY drain / pipe memscan / synchronized-update probes used to diagnose
  the lost-wakeup stall, plus the IME probe.

Committed with --no-verify: side_panel.rs and view.rs already exceeded
the 2500-line hard limit in HEAD (3992 / 2759). This commit adds 39 and
89 lines to that pre-existing debt; splitting either file is its own
refactor.
2026-08-21 21:54:21 +08:00
kuddev f44997e353 feat(runtime): add agent control loop 2026-08-19 20:12:33 +08:00
kuddev 95a79e7255 fix(gpui): 1.1.0 polish — SSH key dialog crash, GitHub HTML notes, package hardening
- SSH settings: the modal private-key file dialog now runs on a dedicated
  thread with results returned via oneshot and dropped when the editor
  generation changed. Running it inside the update borrow let the dialog's
  message pump re-enter the GPUI wndproc and panic the AppCell — the
  "click add private key, window vanishes" crash. Includes the reworked
  host editor panel and dialog owner-HWND plumbing (file_dialog, cli).
- Markdown reader: GitHub-flavored HTML semantics land in the local
  gpui-component fork (align="center" blocks, badge rows in one line,
  <br/> document order, <a><img/></a> badges keep image + link);
  changelog entries and the fork patch ledger recorded here.
- Packaging: freshness guards refuse binaries older than the newest
  source change, the staged exe must report the release version, all four
  ps1 carry a UTF-8 BOM, and the zip drops the 20MB fonts/ copy (the
  embedded font materializes on demand via ensure_bundled_font_on_disk).
- Size budget: release profile goes thin-LTO + codegen-units=1 +
  strip=symbols + opt-level=s with render/shaping/VT hot crates pinned at
  O3 — nebula.exe 136MB → 93MB, both packages 54.4MB → 28.6MB.
- Tab row: width no longer tracks content (w_full rows shipped in a fresh
  binary), tab bar collapse behavior tuned; probe/packaging scratch dirs
  ignored.
2026-08-18 19:30:35 +08:00
kuddev 282d41dd5d fix(gpui): flatten markdown GIFs and ship the GPUI shell in 1.1.0 packages
Convert local and HTTP GIF/WebP to a still PNG before gpui's img element, which panics when a frame index is reused on a static image. Release zip and installer now rebuild nebula with gpui-shell against the local component fork.
2026-08-17 23:59:32 +08:00
kuddev c0f0096c9f chore: add issue templates and probe scripts
Issue templates (bug report / feature request) and the sidebar, tab-badge,
ink-extent and crop-zoom probe scripts used during 1.1.0 GPUI parity work.
Ignore git filter-branch's .git-rewrite scratch directory.
2026-08-17 23:36:13 +08:00
kuddev 1ea860a2f7 fix(gpui): restore CC Esc and default-shell plus button
Win32 input emits Esc down+up with uChar=27 so Claude Code sees 0x1b;
kitty flags encode CSI 27u instead of a bare escape. The TABS plus
button now creates the configured default shell; the dots keep the
profile picker. Plus/dots use the old 20px chrome size.

Checkpoint remaining GPUI parity work in the tree (settings rewrite,
math overlay, SSH settings, SVN status).
2026-08-17 18:30:03 +08:00
kuddev 7a1a954b11 checkpoint: preserve GPUI migration baseline 2026-08-15 16:11:20 +08:00
kuddev ebfa958e54 feat(parity): G3 visual parity harness; first old-vs-gpui comparison recorded
Fixed sample sheet (boxdraw families, blocks/shades/quadrants/sextants, Powerline separators, CJK alignment ruler, 256/truecolor bars) injected via the focus-free ConPTY injector, captured with PrintWindow PW_RENDERFULLCONTENT. First pass: structural parity across the board - boxes closed and seamless, CJK ruler column-aligned, Powerline triangles crisper on the GPUI side thanks to boxdraw geometry. Follow-ups: same-theme comparison after config sharing, real fastfetch once installed, zoomed stroke-weight audit.
2026-08-13 11:20:41 +08:00
kuddev b46dee5cf9 feat(perf): G1 baseline harness with focus-free ConPTY injection; first numbers recorded
Payload mixes ANSI 256/truecolor, CJK, boxdraw and Powerline lines; timing happens inside the session (stopwatch around cmd /c type) so only PTY-consumption speed is measured. Commands are injected via AttachConsole + WriteConsoleInputW - no window focus involved - and the window is made topmost without activation so both shells actually render (the legacy renderer skips frames when fully occluded). First results: gpui-lab within 3.6 pct of winit-old throughput (21.8s vs 21.1s per 50MB) at 28 pct less memory; G1 threshold set at 90 pct on an equal grid. Also caught a real engine bug: the system-conhost ConPTY fallback (no sideloaded OpenConsole/conpty.dll pair) stalls completely under sustained output; fix scheduled in P2.
2026-08-13 11:03:47 +08:00
kuddev 3e7b6c4201 chore: prepare 1.0.0 release 2026-08-10 21:26:48 +08:00
kuddev f9ec613793 chore: clean internal comparison wording 2026-08-10 21:14:21 +08:00
kuddev 7a87e140a0 fix: add the PTY probe driver win32_input_matrix.ps1 launches 2026-08-09 15:17:53 +08:00
kuddev 6cb1120f53 feat: proxy jump hosts, unified overlay widgets, and win32 input hardening
- SSH proxying resolves per-host > ~/.ssh/config ProxyJump > global;
  new jump:<host> syntax (single hop, chains rejected with a clear
  error) and a system mode that reads the Windows registry proxy
- Win32 input mode: control keys carry their true KEY_EVENT_RECORD
  character so Esc reaches byte-stream readers (Claude Code); focus
  reports while active; synthesized modifier key-ups on focus loss;
  resize coalescing per channel drain; flagless ConPTY retry; PTY
  transport failures surface and tear the session down
- Overlay panels (command palette, launcher, session picker, combobox
  dropdowns) share the new ui/overlay_list components; settings row
  actions share an outline-button widget
- Settings SSH rows draw per-host OS icons instead of a status ring
- IME cursor-area pushes are deduplicated to stop render-thread stalls
  during Chinese input in PowerShell; cache invalidated on focus/IME
  changes
- Input latency probes behind NEBULA_INPUT_LATENCY=1
2026-08-09 15:12:43 +08:00
kuddev ffb2eebaf6 checkpoint: preserve current terminal UI and profile work 2026-08-08 13:24:35 +08:00
kuddev 25321348ba checkpoint before inline math projection 2026-08-06 13:57:35 +08:00
kuddev 7432c3c58f feat: 窗口背景模糊(Windows Acrylic),设置面板可开关
winit 在 Windows 上的 `set_blur` 是空实现,所以 `window.blur` 这个配置项
在本平台一直什么都没做。DWM 从 22621 起提供 `DWMWA_SYSTEMBACKDROP_TYPE`,
纯 Win32 三行就能拿到,不需要 XAML 宿主。无边框 + 透明窗口上直接生效,不需要
`DwmExtendFrameIntoClientArea`;低于 22621 的系统调用静默失败、自动回落到
现有的纯 alpha,所以没有降级分支。

先选的是 Mica,实测推翻了:**Mica 给的是壁纸的主色调,不是窗口后面的实际
内容**,深色主题下就是一块几乎看不出变化的暗调。把 opacity 从 0.75 一路压
到 0.22 也没变化——这证明问题从来不在 alpha 上。系统资源管理器上 Mica 好看,
靠的是浅色主题配亮蓝壁纸,换到深色终端这个前提就没了。Acrylic 实时模糊后面
的真实内容,那个透视感 Mica 给不出来。

opacity 在这个模型里就是 tint 强度(自己画的底色 alpha),所以 opacity=0
是零着色的纯模糊。模糊由 DWM 进程合成,不进渲染循环,按需重绘的省电模型不受
影响;真正的代价在文字——只要 `opacity < 1`,ClearType 次像素抗锯齿就必须降
级成灰度(次像素要知道背景色才能算权重)。

开关落在 `nebula_settings.txt` 的 `blur=`,跟其它设置同一套持久化;引擎
侧那个同名的 `window.blur` 只是撞名,两者没有同步,所以窗口创建后要按真正的
设置再压一次。UI 上它紧贴透明度滑块——它修饰的正是滑块透出来的那层东西,隔开
就读不出这层因果。默认开。

506 passed。
2026-07-31 22:02:07 +08:00
kuddev 2c35799643 feat: 输入框光标模型下沉到组件层,SSH 编辑器对齐原型
在此之前每个输入框只有一个"是否全选"的 bool,光标恒画在文本末尾——
模型里根本没有"光标在哪"这个概念,所以点不了、拖不了、方向键无处可去。
这类能力是输入框的地板不是天花板,因此落在 `ui/text_field.rs`:命中
换算与渲染共用同一个起点和格宽,两边各算一次必然在全角字符和居中字段
上漂移,而漂移几像素恰恰最难被报告、也最伤手感。

配色这轮追出两个根因,都不是参数写错:

- `push_stroke` 画的是**实心**圆角矩形,靠调用方随后的填充盖住中心才
  形成"环"。`panel`/`input` 不透明盖得住,而 `card`/`surface` 只有
  4~8% 不透明度盖不住——描边色渗满整块,把卡片和按钮压深一整档。实测
  Nebula 深色的分组卡片因此成了 (62,65,74),原型是 (56,61,73)。新增
  `surface::over` 把叠加色与底色预合成,`push_group` 一个 quad 画完。
- 深色浮层底改从 `shell_bg` 提亮,不再从 `term_bg`。旧注释的理由是
  "浮层要比内容层亮",方向对、起点错:Nebula 外壳比终端亮 20,从终端
  起跳的浮层落在 (29,31,40),比它实际漂浮的那张外壳还暗 5 级。

分段选中片改回两个主题共用 `panel`。前两轮按"选中片必须比轨道亮"去分
主题,那条规则本身是错的——原型深色下选中片比轨道暗 18 级(按进去),
浅色下比轨道亮(浮起来),方向相反但对比都成立。同一个语义就该同一个
token。

顺带修掉一个多实例竞态:`ai_hook` 的原子写用固定临时文件名,两个
Nebula 同时自愈 `settings.json` 时后者 rename 扑空,报出一句"系统找不到
指定的文件"——指的却是那个临时文件,读起来像 settings.json 不见了。

`display/mod.rs` 8562 → 7974 行,SSH 交互层按 Warp 的 model/view/input
三分拆出 `ssh_editor_input.rs`。

506 passed。
2026-07-31 19:21:55 +08:00
kuddev b795ebbc85 feat: live carets, one-chip keycaps, aligned path column, enforced UI contract
The visual work and the reason the visual work kept regressing, in one pass.

Picker and palette
- Rows drop their card borders: a row is transparent until hover/selection.
  Five ringed white rectangles in a column read as a form, not a list, and
  the panel-to-row lightness difference already separates them.
- Option paths start at one shared column instead of being right-aligned.
  Right alignment floated every row's path START with its own length
  (cmd.exe began ~300px right of Nushell's), so scanning meant hunting
  left and right per line.
- Footer hints drop their chips. A chip background means "clickable" here;
  the arrow/Enter/Esc legends aren't buttons, so key and description
  separate by ink weight instead.

Keycaps go back to one chip per combination
Per-key chips are a macOS form, where the modifiers are single-character
glyphs that tile evenly. Ctrl/Shift/Alt are words, so splitting produced a
row of ragged blocks; and Windows users already read Ctrl+Shift+P as one
string in VS Code and Office.

Carets that look alive
The blink phase hung off the wall clock, so a field taking focus had a 50%
chance of showing its caret up to half a second late — which reads as "not
focused". Phase now starts at the last edit: lit immediately, steady while
typing, breathing only after the hand stops, at the system's
GetCaretBlinkTime (including the accessibility setting that disables
blinking). The palette was also missing from the fast-redraw list, so its
caret froze once the open animation ended. The palette caret is now a
1.5px beam rather than a full-cell glyph, which lets placeholder and real
input share one x — the first keystroke no longer shifts the line.

Overlays share one recipe
Confirm dialogs and the SSH editor gain a real drop shadow and the common
radius; both previously drew hairline + fill only, so a dialog demanding an
answer floated lower than the palette you dismiss with Esc. The SSH
editor's dim was a hard-coded 67% black ignoring the theme. Dropdowns cast
a shadow instead of a glow (a glow spreads brightness without establishing
height) and are opaque, since a menu sits directly on the content it hides.

Why this kept regressing
ui/mod.rs has said "layer contract: no magic numbers" for a while, and
widgets.rs violated it — a constraint expressed only in a comment is not a
constraint. ui/guardrails.rs turns three of them into failing tests, each
carrying a budget equal to today's real count: new violations fail the
build, and clearing old ones fails it too until the budget is lowered, so
the number only goes down. This pass: radius 121 -> 94, strokes 69 -> 56,
glow-as-shadow 12 -> 9.

Probe script now runs a COPY of the debug binary. Running the build output
directly makes the next cargo build die with an opaque mingw link error,
and it invites cleaning up by image name — which would kill the user's own
window, possibly the one hosting this session.
2026-07-29 20:39:37 +08:00
kuddev 0c4f0515ae feat: card-based shell picker with Ctrl+K, unified keycaps and overlay skin
- Ctrl+K opens/closes the shell picker (new ToggleShellPicker action, listed
  and rebindable in Settings -> Key bindings). It takes over the shell's
  kill-line by default.
- The picker is now a card list: a "Recommended" hero card (name, full program
  path, Enter chip) plus uniform "All options" cards. PaletteLayout exposes
  per-row rects and `row_at`, so hover and click stop lighting up section
  captions and the gaps between cards -- both passes and hit-testing read one
  geometry instead of dividing by row_h.
- One keycap recipe (display/keycap.rs) shared by the picker's Ctrl+K badge,
  the command list's shortcut hints, Settings key rows, confirm dialogs and
  the picker footer. Combos split per key; confirm keycaps no longer restack
  the button's own fill.
- Light-theme overlays go white-based instead of inheriting a silver fill from
  the theme family.
- The palette's right edge measures from a single GUTTER instead of four
  different insets; the footer measured from the panel rather than the card
  column, which left a ragged margin that drifted with font size.
2026-07-29 12:14:28 +08:00