fix(web): dismiss stale Todo snapshot after continuing - #6307
Conversation
|
🧪 This PR has changes that need a manual QA pass before merge - please hold off self-merging for now; we'll loop QA in once it's merge-ready (and design/product have signed off, where applicable). |
PerishCode
left a comment
There was a problem hiding this comment.
@Siri-Ray I verified that the pinned Todo slot now records the exact continued tool event only after the follow-up send is accepted, restores that dismissal for the conversation across a browser-session remount, and still surfaces a genuinely new TodoWrite/update_plan event even when its task content is identical. The focused component coverage exercises the stale-card dismissal, remount persistence, and new-event replacement paths. Nice work keeping the fix scoped to the existing continuation flow and event identity.
🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.|
Thanks for the contribution. I completed QA validation for this PR at head QA Acceptance Record Scope:
Verified:
Risks / notes:
Conclusion:
|
|
Successfully created backport PR for |
* fix(daemon): surface AMR OpenCode stall context (#6040) * fix(daemon): surface AMR OpenCode stall context * fix(daemon): accept runtime-omitted OpenCode diagnostics Generated-By: looper 0.11.0 (runner=fixer, agent=codex) * fix(ci): make static gate runner-independent (#6039) --------- Co-authored-by: PerishFire <39043006+PerishCode@users.noreply.github.com> * test(e2e): parallelize restoration group (#6169) * test(e2e): parallelize restoration group * test(e2e): identify conversations from persisted prompts Generated-By: looper 0.11.0 (runner=fixer, agent=codex) * test(e2e): wait for conversation persistence --------- Co-authored-by: Looper <looper@noreply.github.com> * feat(landing-page): sharpen the Codex agent page for "codex ui" intent (#6200) The /agents/codex-design/ page ranks #1 for "codex design" but only ~6th with a 1.3% CTR for "codex ui", a query that grew from 30 to ~90 daily impressions this month. A live SERP check shows the intent is mostly "build UI with Codex" (our intent), with a minority looking for the Codex app's own interface. - Retitle to "Codex Design: Build UI with OpenAI Codex" (title + H1). - Lead the frontend section with the query phrase and an answer-shaped opening paragraph, so the section is extractable for AI answers. - Add a disambiguation paragraph separating the Codex app's own UI from the UI you build with Codex, and route the former back to the main line. - Add two FAQ entries covering both readings; they also feed the FAQPage schema, which already earns a text snippet on this query. Applied across all 11 shipped locales (en, zh authored; the other nine translated with the page's terminology preserved). Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com> * Add Clone Audit plugin (#5687) * Add Clone Audit plugin * Update open-design.json * fix: make clone audit skill reusable * fix: sanitize clone audit provenance path * fix(e2e): bound tools-dev runtime lifecycle (#6204) * test(e2e): refresh full-pool UI fixtures (#6211) * fix(web): allow skipping required chat questions (#6177) * fix(web): allow skipping required chat questions * fix(web): auto-skip unanswered chat questions --------- Co-authored-by: xiaoche-hub <298951296+xiaoche-hub@users.noreply.github.com> * docs(tools-pack): add build cache contract (#6207) * docs(tools-pack): add build cache contract Document the tools-pack build-graph cache as a contract: the exact-match acceptance model, determinant rules, materialization-time parameters, the signing boundary, and fail-closed confidence grading. The rules come from an audit of all 11 cache nodes. Two are written down because nothing currently enforces them: a node key must carry the key of every upstream node it consumes, and a node key must not restate a list that already exists as a constant. Known low-confidence points are declared explicitly so fail-closed grading stays checkable rather than becoming a verbal convention. * docs(tools-pack): clarify cache materialization exceptions Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * docs(tools-pack): document NSIS base version scope Generated-By: looper 0.11.2 (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> * docs(landing-page): add 0.16.0 release post, localize and re-cover 0.15.1 (#6236) * docs(landing-page): localize 0.15.1 post, fix its cover, add 0.16.0 release post The 0.15.1 blog post shipped English-only and with an off-brand cover: a Fauvist oil painting overlaid with large display type, which reads nothing like the warm editorial illustrations every other release post uses. It also pointed `socialImage` at a 309KB JPEG while a WebP sat unused beside it. Regenerate the cover in the established house style (cream paper ground, sage/terracotta watercolour washes, pencil sketch resolving into a calm product surface), drop the stray JPEG, and add the full ten-locale i18n block so /zh/, /ja/, /ko/, /de/, /fr/, /ru/, /es/, /pt-br/, /it/ and /tr/ read in their own language instead of falling back to English. Also add the missing 0.16.0 "Reliable Delivery" post with a cover plus two inline figures in the same style, localized across the same ten locales. The 0.16.1 patch is a single preview fix, too thin to carry its own page, so it lands as a closing section of the 0.16.0 post and the download CTA points there. * docs(landing-page): fix doubled apostrophes and locale copy in release posts Three defects surfaced reviewing the localized bodies. The French, Italian and Turkish bodies rendered every apostrophe twice — "aujourd''hui", "all''interno", "0.16.1''i". The `''` escape belongs to single-quoted YAML scalars, but `bodyHtml` is a block scalar, where content is literal. 173 occurrences across the two posts. Korean used Japanese corner brackets and Brazilian Portuguese and Turkish used French guillemets. All three take curly double quotes. The Chinese copy read as translation rather than prose. "标签" opens the release line as a UI label, not a version tag; "抢画框", "编辑策展位" and "安静修复" are literal renderings that say nothing in Chinese; "画廊" is not the term the product itself uses for a gallery, which keeps the English word. The tag fix also lands on 0.10.0 through 0.15.0, which share the phrasing — leaving the series half-corrected would read worse than either state alone. * docs(landing-page): drop the leading tag word from release post openings Every release post opened with the word for a git tag before the version identifier — "Tag open-design-v0.16.0", "Etiqueta …", "タグ …", and in Chinese "标签", which reads as a UI label rather than a version. The word carries no information the identifier does not already carry, and in several languages it lands as a category noun the sentence never uses again. Drop it across all nine release posts and every locale, in both the summary and the opening line, leaving the version identifier to open the dateline. Spanish and Brazilian Portuguese lose the feminine agreement that referred back to the removed noun; Turkish loses the trailing "etiketi" apposition for the same reason. * docs(landing-page): correct the 0.16.1 interval in the 0.16.0 post 0.16.0 was published 2026-07-22 14:42 UTC and 0.16.1 on 2026-07-23 16:11 UTC — 25.5 hours apart. "Two days later" overstated it, and the same wording had been carried into all ten localized bodies, so every published route repeated it. --------- Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com> * feat(integrations): add the local Open Design Cloud flow for Codex (#6055) * feat(daemon): expose Vela login through CLI and MCP * feat(mcp): add interactive local brief card * feat(packaged): bootstrap local MCP headlessly * feat(daemon): secure local BYOK credential profiles * feat(cli): manage secure BYOK profiles * feat(web): store BYOK keys in secure profiles * fix(runs): deduplicate cloud generation requests * feat(daemon): add end-to-end plugin observability * fix(pack): include native PTY runtime in desktop packages Lazy-load node-pty in the daemon so missing native binaries only disable Terminal and interactive Keychain operations instead of crashing startup. Ship and validate target prebuilds in macOS and Windows packages. Repair the macOS spawn helper before signing, and invalidate stale Windows packaging caches. Cover the packaged PTY path in macOS and Windows smoke tests. Require Vela CLI for every beta desktop build target. * fix(mcp): localize and stabilize plugin briefs Keep collect and confirm on one MCP Apps card, report intrinsic size changes, and remove the fragile widget-state fallback. Localize brief forms, summaries, status, and public errors from the current request or Host locale while preserving stable protocol ids and selections. Keep internal runtime identifiers out of user-facing MCP guidance. * fix(packaged): register live Studio URLs with daemon Register the packaged web sidecar loopback origin over namespace-scoped daemon IPC after dynamic binding. Invalidate install-info by the live web port and remove the second MCP URL cache so run and project responses use the current Studio address. Validate loopback origins and cover registration, rebind, and cache refresh. * fix(mcp): stabilize brief confirmation lifecycle Keep confirmed briefs locked after Host publication failures and retry only the cached follow-up message instead of confirming twice. Replace blank initialization with a compact loading state, accept immediate and delayed tool results, and bump the MCP Apps resource to v3 so Codex does not reuse the stale card. Add an executable JSDOM Host bridge harness covering double-submit, publication retry, delayed results, and repeated draft notifications. Validated with the full daemon suite, workspace typecheck, and guard. * fix(mcp): prevent brief app resize feedback loops Replace the self-observed intrinsic-height loop with deduplicated body measurements so Codex MCP app iframes do not repeatedly resize themselves and fail sandbox startup. Bump the brief resource URI to v4 to avoid cached v3 cards and cover the regression with the focused brief-app spec. Validated with daemon tests/build, workspace guard/typecheck, a verified beta DMG, and a direct packaged MCP resource smoke. * fix(mcp): use the final Open Design plugin identity Make open-design the only accepted external plugin ID across MCP tools, run attribution, artifact version origins, and telemetry. Rename the Brief MCP App resource to v5 and reject the unpublished old ID instead of aliasing it. Validated with 171 daemon tests, 5 web tests, daemon/web typechecks, and guard. * chore(pack): bump Vela CLI to 0.0.27 * chore(nix): refresh pnpm dependency hashes * fix(mcp): honor host and plugin request contracts Respect independently advertised MCP Apps capabilities and prefer the Codex-native follow-up bridge so confirmed briefs render as readable user turns instead of context-only messages. Bump the brief resource to v6 to invalidate stale cards.\n\nMark Vela login and account probes as open-world interactions, and require stable request IDs for attributed generation so lost responses cannot create a second logical run. * fix(cli): support keyless BYOK profiles Add an explicit --no-api-key save mode for local and self-hosted providers while keeping credential-bearing profiles stdin-only. Reject missing or conflicting credential modes and cover both paths in the CLI tests. * fix(pack): replace headless owner when desktop opens Advertise headless packaged runtimes as having no visible window, then shut them down before a normal desktop launch continues instead of treating SHOW as a successful focus. Validated with the focused packaged headless and launcher lifecycle tests (20 passed). * fix(pack): clean up failed headless startup Acquire the headless identity, sidecars, and IPC server through one failure-atomic lifecycle so later bootstrap errors close every previously acquired owner in reverse order. Cover MCP-install and web-identity publication failures; validated with 22 focused tests and the packaged typecheck. * fix(byok): remove raw provider request contract Expose only daemon-owned BYOK profile references from shared run types and the web transport, while retaining the daemon's fail-closed rejection for legacy or untyped raw credential payloads. Validated with 76 web provider tests plus web and contracts typechecks. * fix(daemon): preserve interrupted run idempotency Hydrate queued or running durable requests as DAEMON_RESTARTED failures before idempotency reuse, preserving the original request and workflow mappings instead of creating a second cloud operation. Share the restart transition with boot reconciliation and expose synthetic terminal events to reattaching clients. Validated with 48 focused tests and the daemon typecheck. * fix(byok): roll back failed credential metadata writes Snapshot secure-store values before mutation and compensate create, update, and delete operations when profile metadata cannot be persisted, preventing orphaned or lost credentials. Validated with nine focused credential-service tests and the daemon typecheck. * fix(web): reconcile selected BYOK profile metadata Treat the daemon's selected secure profile as authoritative for protocol, endpoint, model, and API version so CLI profile edits cannot leave the browser showing stale execution settings. Validated with 66 config tests and the web typecheck. * fix(byok): migrate legacy credentials before cleanup Import each supported legacy browser credential into a stable daemon-owned secure profile before removing plaintext copies. Keep the original browser record on secure-store or unsupported-provider failures and surface a Settings recovery path. Cover successful migration, duplicate projections, and injected secure-backend failure while preserving existing Bedrock downgrade behavior in memory. * fix(byok): secure Windows profiles with DPAPI Dispatch native Windows BYOK profiles to a CurrentUser DPAPI backend rooted under the resolved daemon data directory. Secrets enter PowerShell only through stdin, encrypted blobs stay separate from non-secret profile metadata, and API responses remain secret-free. Add platform dispatch coverage, a Windows-only real DPAPI round-trip test, and the packaged Windows smoke path for create, resolve, response-redaction, and delete behavior. * fix(web): preserve config writes during hydration * fix(byok): persist secure credentials across entry flows * test(byok): cover secure onboarding persistence --------- Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com> Co-authored-by: lefarcen <935902669@qq.com> * test: strengthen E2E coverage and fixtures (#6150) * test: strengthen e2e coverage and fixtures * test: allow artifact route when starting conversation * test: keep e2e count assertions stable Use the shared stable-count helper for no-request and duplicate-event windows so delayed async events cannot escape the assertions. Generated-By: looper 0.11.0 (runner=fixer, agent=codex) * fix: add e2e assertion import extension Use the explicit runtime extension required by the e2e NodeNext typecheck.\n\nGenerated-By: looper 0.11.0 (runner=fixer, agent=codex) * fix: preserve design system provenance and settle e2e assertions Keep disabled design systems available to project recovery and provenance while filtering only runtime injection. Make hover and cancellation checks observe their full settled windows. Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * test(e2e): preserve unique restoration run IDs Pass the restoration fixture's run ID prefix through routeSuccessfulRuns so each mocked request receives a distinct run identity. Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * test(e2e): stabilize agent and async count fixtures Route restoration agent requests through the shared JSON and SSE fixture, capture autosave baselines after a quiet period, and observe onboarding cancellation for a bounded stable window.\n\nGenerated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix: honor disabled design systems in daemon runs Filter disabled persisted project selections at prompt and analytics boundaries, and keep restoration run fixtures unique.\n\nGenerated-By: looper 0.11.2 (runner=fixer, agent=codex) * test(e2e): shorten cancellation duplicate check Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix(daemon): continue stalled post-tool sessions (#6237) * fix(daemon): continue stalled post-tool sessions * fix(daemon): separate post-tool continuation budget Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(daemon): preserve retry telemetry budget Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(daemon): align retry failure telemetry Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(tools-pack): carry workspace build key into tarballs (#6235) * fix(amr): recover late login failures and trace auth stages (#5986) * fix(amr): recover late login failures and trace auth stages * fix(amr): preserve scoped cancel attempt IDs Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): defer unsupported Vela auth stages Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): narrow fallback telemetry to shipped Vela Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): preserve live login after stale cancel Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): preserve cancel during login startup Retain cancellation intent when a provisional cancel races the delayed canonical login response, then cancel the canonical attempt before polling can begin. Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): rejoin newer login after startup cancel Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): preserve cancel across web login starts Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): retain cancel when status refresh fails Generated-By: looper 0.11.1 (runner=fixer, agent=codex) * fix(amr): cancel onboarding status preflight Treat cancellation before an auth attempt exists as a local preflight cancel so a delayed status response cannot start login.\n\nGenerated-By: looper 0.11.1 (runner=fixer, agent=codex) * ci: constrain Actions cache writes (#6270) * fix(tools-pack): carry workspace build key into tarballs * ci: constrain Actions cache writes * fix(daemon): auto-mint assistantMessageId when clients omit pin (#6107) * fix(daemon): auto-mint assistantMessageId when API clients omit it Web always supplies assistantMessageId. Headless/MCP/eval clients that already send conversationId but omit the pin left lastMessageId null and skipped multi-turn native session resume (missing_cursor). Mint the id server-side whenever a conversation is bound and the client did not, and seed the user message the same way the old MCP-only path did. * fix(daemon): validate conversation ownership before omit-pin seed Reorder project-ownership checks before minting assistantMessageId and seeding the user prompt so cross-project omit-pin requests cannot corrupt foreign chats. Make ChatRunCreateRequest.assistantMessageId optional and expose conversationId/assistantMessageId on McpRunCreateRequest with contract tests for the omit-pin shape. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): reject missing conversation before omit-pin mint Return CONVERSATION_NOT_FOUND when a client supplies a stale or mistyped conversationId so omit-pin does not mint an unpersisted assistantMessageId and plugin snapshot resolve does not FK-crash with a 500. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): seed latest turn and fallback-bound user prompts Prefer currentPrompt over full message transcripts when seeding omit-pin user turns, and still seed after conversationId fallback when the client already supplied assistantMessageId. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): preserve attachments on omit-pin seeded user turns Copy request attachments and commentAttachments into the server-seeded user message so omit-pin/headless clients keep chips and annotation context after conversation reload. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): treat empty currentPrompt as authoritative omit-pin seed Attachments-only ChatRequest turns send currentPrompt as '' while message is the flattened transcript. Prefer any string currentPrompt, including empty, so seeded user rows keep empty content and do not duplicate history. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): seed turn metadata and bump project activity on omit-pin Persist sessionMode, runContext, and appliedPluginSnapshot on omit-pin seeded user turns so reload/retry keep applied context. Call updateProject after seed so listProjects reorders headless/API activity like PUT /messages. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): require projectId for bound conversation ownership Reject POST /api/runs when conversationId is present but projectId is missing or non-string, so omit-pin cannot seed messages without owning project context. Cover both early and post-fallback ownership checks. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): preserve slideIndex and BMP kind on omit-pin seeds Keep deck annotation slideIndex and classify .bmp as image when seeding user messages for clients that omit assistantMessageId. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): seed empty message when omit-pin has attachments When currentPrompt is unset and message is empty, still seed the user turn if attachment metadata is present so chips/annotations survive reload. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(daemon): seed omit-pin chat content from original request Plugin resolution may rewrite meta.message with a rendered scenario brief for the run; persist requestBody currentPrompt/message for the user turn so the internal brief is not shown as chat content. Generated-By: looper 0.11.1 (runner=fixer, agent=grok-build) * fix(web): persist browser preview viewport (#4899) * fix(daemon): honor Kiro ACP turn completion (#6268) * fix(daemon): isolate plugin-started Local Codex runs (#6273) Disable Codex plugins only for externally attributed Open Design Plugin runs so Local Codex cannot recursively enter collect_brief or Cloud login. Preserve normal Local Codex plugin loading and the existing operator-wide override. Validated with the focused runtime args suite, workspace typecheck, guard, and an isolated source smoke that produced a valid artifact without Cloud login. Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com> * fix(landing): accept signed Vela team plan leads (#6283) * fix: durably deliver enterprise leads * fix(landing): make contact sales KV canonical * feat(prompts): introduce on-demand discovery in SP v2.0 (#6223) * feat(prompts): introduce on-demand discovery in SP v2.0 * fix(prompts): prevent nested deck label overlap * fix(plugins): stabilize od-default task routing * fix: address prompt and deck audit regressions * fix(prompts): restore plan mode precedence * fix(daemon): accept all form answer headers --------- Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com> * fix(web): surface BYOK migration validation errors (#6280) * fix(web): surface BYOK migration validation errors Preserve structured daemon errors during legacy credential migration and reserve offline guidance for fetch failures. Keep legacy browser credentials until migration succeeds, and cover HTTP validation, malformed responses, and network failures. Validated with focused web tests, web typecheck, workspace guard, and workspace typecheck. * fix(web): stabilize BYOK persistence error telemetry Map secure-profile HTTP and network failures to semantic error codes before emitting settings_byok_test_result, while preserving existing fallback behavior for unrelated connection-test errors. Validated with the complete web test suite, web typecheck, workspace typecheck, guard, and git diff --check. --------- Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com> * fix(ui): improve dark-mode contrast for off-state toggles (#5825) * fix(ui): improve dark-mode contrast for off-state toggles The default off-state track uses --border-strong (#c9d0da light / #46433c dark). In dark mode #46433c is only ~5% lighter than the --bg-subtle (#252321) panel behind it, making the toggle nearly invisible when off and users unsure of the control state. Bump the off-state track to #6b6862 with a subtle inset border, and add a thin outline to the white thumb so it stays visible against the (now lighter) track. On-state already uses --text (#e8e4dc) and is left unchanged. Applies to both .toggle-row (used by speaker-notes toggle in the deck tab) and .compact-toggle (used by SurfaceOptions toggles). Hover lift gives an additional interactive affordance. Fixes #5298 * fix(ui): fix two dark-mode toggle blocking issues from review Two correctness issues called out by mrcfps: 1. System dark theme never gets the contrast fix — the default "system" theme mode removes [data-theme] and falls back to @media prefers-color-scheme. Added a parallel block scoped to html:not([data-theme]) inside @media (prefers-color-scheme: dark). 2. Hover override wins over on-state — .compact-toggle:hover and .toggle-row:hover have higher specificity than .on variants, so hovering an ON toggle dropped its track from bright var(--text) to #75726c. Changed to :not(.on):hover so the hover lift only applies when off, leaving the on-state always bright. Both applied to both selector paths (explicit data-theme and system dark). * fix(web): keep Azure deployment names editable (#6034) * chore(plugin-previews): refresh baked preview manifest (#6293) Co-authored-by: open-design-bot <bot@open-design.ai> * fix(byok): withdraw Windows DPAPI backend (#6308) * fix(byok): withdraw Windows DPAPI backend * fix(byok): clean up retired Windows secret blobs Generated-By: looper 0.11.2 (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> * fix(web): dismiss stale todo after continuation starts (#6307) * fix(web): preserve shared project update timestamps * fix(web): reconcile shared timestamps on home * fix(web): preserve workspace scope in preview assets * fix(collab): avoid unscoped shared cover requests * fix(web): avoid double-wrapping preview assets * fix(web): preserve first prompt across project refresh * test(web): target the active shared project card * test(web): keep empty BYOK profile type-safe * test(e2e): require explicit workspace scope * fix(web): finish scoped preview hydration * test(e2e): align manual edit with current inspector * fix(web): reconcile files after event stream readiness * fix(web): keep local project creation workspace-independent * fix(web): preserve scoped auth recovery state * test(e2e): assert explicit Personal workspace scope * test(e2e): preserve visual AMR account fixture * test(web): await scoped cover source * UI polish batch: cloud sign-in, onboarding, composer menu (#6281) * UI polish batch: cloud sign-in, onboarding, composer menu Sign-in surfaces (rail callout, balance-gate dialog, onboarding) had drifted from the visual system and lost some redundant chrome; this batch tightens them up alongside a couple of composer/design-files reorganizations that were sitting in the same working tree: - Rail's signed-out callout: reorder copy above the login pill, give the pill an icon + accent-green label, restore the Escape hatch the pill had before it lost its close affordance. - AmrBalanceDialog (insufficient-balance / signed-out gate): add a full-bleed art banner above the copy, drop the now-redundant icon badge, tighten spacing/shadows to match. - Onboarding cloud landing: switch from a single centered column to a two-column layout (form pane + full-bleed art panel), move the language switcher into the footer, swap the local-CLI/BYOK links for icon Buttons, and add a dismiss control to the activation-retry hint. - Composer "+" menu: fold 插件/设计百宝箱 back in as hover-expand submenu rows instead of standalone quick pills above the input. - Design files panel: move new-document/upload actions out of the always-visible toolbar into the empty-state actions only. - Message center: drop the redundant header close button (backdrop click and Escape still dismiss it) and restyle the list from bordered cards to a divider-separated list. - New `key` / `robot` / `translate` / `arrow-right` icons; language menu switches from the `languages` glyph to `translate`. - Tab launcher popover reverts to the glass material; language dropdown gets a max-height + scroll so long lists don't blow out the popover. Rebased the composer-quick-pill removal onto this branch's own accessibility work on those pills (opener-based focus return via `ComposerStandalonePanel`) rather than reverting it — the "next step" card still drives the same standalone-panel API, just without a pill to hand focus back to. Also updated/removed the tests that pinned the now-removed surfaces (quick-pill popup contract, message-center close button, onboarding top bar, design-files toolbar upload trigger) so none of this lands with a newly-red suite. * perf(web): optimize onboarding cloud artwork * fix(web): invalidate project file reads after mutations * fix(web): disable readonly project starter mutations * fix(web): preserve focus for standalone composer panels * test(e2e): require explicit workspace scope * fix(web): invalidate file reads on project events * test(e2e): seed explicit settings workspace * test(e2e): align manual edit with current inspector * fix(web): refresh deployments when share opens * test(e2e): follow composer design system entry * fix(web): keep local project creation workspace-independent * fix(web): preserve scoped auth recovery state * test(e2e): follow current entry settings flows * fix(web): preserve AMR retry across settings * test(e2e): model explicit personal workspace recovery * test(e2e): stabilize AMR logout settings recovery * fix(projects): return workspace scope on create --------- Co-authored-by: lefarcen <935902669@qq.com> * test(e2e): lock design system team partition * fix(workspace): stabilize scoped project lifecycle * test(e2e): stabilize retained workspace transitions * fix(workspace): retain exact scope through transient outages * test(workspace): lock outage identity boundaries --------- Co-authored-by: Ray Xi <2667192167@qq.com> Co-authored-by: PerishFire <39043006+PerishCode@users.noreply.github.com> Co-authored-by: Looper <looper@noreply.github.com> Co-authored-by: Joey-nexu <joeylee12629@gmail.com> Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com> Co-authored-by: bestthanapon <thanapon.suwannasuk@gmail.com> Co-authored-by: open-design-crew[bot] <299007234+open-design-crew[bot]@users.noreply.github.com> Co-authored-by: xiaoche-hub <298951296+xiaoche-hub@users.noreply.github.com> Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com> Co-authored-by: Amy <58060647+AmyShang-alt@users.noreply.github.com> Co-authored-by: Marc Chan <mrc@powerformer.com> Co-authored-by: _HDCoder <2728073932@qq.com> Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com> Co-authored-by: Nicholas-Xiong <2482929840@qq.com> Co-authored-by: mehmet turac <mehmetturac@gmail.com> Co-authored-by: open-design-release-bot[bot] <295937643+open-design-release-bot[bot]@users.noreply.github.com> Co-authored-by: open-design-bot <bot@open-design.ai> Co-authored-by: CHENGLONG WANG <honam884844@gmail.com>













































Fixes #6306
Why
A user hit a disconnected design run whose pinned Todo card remained at 3/4 even after they clicked Continue remaining tasks and the follow-up turn finished without changing files.
The card treated the last TodoWrite/update_plan event as conversation-global state. Starting a continuation did not invalidate that event, so any follow-up turn that emitted no new plan snapshot left the old progress and Continue action pinned indefinitely.
What users will see
After Continue remaining tasks successfully starts a follow-up run, the interrupted run's old Todo card leaves the pinned slot. The dismissal survives conversation remounts within the browser session.
If the follow-up run emits a new TodoWrite/update_plan event, that new snapshot appears normally even when its task content is identical to the old snapshot.
Surface area
apps/weborapps/desktop(including Electron menu bar)odsubcommand or flag, newtools-dev/tools-packflag, or newOD_*env var/api/*endpoint, new SSE event, or changed shape inpackages/contractsskills/,design-systems/,design-templates/, orcraft/, or change to the skills protocolTRANSLATIONS.mdfor the locale workflow)package.json(dependenciesordevDependencies); workspace-packagepackage.jsonfiles are out of scope. Include a paragraph on what we get vs. what bytes we ship (seeCONTRIBUTING.md→ Code style)Screenshots
Not applicable: this changes the existing Continue state transition without adding or restyling a visual surface. The user-visible transition is covered by the component regression test below.
Bug fix verification
apps/web/tests/components/ChatPane.streaming.test.tsxmainand green on this branch? Yes.Validation
pnpm --filter @open-design/web exec vitest run -c vitest.config.ts --maxWorkers=2 tests/runtime/todos.test.ts tests/components/ChatPane.streaming.test.tsx— 40 passedpnpm --filter @open-design/web typecheckpnpm guardpnpm typecheckgit diff --check