The hover dashed outline painted at page level from the unrotated
doc-space bounds, so a rotated frame (and any element inside one)
showed an axis-aligned outline detached from its rendered geometry.
Accumulate the root-to-node flip/rotation chain during the scene
paint walk and replay it around the dashed rect so the outline lands
exactly where the node renders. Hit-testing already handled ancestor
rotation, so trigger area and visual now agree.
`with_decorations(false)` strips the native frame entirely on Windows,
so DWM painted the borderless window as a flat rectangle with sharp
corners instead of the Windows 11 look. Opt back into
`CornerPreference::Round` and a hairline border matching the dark
chrome via casement's `WindowAttributesExtWindows`.
Introduce the ZSeven-W product family (zode, agent-rs, jian, noema)
with a new Ecosystem section across all 15 locales, and reframe jian
from 'widget/render/event toolkit' to 'GPU-Skia UI framework' in the
Tech Stack table, Ecosystem table, and Project Structure tree.
Chrome text rendered blurry on Retina: all chrome/canvas text goes
through the offscreen 2D-canvas raster path (drawBrowserText), which
rasterized glyphs at CSS (1x) resolution. Those bitmaps are then drawn
onto the CanvasKit surface while a scale(dpr, dpr) transform is active,
magnifying them dpr-x — half-resolution on 2x displays.
Supersample the offscreen text canvas by the device pixel ratio and
composite it back at 1/dpr so glyphs land at native device resolution.
Thread the real dpr from Rust (CanvasKitBackend::new + resize_for_display)
into the bridge via a new setDpr method; cache key includes dpr and
stale bitmaps are dropped on dpr change.
Advance past c8fb619b (head/tail grep cap that could hide a match in a
long line) to origin/main, which centers the per-line cap on the match
plus repairs feature gates/advisories.
Advance the submodule past the pre-rebase 876c890 (no longer on any
remote branch) to origin/main, which carries the ripgrep/compression
series rebased onto main plus the grep per-line output cap.
- rquickjs 0.9->0.12 (op-mcp): 0.12 ships aarch64-pc-windows-msvc bindings
(0.9 doesn't), so the native-only script feature builds on windows-arm64
with full parity (as Zode's zode-core already uses 0.12). Clean drop-in;
25 script_runner tests pass. Reverts the earlier per-target gating.
- Workspace MSRV 1.85->1.87 (rquickjs 0.12's floor; pinned toolchain is 1.94).
- agent_settings switch test: assert theme.input (the token the off-track
paints) now the light theme gives input its own value distinct from border.
- Call blur_input when agent settings panel opens (shortcut + click)
on both native and web hosts, so chat.focused becomes false.
- Guard agent_settings focus check with agent_settings_open in
input_active() to prevent stale focus from claiming keyboard.
- Reorder handle_cmd_paste to check non-chat inputs first, with an
additional !chat.focused guard.
Read `~/.zode/config.json` on startup (native/daemon) and merge every
Zode `(provider, model)` pair into agent_settings.builtin_agents as a
BuiltinAgentConfig, so providers already configured in the Zode CLI show
up as OpenPencil custom models without re-entering keys. Anthropic vs
OpenAI-compat is chosen by the provider `type`; one custom model per
model id (provider name qualified by model when a provider has several).
Best-effort + idempotent: missing/malformed file is a silent no-op, and
add_builtin_agent_config backend-dedupes so re-running each launch adds
nothing new. Imported agents are tracked in imported_agent_ids and
excluded from settings.json persistence — Zode's config stays the single
source of truth and its API keys are never silently duplicated onto a
second on-disk location (they're re-imported every launch).