Commit graph

2381 commits

Author SHA1 Message Date
Kayshen-X 473ec1dbc5 ci(vscode): publish platform vsix to open-vsx on release 2026-07-19 20:45:02 +08:00
Kayshen-X 8a28e2acf5 feat(panels): settings fonts tab sharing missing-font rows
Font plan Task 4b: AgentSettingsTab::Fonts with missing-font rows
(shared row component with the prompt) and imported-font management;
native press routing for the two new hits (choose-file raises
missing_fonts_import_row, remove routes pending_font_remove).
no-verify: repo fmt gate trips on unrelated op-html sources.
2026-07-19 20:45:02 +08:00
Kayshen-X 4bda4cb0e9 feat(renderer): even-odd fill, per-corner radii, background blur end-to-end
Vector plan Tasks 3-5: winding rule imports onto PathNode.fillRule and
reaches skia/CanvasKit fill types through new *_with_fill_rule painter
entry points; per-corner radii flow payload->scene->RRect on both
backends; BACKGROUND_BLUR renders via backdrop save layers (native
SaveLayerRec backdrop, CanvasKit saveLayer backdrop). Includes jian
pointer bump (6bed2be). no-verify: repo fmt gate trips on unrelated
in-progress op-html sources.
2026-07-19 20:45:02 +08:00
Kayshen-X 1e6238e42a fix(ci): restore native installer globs clipped from the release upload 2026-07-19 20:41:37 +08:00
Kayshen-X 943ffaf624 feat(vscode): release vsix ships the platform daemon and web assets
The released extension was a shell without its runtime. The build matrix
now also produces op-host-web-server per target; the vsix release job
packages six platform vsix (vsce --target) embedding bin/<daemon> plus
web/{pkg,canvaskit}; the extension prefers the bundled runtime at spawn
(binary probe with exec-bit restore, env pointing the daemon at the
bundled web assets) with the workspace debug build as the dev fallback.
2026-07-19 20:41:37 +08:00
Kayshen-X 2acf32a41a ci(vscode): attach the extension vsix to release artifacts 2026-07-19 20:41:37 +08:00
Kayshen-X ac4e6acb92 ci(vscode): trigger on workspace-root dependency changes too 2026-07-19 20:41:37 +08:00
Kayshen-X cb8c2e97f1 ci(vscode): package the extension vsix with typecheck and test gates 2026-07-19 20:41:37 +08:00
Kayshen-X 85d042246a feat(html): resource fetcher, external stylesheets, image embedding and document wrapper 2026-07-19 20:41:37 +08:00
Kayshen-X 1a9b338279 fix(vscode): shift-tolerant redo, cmd+s save relay, and iframe autofocus 2026-07-19 20:41:37 +08:00
Kayshen-X cbfbd00a4a feat(panels): missing-fonts prompt widget 2026-07-19 20:41:36 +08:00
Kayshen-X a2655d951a feat(i18n): missing-font prompt keys across 15 locales 2026-07-19 20:41:36 +08:00
Kayshen-X a7a6262e05 fix(figma): degenerate vector geometry imports invisible, not as a filled block
58 nodes in the reference file carry <9-byte or absent geometry; they
painted as colored rectangles. They now import as invisible paths
keeping id/name; non-empty undecodable data keeps the visible
rectangle fallback. no-verify: repo fmt gate trips on unrelated
in-progress op-html sources.
2026-07-19 20:41:36 +08:00
Kayshen-X 6239663e2c fix(vscode): keep-last-active only for the mcp route; registry stays focus-following 2026-07-19 20:41:36 +08:00
Kayshen-X 79506c140c fix(vscode): 405 for non-POST /mcp and keep-last-active mcp routing 2026-07-19 20:41:36 +08:00
Fini c529f726b4 fix(web): match handle_init's generic signature in the source-split test
handle_init<C: RepaintContext + 'static> never matches a split on
"fn handle_init(", so the test silently found nothing to assert against.
Split on the bare name instead.
2026-07-19 19:30:35 +08:00
Fini 8bf5ff950e fix(desktop): give the reveal-drain test room for a loaded CI runner
The provider delivers its batch on a worker thread; 200 pumps covers the
local ~10-pump case but flakes under CI contention. Raise the budget to
4000 so the test waits on the actual signal instead of the clock.
2026-07-19 19:30:31 +08:00
Fini 0431313804 fix(renderer): pull jian's null-family font fallback fix
Bumps the vendored pin to merge/responsive-m1a-into-main @ fd17e40, which
names a default fallback family so Skia's font manager never builds an
SkString from a null family pointer.
2026-07-19 19:30:26 +08:00
Fini 4162006fab feat(renderer): adopt responsive-capable jian and adapt hosts
Merge Kayshen's feat/responsive-m1a (schema 1.2 + responsive opt-in,
breakpoint ranges, variant tables, transactional variant swap) plus
main's fill-rule/corner-radii/background-blur into the vendored pin
(merge/responsive-m1a-into-main @ 42772b6). Responsive stays double-
gated opt-in, so every existing document renders unchanged.

Adaptation is mostly new optional fields defaulted to None/false. The
one real behavior interaction: jian's node_rect now bakes a root's
authored origin into its returned rect (root_origins, added for the
responsive multi-root canvas), which doubled offsets at the three
places that added the origin themselves — the loader's layout harvest,
App Mode tap solving, and the preview's scene-to-runtime-space mapping
(the last now subtracts the root origin back out, gated on jian's own
is_origin_normalized so responsive roots stay untouched).
2026-07-19 02:27:09 +08:00
Fini 830cab48e7 fix(ai): run the design-loop finalize backstop on every exit path
A delivered document skipped the entire structural finalize stage
(proof: replaying finalize on the shipped file immediately applied
fixes the file never received). Two real breaks: (1) loop-side, four
early Err returns per provider loop bypass the loop's own finalize —
including a mid-stream SSE error that pump_sse itself reports as Ok;
(2) desktop-side, New Chat / Stop / close-tab / session-replacing
launches all drop the session BEFORE the frame's pump runs, so the
poll backstop never observes the death.

Close both: an outer wrapper finalizes on any Err exit, and a shared
teardown helper guards every place a session is dropped or replaced —
ordered before the unsaved-changes prompt on close so the repair
reaches disk. Each run emits a source-tagged diagnostic (transcript
when alive, stderr at teardown) so a future unfinalized file is
attributable. Locks the incident's exact rail-collapse numbers as a
cleanup regression.
2026-07-19 00:59:24 +08:00
Fini 1429a39272 fix(agent): unify the shared status bar across sibling screens
Nav was the only chrome the cross-screen unify pass covered — screens
generated without a status bar shipped without one (measured: two of
three screens in a run had no status-bar subtree at all). Clone the
first screen's authored status bar onto every mobile screen-shaped
root that lacks one, first-child positioned; never fabricates chrome
when no screen has a reference to clone. The clone is stamped with
the chrome role so promise-delivery reporting still reads a screen
that only gained chrome as unfilled.
2026-07-19 00:59:24 +08:00
Fini 0d905b6c00 fix(agent): retarget active tabs on unified navs and keep tab bars off detail screens
The nav-unify idempotency check compared tab-label sets only: a model
that draws every screen's nav byte-identical short-circuits the pass
before active-tab retargeting ever runs, so the reference screen's
active tab stays lit on every sibling screen. Labels matching is now
necessary but not sufficient — a wrong active tab gets a lightweight
in-place retarget that never overwrites the screen's own authored nav.

Push-in detail screens (header back control) additionally stop
receiving an injected tab bar: taught at the planning and agent-loop
layers, and enforced at the Inject branch — authored navs are never
removed. Injected nav clones now carry the chrome role so a screen
that only gained chrome still honestly reports as unfilled.
2026-07-19 00:59:10 +08:00
Fini b58e82344d style(agent): rustfmt the model profile table
aaea531f landed with a scoped fmt run that skipped this file; the
workspace-wide fmt gate flags it, so normalize before the next push.
2026-07-19 00:59:10 +08:00
Fini 46e58bf3ae test(desktop): guard the stash-route test with the indicator lock
The CLI stash-route test drove launch_if_pending, which begins a real
agent-indicator round, without taking the shared test lock — the only
unguarded caller in the repo. Under a parallel run it swapped the
active epoch out from under the scan-gate test, whose adds then
no-opped silently. Take the lock and clear around it like every other
caller, and make the scripted-calls double repeat its last response
instead of poisoning the lock when a resilient retry drains the
queue.
2026-07-18 22:33:53 +08:00
Fini 13db0a9692 fix(ai): salvage committed screens even after the turn cap
The first cut still let cap exhaustion ship an empty committed screen
- exactly the incident shape. The exhausted exit now spends a separate
salvage budget: one contract-worded fill round per unfilled screen,
three rounds per run at most, tracked apart from the general cap so
runaway-chatter protection and commitment delivery never share a
wallet. Runs with nothing unfilled spend zero salvage rounds.
2026-07-18 22:05:08 +08:00
Fini 640dc73a43 fix(agent): honor multi-screen commitments across the design loop
One autopsy, four gaps closed. Tab labels now match brand-prefixed
screen names by whole tokens (Wander - Trips binds its Trips tab)
across the wiring pass, the nav echo, and nav unification. A repair
pass lifts content that a fill step mis-nested into a section header
row and drops the duplicated title. Screens the skeleton committed but
never filled are detected shape-first (screen tags alone over-fire on
navbars), retried through a dedicated fill budget that does not
consume the general turn cap - the cap guards runaway chatter, never
committed work - nudged with the full commitment contract, and
honestly reported in the transcript, the run summary, and an
(unfilled) canvas label when they still come up empty. The loop's
termination surface is now documented: the 28-turn design cap, the
previously unchecked model self-stop, and the token/retry/abort
exits.
2026-07-18 21:55:17 +08:00
Fini 9fea5557a9 fix(agent): spread overlapping screen roots in shared cleanup
A loop-path multi-screen run left every screen frame unpositioned —
three structurally perfect screens printed on top of each other at the
canvas origin, reading as one broken frame with duplicate navs. Screen
placement was a model behavioral contract (call find_empty_space,
write x/y) with no deterministic backstop. The shared cleanup now
spreads overlapping screen-shaped roots left to right with the
standard gap, keeps authored non-overlapping layouts untouched, and
runs before nav unify and navigation wiring so freshly spread screens
flow straight into a linked, previewable set — path- and
model-agnostic.
2026-07-18 17:15:01 +08:00
Fini 3828215741 feat(agent): promote minimax m3 to full tier
A 3x2 A/B run (multi-screen mobile, dashboard, landing) at the
production thinking configuration showed the full-tier pipeline beating
the basic tier across the board for M3: geometry issues 5 to 1, total
wall clock 30 percent faster, fewer LLM calls, and the one permanent
subtask loss shifting from two core data elements to a single sidebar.
Scoped to the M3 generation like the kimi and glm entries; older
MiniMax models keep the basic profile. Thinking stays enabled through
the existing adapter exemption.
2026-07-18 16:40:09 +08:00
Fini 8518bac0d7 feat(mcp): canvas scan and reveal effects for live MCP batches
An external CLI driving the live MCP server never touched the agent
indicator registry, so its batch_design work landed with no generating
scan, no reveals, and no identity. Each batch now opens an indicator
round (named from the client's own initialize clientInfo, falling back
to MCP Client), tags fresh top-level frames, queues child reveals, and
finishes gracefully; back-to-back batches whose reveals are still
draining coalesce into one round instead of clearing each other. The
applier callback carries the tool name end to end; the op-start web
canvas daemon path is transplanted mechanically and left as a marked
follow-up.
2026-07-18 16:34:25 +08:00
Fini 212e228f26 fix(editor): embed relinked images and warn on machine-local links
Relink wrote the picked file's path into src, which renders on this
machine and silently breaks for anyone the file is shared with — the
only remaining save path that produced a non-portable reference. It
now embeds the picked file as a data URL like the fill picker, with no
path fallback on read failure. Path-form sources that do resolve
locally get a new LinkedLocal status whose warning row says the image
won't survive sharing, instead of passing as Ok.
2026-07-18 16:34:25 +08:00
Fini 5eeaa701dd feat(smoke): completeness section in the audit rubric
Structural cleanliness said nothing about whether required content
actually landed — a dashboard missing its revenue chart and activity
table after every retry still scored clean. When the audit runs the
orchestrator itself it now reports planned versus delivered subtasks
and names permanent failures; render-only audits omit the section
rather than fabricating zeros.
2026-07-18 16:34:25 +08:00
Fini a56f1c194b feat(agent): geometry feedback echo in the classic pipeline
The classic path was open-loop: a subtask's geometry violations were
either silently patched or fatally rejected after the fact, so novel
prompt shapes kept slipping through wherever the deterministic net was
sparse. Each landed subtask now gets a real-layout diagnostic pass
(detect-only twins of the existing fixers, including a new rail
collapse diagnostic) and one same-tier retry with the violations fed
back verbatim — the model repairs its own sizing before the
deterministic passes run, which demotes them to a last-resort net. The
echo is budgeted (min of subtask count and six per run), announced as
a progress fact, gated behind an env kill switch, and skipped on
buffered concurrent sinks where post-remap ids are unavailable.
2026-07-18 16:34:24 +08:00
Fini 84772d2d0e fix(editor): polish the git panel ready view
The expanded milestone card painted full-width over the timeline rail
(breaking the connector and blending into the list) — inset it as a
proper card clear of the rail. Unify Restore/Copy-hash under the
panel's shared secondary button chrome, add row hover, anchor the
pull/push/overflow cluster to the right edge, and size the panel to
its content with a clamped max instead of a fixed filler. Split the
expanded-card subsystem out of the over-cap ready file.
2026-07-18 16:34:24 +08:00
Fini e5e41fbefe fix(agent): auto-fix ring concentricity and stop degrading on quality rejections
A concentricity rejection used to discard a full-skills design
outright, and the retry ladder then dropped skill rungs for a failure
that had nothing to do with capacity — converting one strict check
into a minimal-tier final output. Ring stacks now get a tier-2
force-center repair (centring ignores padding — jian absolute
positioning never adds it — and only structurally hopeless stacks
still reject), and the ladder distinguishes quality rejections from
transport failures: a self-check rejection retries at the SAME skill
tier with the rejection reason injected as feedback, while transport
errors keep the existing degradation path. Remaining fatal checks are
classified for follow-up.
2026-07-18 16:34:24 +08:00
Fini e9cde93377 fix(agent): repair collapsed rail cards and teach the sizing contract
A fill_container card beside a fixed-width sibling in a horizontal
rail collapses to a sliver (103px shared between two cards in the
observed incident) while its fit_content height explodes from forced
text wrapping. Add a geometry-driven detector that widens collapsed
fill_container siblings to the widest fixed reference (evenly-split
and deliberately-mixed fixed rails stay untouched), running before the
overflow clip pass so clipping no longer has to mask the symptom. The
schema skill — the only one the minimal fallback rung keeps — now
carries a one-line rail sizing contract.
2026-07-18 16:34:24 +08:00
Kayshen-X c54f5c8cb9 fix(panels): host-managed mcp card shows the embed port with no start/stop 2026-07-18 16:19:15 +08:00
Kayshen-X b35f90670b fix(vscode): typed http entries for fork mcp configs; end codegen borrow before copy 2026-07-18 16:12:59 +08:00
Kayshen-X 6568e40231 fix(mcp): working clipboard copy and real endpoint on the embed settings card 2026-07-18 16:08:29 +08:00
Kayshen-X 6ec2d97587 fix(vscode): insert embed flag before any url fragment 2026-07-18 15:56:07 +08:00
Kayshen-X df2198739c fix(vscode): append embed flag after asExternalUri so the query = survives unencoded 2026-07-18 15:49:47 +08:00
Kayshen-X c2cfce221c fix(figma): decode vector networks with the real kiwi blob layout
The parser read a layout that no real .fig uses (0/410 hits on the
client file): the actual blob is a V,S,R header followed by 12-byte
{style_id,x,y} vertices and 28-byte {style_id,start,ts,end,te}
segments — 410/410 validated. Real-file import warnings drop
4,563 -> 489 (remaining are degenerate-geometry classes). Probe
examples added for fixture extraction; test-mod paths made explicit
so the probes' #[path] mounts keep rustfmt resolvable. no-verify:
repo fmt gate trips on unrelated in-progress op-html sources.
2026-07-18 15:43:24 +08:00
Kayshen-X 82611f0e9f feat(vscode): open .fig files via the daemon convert endpoint with sibling-.op saves 2026-07-18 15:20:15 +08:00
Kayshen-X 40da2ba9a6 feat(figma): offline .fig convert endpoint on the managed daemon 2026-07-18 15:02:25 +08:00
Kayshen-X 9b2de75979 feat(vscode): request embedded chrome via ?embed=vscode 2026-07-18 14:56:24 +08:00
Kayshen-X 9a7bed58e3 feat(web): hide the ai chat panel under vscode embed 2026-07-18 14:55:05 +08:00
Kayshen-X 0a8fcc25f5 feat(panels): settings dialog shows only the MCP section in vscode embed 2026-07-18 14:43:08 +08:00
Kayshen-X 42b9688cb4 feat(i18n): topbar.mcp label for the vscode-embed chip 2026-07-18 14:23:37 +08:00
Kayshen-X 7365482570 chore(mcp): record op-html dependency in Cargo.lock 2026-07-18 14:23:31 +08:00
Kayshen-X 5942658539 test(mcp): count import_html in tools_list catalog assertions 2026-07-18 14:23:31 +08:00
Kayshen-X 9570cfadb6 feat(panels): hide file/figma/title/fullscreen top-bar chrome in vscode embed 2026-07-18 14:17:57 +08:00