Commit graph

2582 commits

Author SHA1 Message Date
Fini e29ea4229c fix(agent): backfill generated screen interactions 2026-07-30 08:59:39 +08:00
Fini ee44d9b2c0 fix(agent): default ACP agents to basic capability tier 2026-07-30 08:57:17 +08:00
Fini 6932081068 feat(agent): present custom ACP agents as local integrations 2026-07-30 08:57:16 +08:00
Fini ddac26e23a fix(agent): make ACP connection probes generation-safe 2026-07-30 08:57:15 +08:00
Fini 9b01720850 feat(agent): refresh cli model catalogs on picker open 2026-07-30 08:57:14 +08:00
Fini bcce4e7071 fix(panels): fix color variable picker interaction routing 2026-07-30 08:57:13 +08:00
Kayshen-X 76af87930f fix(desktop): show update check status 2026-07-30 02:14:54 +08:00
Kayshen-X 9a09d3cdbe fix(desktop): remove native batch export item 2026-07-30 01:52:44 +08:00
Kayshen-X 7f953dfdf7 fix(host): gate login shell probe on windows 2026-07-30 00:47:21 +08:00
Kayshen-X 7c4d715005 test(relay): pump delayed reauth controls 2026-07-30 00:10:09 +08:00
Kayshen-X 7c2ce58aa3 test(collab): gate unix key store helpers 2026-07-29 23:51:50 +08:00
Kayshen-X d0d0e5b866 test(editor): isolate selection overlay indicators 2026-07-29 23:14:25 +08:00
Kayshen-X 9ac8428799 fix(locator): isolate unix hsm support 2026-07-29 23:14:15 +08:00
Kayshen-X 4a95bd374c test(collab): await rebased smoke acknowledgement 2026-07-29 23:12:27 +08:00
Kayshen-X 0324a61a83 test(collab): await final smoke acknowledgement 2026-07-29 22:55:17 +08:00
Kayshen-X af812daa77 chore(deps): update anyhow to 1.0.103 2026-07-29 22:39:41 +08:00
Kayshen-X bc9993b189 fix(relay): gate development-only host import 2026-07-29 22:39:32 +08:00
Kayshen-X abfebfea87 test(collab): wait for retired worker slot 2026-07-29 22:39:21 +08:00
Kayshen-X c766338fef fix(web): preserve shortcut input ownership 2026-07-29 22:39:08 +08:00
Kayshen-X dc92e63019 fix(auth): isolate bundled runtime symbol 2026-07-29 22:38:54 +08:00
Kayshen-X 91fa60898e fix(editor): center top bar title group 2026-07-29 22:35:03 +08:00
Kayshen-X 2b713635f5 feat(collab): ship public relay collaboration 2026-07-29 21:42:33 +08:00
Kayshen-X da2c90fe9e build(collab): enable local ABI v2 auth debugging 2026-07-29 16:46:03 +08:00
Kayshen-X d17c26ab39 style(editor): refine account settings card 2026-07-29 16:13:41 +08:00
Kayshen-X 59cc8f93c2 feat(editor): show authenticated account username 2026-07-29 15:55:35 +08:00
Kayshen-X f1ae6002ec feat(editor): show authenticated profile avatars 2026-07-29 15:20:34 +08:00
Kayshen-X 435f0b4091 fix(desktop): terminate disconnected git pull jobs 2026-07-29 00:13:57 +08:00
Kayshen-X 30b312f32f refactor(agent): split oversized service modules 2026-07-29 00:13:57 +08:00
Kayshen-X 2e9de6d2a2 fix(ci): update collaboration security gate 2026-07-29 00:06:58 +08:00
Kayshen-X 0bd9947310 feat(collab): add authenticated p2p collaboration 2026-07-29 00:06:58 +08:00
leinaldo 42688d4081
fix(agent): update winget package name from GitHub.CopilotCLI to GitHub.Copilot (#193) 2026-07-29 00:05:25 +08:00
leinaldo 3e1fc81d7a
fix(desktop): prefer .exe/.cmd/.bat over extensionless npm shims on Windows (#191) 2026-07-28 23:52:33 +08:00
Fini 8102ca506b docs(ai): teach overlay-only layout:none and concentric ring authoring
Two schema-skill clarifications for shapes models keep getting wrong:
layout:none is overlay stacking only — a row or column of cards belongs
to horizontal/vertical (one corpus document authored a carousel as a
none frame and depended on the old engine bug to display) — and a ring's
track and progress arc are never flex siblings but same-origin layers in
one fixed wrapper.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:14:11 +08:00
Fini 093d7ed094 fix(agent): rerun gutter dedupe after content rails install their padding
strip_wrapper_double_inset has always known how to strip a transparent
wrapper's duplicate side padding, but it runs before the mobile rail
pass installs the rail gutter it deduplicates against; the later rerun
used the single-child collapse whose contract cannot see a wrapper with
siblings. A padded sheet wrapper inside a freshly railed section thus
kept a second 24px inset and its card measured 279 against 327 rail
siblings. The dedupe now reruns after rail installation, and gutter
ownership is inherited along transparent chains — resetting at any
painting surface — so nested wrappers converge on one gutter owner
instead of reproducing the bug one level deeper. The rail skill's
wrapper rule is sharpened to name the shape models actually emit.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:13:47 +08:00
Fini 9e417c238a fix(agent): exempt image-backed cards from the deck opacity repair
fix_deck_front_card_transparency saw a photo card's transparent content
layer over its alpha gradient scrim as a deck front card leaking a
painted sibling, and lidded it with an opaque surface fill — hiding the
photo and the scrim the model had deliberately composed (three theme
cards in one measured document). An image sibling anywhere in the stack
now marks the see-through front as the composition itself, the same
reasoning as the existing ellipse exemption.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:13:31 +08:00
Fini fd671651a1 feat(agent): flag bottom-flush screens and teach bottom breathing room
A detail screen without a bottom tab bar that ends flush against the
device edge reads as clipped, and the corpus had no rule for it. The
geometry diagnostics now echo a mobile-bottom-flush fact when a mobile
root's lowest resolved child edge sits within 12px of the root bottom
and the trailing child is not nav-shaped — nav detection reads the
authored role or pure row geometry (full-width band in the nav height
range with evenly split targets), never node names. Repair stays with
the model: whether the fix is padding or a spacer is an intent call.
The mobile skill gains the matching breathing-room rule.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:13:13 +08:00
Fini b74c94d2da fix(ai): budget runtime-augmented planning skills and raise the phase ceiling
The per-skill budget guard measures skill files as they sit on disk, but
style-guide-selector grows at resolve time when the available-style-guide
catalog replaces its placeholder — 819 tokens against a 500 budget, so
the catalog tail was silently cut from every planning prompt. Worse, the
three base planning skills alone already exceeded the 4000-token phase
ceiling, which made the only domain skill of the phase undeliverable on
any prompt, with no warning anywhere. The skill budget now covers its
worst-case injection, the planning ceiling rises to 6000, and three new
guards keep the hole shut: augmented skills must fit their own budget,
every augmentation placeholder must declare a worst case, and the end-to-
end resolver must deliver the full phase without drops or truncation.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:12:57 +08:00
Fini 2ca873346c fix(mcp): default omitted effect fields instead of dropping the whole node
ShadowBody deserializes with five required fields, so a model omitting
just spread lost the entire node — and every child line that named it as
a parent cascaded into 'Insert parent not found' (a measured 19-line,
whole-card silent loss). Effects are now normalized before the strict
parse: identity defaults for offsets/blur/spread, alias folding for the
common synonyms, a lone effect object wrapped into the array, numeric
strings coerced, and glow/drop-shadow spellings canonicalized. Truly
unknown effect kinds still fail the node — inventing an effect the model
did not ask for would be worse than dropping one. The modify path's
parser reuses the same normalizer so the two lanes cannot drift.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:12:36 +08:00
Fini 3571d70a53 fix(agent): extract ring fragments from flex rows into a concentric wrapper
Models keep authoring a progress ring's track and arc as flex siblings,
so the layout engine lays the two circles out side by side with the
percentage label floating off the edge. radial_repair already converts
a parent that IS the ring's own wrapper, and correctly declines padded
general-purpose containers — which was exactly the hole the defect kept
returning through. This pass closes it from the other side: the arcs are
extracted into a fixed-size layout:none wrapper that takes the first
arc's slot, the parent keeps its layout and other children, and a lone
percent-content text sibling is adopted as the centred label. The lane
predicate is shared with radial_repair so exactly one pass owns any
given ring, and the same detector feeds geometry diagnostics so the loop
sees the violation it can no longer ship.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:12:19 +08:00
Fini 97b8f089a2 fix(canvas): adopt stack semantics for layout:none and retire the flow bandaid
Bump jian for the single-cell stack compilation of layout:none frames.
The loader's repair_inferred_horizontal_container previously rearranged
explicit layout:none children into a row to paper over the engine gap;
with the engine fixed that bandaid would shove correctly stacked layers
out of the frame, so it now only fires for documents that omit the
layout field entirely. Corpus-wide differential over 184 documents:
60 of 240k node rects change, all overlay repairs (hero scrims and
avatars regaining their parent box), none collapsing to zero.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:11:59 +08:00
Fini 1bf5f9b8cc fix(renderer): register pan-cache strips to the layer anchor and refresh on decode
Two independent defects in the pan bitmap cache showed as misregistered
bands while dragging at high zoom and photos stuck on their blur-up
placeholders. Strips repainted during an in-place scroll used the live
viewport pan while the layer stays anchored at the snapped cache pan, so
every threshold crossing baked a band at twice the residual; the restore
rebase also vacated a margin strip nothing ever repainted. And a decode
landing on the worker mutates no editor state, so a sharp layer kept
serving stale placeholder pixels forever. Strips now paint against the
cache anchor, vacated margins join the progressive restore, and a raster
generation stamp reopens the restore when new pixels install.

Claude-Session: https://claude.ai/code/session_01FqKQqNj8exYwopGDpYUU7x
2026-07-28 22:11:36 +08:00
Fini 878a393517 fix(ci): satisfy the fmt gate and the version-literal fixture rule
The rebase port left a hand-wrapped import list rustfmt disagrees
with, and two restored-comment references to the current product
version trip the version-sync fixture rule — reflow the imports and
reword the comments without the literal.
2026-07-28 00:56:22 +08:00
Fini 9354d786cb fix(web): import the scroll helper the popover wheel path uses
Leftover from porting the color-variable popover onto the unified
scroll tier: the web host's popup interception references
scroll_by_max, which only default-feature builds resolved via an
unrelated re-export — import it directly so the canvaskit build
compiles too.
2026-07-28 00:49:57 +08:00
Fini 225c12d1ce feat(i18n): complete locale coverage for batch export and match-ratio keys
The catalog integrity gate requires every locale to carry exactly the
English key set — the eight keys added for batch frame export and the
image-ratio action existed only in en / zh-CN / zh-TW. Translate them
across the remaining twelve locales (placeholders preserved) and bump
the intentional catalog size.
2026-07-28 00:49:57 +08:00
Fini d539576f83 fix(editor): route escape through the color-variable popup on native too
The popover's escape layer was applied to the web host but dropped
from the native ladder while porting across the unified
keyboard_escape split — close the popup (and reset its scroll) one
layer before the fill-type dropdown, matching web. Also rustfmt
normalization of the rebase port sites.
2026-07-28 00:36:35 +08:00
Fini b567a6a027 docs: refresh image-fill popover description and add the gl-host test invariant
The stale 'Image — fill row' line made the crop/adjust feature read
as unimplemented; describe the actual popover. Record that
op-host-native tests need --features gl-host — the default run
compiles out widget_host entirely and covers none of it.
2026-07-28 00:29:39 +08:00
Fini 25a38f4c00 fix(ai): point the latin line-height tiers at the cjk rules
text-rules and cjk-typography co-load on every Chinese request with
contradictory lineHeight tiers and no cross-reference — the model
picks one silently, and a wrong pick renders cramped headings rather
than an error. Mark the tiers latin-only and route CJK text to the
cjk-typography values, keeping latin digits and labels inside a CJK
design on the latin tiers.
2026-07-28 00:29:39 +08:00
Fini cb8a2624ba fix(editor): align the font picker's wheel direction with every other list
The inspector's font dropdown scrolled against the wheel: it added
delta to its offset while the settings-panel font picker — same
widget, same scroll field, same file — and a dozen other scroll
surfaces all subtract. Flip it on both hosts and pin the convention
with direction tests that drive the real wheel entry point and
require the rail popups to move the same way as the panel behind
them. Also gate agent_indicator_test_support behind the same cfg as
its only consumers inside gl-host'd widget_host, so a default-feature
clippy run is clean without blanket allows.
2026-07-28 00:29:39 +08:00
Fini d3a7191848 fix(editor): float the color-variable picker in a scrolling popover
The variable-binding list was emitted by the section walker as plain
panel rows — no height cap, no viewport, no scroll — so forty
variables inflated the inspector past the window and the clipped tail
stayed unreachable (yet still clickable through the clip). Rebuild it
as an anchored overlay in the same family as the fill-type and font
pickers: 320px cap with its own wheel scroll, outside-click and
Escape to close, name column ellipsized against a right-aligned hex
column so long tokens never overlap their value. Bind/unbind emission
is unchanged, the stroke-section picker shares the implementation,
and a regression test compares every other panel rect open-vs-closed
so the inline-inflation shape cannot come back.
2026-07-28 00:29:39 +08:00
Fini 853369006d test(editor): cover the frame-path image fill controls
Every image-fill popover test built its fixture on a rectangle, but a
dropped screenshot lands on a frame — a different SectionCapabilities
branch. A regression there would present exactly as 'the dropped
image can't be adjusted' with no red test. Walk the real chain once
from apply_image_drop on a frame through the fill row, mode chips and
crop-editing gate.
2026-07-28 00:29:39 +08:00