Commit Graph
81 Commits
Author SHA1 Message Date
a2ba3ee2ad feat(updater): manual cache clear, installer-reinstall floor, and crash-recovery lifecycle (#6032)
* feat(updater): manual cache clear + installer-reinstall floor on the installed outer version

Two disaster-recovery capabilities for the packaged updater:

- Reuse control.launcher.version.min properly: the gate now compares the
  physically installed outer package version (read at check time from the
  outer bundle's open-design-config.json via the launcher launch path;
  OD_UPDATE_INSTALLED_VERSION overrides for tests), not the running payload
  version. When the floor trips - or min is set but the outer version is
  unreadable (conservative) - the updater selects the installer artifact and
  offers a same-version installer reinstall when no newer release exists
  (clamped to min <= candidate so the offer always converges). The status
  snapshot carries a reinstall block {reason, installedVersion, minVersion,
  url}; UpdateDialog/UpdaterPopup render reinstall copy with an optional
  operator jump link. tools-release publish-metadata publishes the block from
  RELEASE_LAUNCHER_VERSION_MIN(_URL) (per-channel repo vars with a _STABLE
  fallback wired in all release workflows) and hard-fails when min exceeds
  the release version; verify-metadata re-checks the published block and
  summary-metadata surfaces the floor.

- Manual clear-cache action (od:update:clear-cache IPC, sidecar clear-cache
  action, Settings > About row with a two-stage inline confirm): resets
  one-shot update state (downloaded release, install freeze) back to idle,
  purges releases/staging/downloads/.back, removes a stale launcher
  attempt.json plus any non-confirmed desktop-handoff journal, and deletes
  non-retained payload versions. Runtime active/lastSuccessful versions,
  retained cleanup entries, install.json, and a confirmed handoff journal
  are never touched; locked files defer through the existing cleanup.json
  retry machinery.

Also: tools-pack --update-action now validates through sidecar-proto's
exported isDesktopUpdateAction so clear-cache reaches the ops surface;
tools-serve updater fixture gains control min/url knobs and CLI flags;
9 new i18n keys across all 19 locales; tools/pack/AGENTS.md documents the
gate semantics and clear-cache boundaries.

Validated locally per the updater matrix (desktop/web/tools-serve/tools-pack
suites, guard, typechecks) plus a mac release-beta closed loop: platform full
spec, same-version reinstall against a real outer/payload version split,
clear-cache recovery, and a real-feed payload update to 0.15.1-beta.4.

* test(updater): close Windows recovery acceptance

* test(updater): mirror Windows same-version reinstall recovery on the mac lane

Port the Windows runSameVersionUpdaterRecoveryAcceptance shape into the mac
full profile: after the payload cold-start acceptance, restart the packaged
app against a fixture publishing an installed-outer floor at the running
payload version and assert the same-version installer reinstall snapshot
(reason/installedVersion/minVersion/url), the popup reinstall learn-more
link, clear-cache back to idle with launcher pointers untouched, explicit
re-check recovery, and the installer open in dry-run mode — macOS has no
silent DMG install to execute, unlike the Windows NSIS transaction lane.
Extends the popup eval expression/validator with reinstallLinkVisible and
records an updaterRecovery block in the smoke summary. Full-profile test
timeout raised 240s -> 360s for the extra app restart.

Validated locally: release-smoke full profile green in 80s with the recovery
summary populated (reinstall block exact, cleared idle, recovered dmg,
dryRun install).

* refactor(release): centralize launcher version floor channel policy in one resolver

Channel policy for control.launcher.version.{min,url} is now managed as one
repo-vars pair per channel (RELEASE_LAUNCHER_VERSION_MIN[_URL]_<CHANNEL>).
Workflows pass the channel pair plus the STABLE pair through verbatim — the
|| fallback expressions are gone from YAML — and the shared resolver in
tools/release/src/storage/launcher-version-floor.ts owns resolution and
validation: pair-level stable fallback for non-stable channels (never mixing
one channel's min with another's url), version format, http(s) url, orphan
url rejection, and the floor <= releaseVersion guard. publish-metadata and
verify-metadata consume the same resolver, so verify re-derives the expected
block from the same channel policy instead of trusting a pre-resolved env.
release-workflows.test.ts pins the verbatim passthrough keys in all five
release lanes and rejects any reintroduced YAML fallback.

* feat(updater): let clear-cache rebuild a provably-owned corrupt update store

A corrupt store is one of the blocking scenarios the manual clear exists to
recover from, yet the action previously bailed on the very store errors it
should heal. clear-cache now rebuilds the update root when — and only when —
ownership is provable: the current-generation sentinel is the proof, and
everything else inside an owned root is updater cache by definition. Roots
without a sentinel, with a foreign-generation marker, or failing IO are never
touched; the original store error surfaces unchanged. Four specs pin the
boundary (corrupt metadata rebuilt, stray entries rebuilt, unowned root
refused with files intact, foreign-generation marker refused).

* fix(launcher): pre-arm delegated payload launches so pre-bookkeeping crashes roll back

A payload that spawned successfully but died before reaching its own launcher
bookkeeping left no attempt.json behind, so every later cold start re-selected
the same broken active pointer and re-delegated to the dead payload — a
permanent dead loop the installer fallback could never surface (found while
designing the crash-rollback acceptance).

The delegating parent now arms attempt.json BEFORE spawning the payload and
passes the pointer as --od-launcher-delegated-* argv. Selection gains an
active-delegated reason: an attempt matching active AND the delegated pointer
is the launch in progress, not a previous failure; only an exact active match
qualifies, so a stale pointer cannot defeat the rollback. Rollback
(last-successful) delegations deliberately carry no marker and never re-arm —
the attempt on disk IS the rollback evidence the child must re-derive.

Covered end to end: packaged outer delegation pre-arms (and skips pre-arm on
rollback), the updater's payload activation pre-arms and threads the pointer
through the deferred relaunch, and confirm clears the attempt for delegated
launches. launcher-proto 18, packaged 237, desktop 264 all green.

* fix(updater): scrub a stale payload install freeze after a rollback

A payload install freezes the updater with installResult.activeVersion
awaiting the relaunch. When that payload crashed and the launcher rolled
back, the app restarts on the OLD version with the freeze still persisted —
every later check became a frozen no-op, so a rolled-back install never saw
another update offer (the crash-rollback acceptance exposed this in its
self-heal phase). Cold-start restore now detects the broken promise —
installResult.activeVersion newer than the running version on a live process
— and drops the freeze and stale install result while keeping the verified
downloaded release actionable. The installer-artifact freeze (no
activeVersion) keeps its existing restore semantics. Red spec:
'clears a stale payload install freeze when the promised relaunch never
became the running version'.

* test(updater): full-lifecycle acceptance — silent startup, crash rollback, coverage map

Two new packaged acceptance tests on both platform lanes (mac validated
locally; win symmetric for the Windows box):

- 'applies a downloaded payload silently on the next cold start': enables the
  daemon-owned allowSilentUpdates through the production GET+PUT
  /api/app-config path, restarts, and asserts the first scheduler tick
  installs, quits, and relaunches with converged pointers — no updater action
  issued.
- 'rolls back a crashing payload and self-heals on the next good update':
  repacks the real payload archive with a crash-before-bookkeeping stub
  (mac: shebang script via ditto; win: a real executable — System32 where.exe
  — via the installed app's bundled 7z, since a script cannot stand in for an
  exe), drives the update through the popup, asserts the pre-armed attempt
  survives the crash as rollback evidence, cold-starts into the rolled-back
  base version (degraded steady state pinned: broken pointer stays active
  with its attempt), then self-heals via a version-bumped healthy payload —
  real recovery releases ship as version+1.

Spec hygiene: resetPackagedRuntimeState wipes launcher/runtime/daemon state
before each lifecycle test (uninstall keeps runtime data by design, and
leftover pointers silently delegate fresh installs onto stale payloads);
mac waitForHealthyDesktopVersion gains win's requireSettledLauncher opt-out
for rollback waits.

docs/testing/updater-lifecycle.md is the new lifecycle-to-test coverage map
(incl. deliberate manual-only nodes), linked from tools/pack/AGENTS.md and
the e2e coverage status doc.

* fix(updater): harden Windows full-lifecycle acceptance

* test(release): make channel-prepare hermetic against local git tags

prepare-preview derives its latest-stable floor from the clone's real
open-design-v* tags, so the channel-prepare tests were green on tagless CI
checkouts but permanently red on any developer clone once shipped stable
tags advanced past main's package version (0.15.1 vs v0.15.1/v0.16.0 today).
The spawned scripts now run with GIT_DIR pointing at a throwaway repo
holding exactly the tags each test declares, and a new negative case pins
the floor rejection itself (packaged version below a v99.0.0 stable tag).

* test(e2e): model delegated payload launch

Pass the updater's pre-armed payload pointer into the cross-runtime launcher simulation so it represents the spawned payload process instead of a later crash-recovery launch.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* test(web): wait for question form readiness

Wait for the asynchronously derived submit-disabled state before asserting it, removing the suite-order race observed by the Web workspace tests check.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(updater): preserve recovery state across locks and restarts

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-24 05:18:48 +00:00
AmyandGitHub 3162da5f23 test: cover runtime automation gaps (#5976)
* test: cover runtime automation gaps

* fix: remove duplicate runtime startup declarations

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)
2026-07-22 14:29:34 +00:00
2d1f25ac60 feat(web): add message center (#5920)
* feat(web): add message center demo

* fix(web): align message center actions

* fix(web): remove message read toggles

* fix(web): show unread count on message filter

* feat(web): connect message center to vela (#5777)

* feat(web): connect message center to vela

* fix(web): harden message center read syncing

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(web): preserve cached message center reads

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(web): repair message center read sync and visual selector

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(web): refresh message center write auth and bound pagination

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(web): preserve message center state across locale and logout

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(message-center): stabilize login and anonymous delivery (#5910)

* journal: stop repeated amr login polling

* fix(web): drop anonymous message-center window gate

Align with Vela audience+TTL visibility by stopping startedAt local
windows so anonymous clients can pull all non-expired global messages.

* refactor(web): promote message center from demo

* fix(daemon): guard vela message center proxy stream

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(cli): add message center command

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* test(e2e): harden visual workspace file readiness

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(web): separate message center sync empty states

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com>
2026-07-21 11:50:57 +00:00
d8b6b797fe Simplify chat execution disclosures (#5667)
* Simplify chat execution disclosures

* test: cover collapsed file disclosures

* refactor(web): consolidate chat task activity

* fix(web): show small file outputs inline

* fix(web): separate file outputs from reads

* fix(web): collapse completed todo cards

* refactor(web): compact completed todo lists

* fix(web): make completed todos expandable

* fix(web): keep four output files visible

* refactor(web): clarify chat activity timeline

* fix(web): make file output disclosure interactive

* feat(web): emphasize chat run states

* style(web): simplify chat run status colors

* style(web): remove chat run status icons

* feat(web): stream one chat activity at a time

* style(web): align chat completion row

* fix(web): simplify priority chat states

* feat(web): simplify secondary chat details

* style(web): simplify secondary chat hierarchy

* fix(web): keep execution state out of artifacts

* fix(web): use icons for artifact operations

* style(web): frame todo disclosure header

* fix(web): clarify artifact and tool semantics

* fix(web): clarify chat disclosure hierarchy

* fix(web): keep execution history neutral

* fix(web): simplify user action cards

* fix(web): align failure card actions

* fix(web): refine chat action hierarchy

* fix(web): address chat disclosure review feedback

* fix(web): restore chat recovery actions

* fix(web): make collapsed action details inert

---------

Co-authored-by: xiaoche-hub <298951296+xiaoche-hub@users.noreply.github.com>
2026-07-21 07:44:52 +00:00
PerishFireandGitHub 20c6c0a6ed ci(e2e): shard the full UI functional pool into a merge-ready matrix (#5883)
* ci: benchmark deduplicated UI merge sentinel

* ci: benchmark restoration-hosted sentinel

* ci: benchmark distributed P0 sentinel

* ci: benchmark split P0 sentinel

* ci: serialize split sentinel benchmark

* ci: finalize deduplicated UI merge topology

* ci: prototype all-shades UI domain topology

* ci: bound full UI runtime by shade

* test(e2e): stabilize full UI suite

* fix(web): unclip DS picker popover and propagate patched project metadata

Two regressions surfaced by re-enabling the full UI pool:

- The New Project design-system popover lost its portal and was clipped by
  short viewports and the modal body. Render it through createPortal with a
  viewport-aware anchor that flips upward when space below runs out.

- After a working-dir pick, onProjectMetadataChange forwarded only the
  metadata onto a stale project copy, so ProjectView.currentProject's
  recency comparison let an older useProjectDetail snapshot shadow the
  accepted PATCH and the picker label never updated. The callback now
  carries the daemon's authoritative post-patch project (fresh updatedAt
  included), matching the design-system switch path, and ProjectView hands
  it straight to onProjectChange.

* test(e2e): repair remaining stale full-suite UI contracts

Second repair batch for the failures surfaced by full diagnostic run
29480362163, plus one CI-invisible case that was serially skipped behind
the BYOK failure in the same file:

- Point the working-dir metadata spec at a directory that exists on the
  runner instead of a hardcoded absolute path, and assert the label from
  the picked path (this spec is red without the ProjectView patched-project
  fix).
- Navigate back to All project files before asserting the plugin-folder
  cards, since a finished run auto-opens the produced file tab.
- Resolve the create-run response race in real-daemon-run's sendPrompt via
  a single waitForResponse alongside the click.
- Refresh selectors and copy for entry topbar, home hero rail, chat todo
  autoscroll, project management, workspace keyboard, design files, manual
  edit, restoration, and DS picker clipping flows to match the current UI
  contracts while keeping each spec's oracles.

* ci: distribute the full UI suite over a generic 8-shard matrix

Replace the diagnostic four-domain P0/P1/P2 serial topology with a single
all-shades Playwright invocation per shard (--shard=N/8, two fully
parallel workers, 20-minute cap) and drop the scheduled trigger; full runs
stay manual until the merge-queue wiring lands. Update the workflow
topology guard accordingly.

* ci: serialize full UI shards and widen the matrix to twelve

The eight-shard two-worker experiment left six light shards healthy
(260-477s test steps) but both shards holding runtime-heavy files
degraded: repeated two-minute timeouts with retry recovery in one, and a
consistent create-run response starvation failure in the other. This
matches the earlier finding that runtime-heavy scenarios cannot share a
runner under two fully parallel workers. Run each shard with a single
worker and rebalance to twelve shards; fully-parallel stays on only for
test-granularity sharding.

* fix(web): preserve prompt-extracted plugin inputs across apply reconcile

The active-plugin apply reconcile rebuilt the inputs from the bind-time
optimistic snapshot, so edits the user typed during the apply roundtrip
(already extracted into active.inputs by handlePromptChange) were silently
reverted to defaults — the submitted pluginInputs then disagreed with the
visible prompt. Merge the apply result's defaults into the current inputs
inside the functional updater instead, mirroring the guard the prompt-text
reconcile already had.

* test(e2e): stabilize home gallery flows for all-shades execution

Generic all-shades sharding executes tests in orders the shade-filtered
domain topology never produced, exposing a home-surface remount window:
the async projects fetch can mount or remount HomeTemplatesReveal after a
test starts interacting, collapsing the gallery (inert) under the test's
cursor. Stabilize the shared helpers instead of individual specs:

- gotoEntryHome arms a projects-list response waiter before navigating and
  holds until it settles.
- revealHomeTemplates requires the revealed state (or a true pass-through)
  to survive a settle window, retrying when the wrapper mounts late; a
  card's isVisible() is true inside the collapsed container, so
  openHomePluginDetails now always routes through the reveal path.
- The browse-registry spec reveals before clicking.
- The DS-picker options moved out of the new-project-modal subtree with the
  portal fix; query the page-level popover per the clipping spec's
  convention.
- real-daemon-run's sendPrompt reports on timeout whether POST /api/runs
  was ever issued, so the CI-only BYOK failure can be split into
  swallowed-click vs unanswered-request on the next reproduction.

* test(e2e): make BYOK availability hermetic and reveal remaining gallery clicks

The BYOK missing-provider spec could only pass on machines with a real
`opencode` binary: daemon detection maps byok-opencode's availability
through the `opencode` agent's configured cli env, and the web composer
refuses to POST /api/runs for an unavailable agent (the sendPrompt
diagnostic confirmed "was never issued" on CI). Point the helper's
agentCliEnv at the fake opencode runtime — the run still fails pre-spawn
on the missing provider config, so the fake binary never executes.

Also route the two remaining collapsed-container gallery clicks (the
browse-registry starter journey and the detail-use force-click) through
revealHomeTemplates; an inert container swallows force-clicks silently.

* ci: probe a 24-shard full UI matrix against the four-minute wall target

The first green 12-shard run put eleven shards at 141-354s test steps but
concentrated the contiguous runtime-heavy chain in one 894s shard, setting
a ~16-minute wall tail. With ~3568 total test-seconds and ~90s per-job
overhead, 24 shards should land every job near four minutes.

* ci: settle the full UI matrix on twelve shards

The 24-shard probe stayed green but proved the runtime-heavy chain is a
serial group (test.describe.configure serial in real-daemon-run), which
Playwright keeps atomic within one shard: the tail stayed ~16 minutes while
the extra twelve cold starts raised aggregate runner time from ~76 to ~102
minutes. Twelve shards dominate; lowering the wall below the serial-chain
floor is a de-serialization follow-up, not a shard-count knob.

* test(e2e): drop serial mode from shard-splittable files

Playwright keeps a serial group atomic within one shard, so
real-daemon-run's file-level serial made its ~16-minute chain the floor of
the full UI matrix wall regardless of shard count. Every test in the three
serial files already performs its full setup per test (config reset,
route stubs, own project), so serial only added skip-after-failure and
shard atomicity. Verified order independence by running each file's two
standalone shard halves locally (fully parallel sharding, one worker):
21/21, 57/57, and 12/12 across the halves.

* test(e2e): settle the projects fetch in real-daemon-run home navigation

With serial mode gone, the plugin-authoring spec runs after arbitrary
shard predecessors, so the daemon holds more projects when it navigates
home; the late-resolving projects list re-renders the hero and left the
shortcuts trigger unstable for the whole click timeout on CI. Port the
projects-settle waiter already used by entry-chrome-flows into this
file's gotoEntryHome.

* test(e2e): name the plugins-load gate in the plugin authoring spec

The home shortcuts trigger is disabled while the plugins list loads, and
this spec's mid-flow reload re-fires that fetch after gotoEntryHome's
settle has already passed — on CI the click then times out opaquely for
120 seconds. Arm a response waiter across the reload and assert the
trigger's enabled state explicitly, so a slow or hung /api/plugins fails
with the actual cause named.

* test(e2e): enter plugin authoring through the plugins page create button

The home shortcuts trigger sits disabled on CI runners while a home
plugin apply hangs (plugins list resolves, the pending-apply gate never
clears); three reproduction attempts confirmed the anomaly is CI-only
and independent of this journey. The create button on the Plugins page
drives the same queuePluginAuthoring flow, and this spec's oracle is the
generated scaffold plus its action cards, so route the entry there and
track the disabled-trigger anomaly separately.

* ci: let configure-ci-parallelism drive full UI shard workers

The single-worker override predates the repairs that explained the
two-worker instability (BYOK agent availability and the reveal remount
race, both test-side and since fixed), so it was pinning throughput on a
stale diagnosis. Drop it and let the repo's nproc/2 convention apply —
two workers on the four-core ui_hot profile — halving the per-shard test
step if the runtime holds.

* ci: probe three full UI workers against Blacksmith's actual vCPU capacity

The ui_hot profile resolves to blacksmith-4vcpu runners that reportedly
provide six actual vCPUs while nproc's cgroup view says four, so the
nproc/2 convention derives two workers and idles capacity. Pin three
workers for this probe and print the CPU topology alongside for
verification.

* Revert "ci: probe three full UI workers against Blacksmith's actual vCPU capacity"

This reverts commit 63c8296ae0ead2c3dadfbfda41f6e068d58331ef.

* ci: skip the critical fallback for pure packaged-leaf changes

Playwright starts tools-dev web (daemon + web runtimes) and never
launches the desktop, packaged, or tools-pack entrypoints, so PRs
confined to apps/desktop, apps/packaged, or tools/pack were paying the
two-job critical fallback (5.4-13.4 minutes of wall each) for coverage
their package tests and preflight already provide — seven of the eight
fallback PRs in the latest 100-merge sample were such false positives.

Add a fail-closed ui_critical_validation_required scope: it clears only
when every non-exempt changed file sits under one of those three leaf
roots. tools-dev, any transitive package (including the undeclared
metatool edge), scripts, runtime resources, unknown roots, and mixed
leaf + runtime changes keep the fallback armed; root manifests keep
enabling P0 with the existing critical/P0 mutual exclusion; merge-group
full mode is unchanged.

* test(e2e): align question-form specs with inline Studio discovery

Rebasing onto main picked up #5496, which moved clarification forms
inline into the chat flow and removed the legacy Questions workspace
tab. Re-point the submit-persistence spec at the inline form, and fix
the oracles that no other lane had verified since: the answered summary
echoes the picked visual-style card title (not the option label), and
the submitted answer message carries the card title plus its value id.

* test(e2e): absorb post-rebase drift in BYOK gating and zh-CN hero copy

Two more contracts only the full pool guards moved under the rebase:

- The composer's BYOK gate silently swallows submits until the
  incremental /api/agents stream has delivered byok-opencode's
  availability, so a fast submit races the stream (the sendPrompt
  diagnostic reports the POST was never issued). Retry through that
  window; runErrorCard reads the last card, so swallowed attempts cannot
  shadow the provider-validation oracle. The gate erroring instead of
  waiting while agents are still loading is a product-side follow-up.
- The home hero title copy changed in every locale; re-point the zh-CN
  P2 smoke at the current translation.

* test(e2e): align gallery specs with the all-types default slice

The Community gallery now defaults to an All category pill (#5759)
instead of pre-selecting Deck: assert the new default state in the hero
and category-tab specs, and have the facet-filter spec pick Deck
explicitly before asserting the deck-only visibility set.

* test(e2e): align the first-run reveal spec with the all-types default slice

Same #5759 drift family as the entry-chrome-flows gallery specs, missed
by the first sweep because it lives in home-hero-rail: the revealed
gallery now shows the All pill selected instead of hiding it with
live-artifact pre-selected.

* docs(e2e): add UI test stability rules distilled from the full-pool work

Capture the invariants a UI test must hold to stay green under the generic
sharded full pool, learned from stabilizing that suite and two rebases:

- order independence (no serial groups; setup is per-file, not universal),
  and that neither shade-filtered local runs nor merge-path P0 prove it;
- retry-only passes are an order-leak/readiness signal, not flake;
- settle async surfaces (best-effort waiter + a state-survives-a-window
  check) before interacting;
- an enabled control is not a ready control when a streamed precondition
  (e.g. BYOK-OpenCode agent availability over the /api/agents SSE stream)
  gates it;
- never force-click into inert/collapsed reveal containers; use
  actionability, not visibility, as the readiness signal;
- hermetic agent availability via route mocks (with the terminal SSE `done`
  event) or fake CLI runtimes + agentCliEnv, never host binaries;
- realign stale oracles against the product and confirm them in the lane
  that actually executes the case, since a merged PR does not verify P1/P2
  or unregistered-file P0 oracles;
- name failure causes so a CI-only reproduction carries its own evidence.

Cross-linked from the top-of-file coverage-status pointer.

* test(e2e): realign BYOK missing-provider spec to the #5745 client-side preflight

main #5745 added a client-side BYOK preflight that blocks a missing-provider
run before any POST and opens the execution Settings section, instead of
letting the run reach the daemon and fail there. Rewrite the spec to the new
"blocked before spawn" behavior: submitting opens the execution-mode dialog,
no create-run request is issued, and no artifact is produced (persisted
across reload). This drops the now-obsolete daemon-failed-run assertions and
the SSE-availability retry loop, which the preflight makes unnecessary.

* docs(e2e): explain why the functional config ignores visual specs

Clarify that visual-*.test.ts are owned by playwright.visual.config.ts and
its playwright_visual lane, so excluding them from the functional config is
intentional scope (it keeps a bare test:ui or the full-pool shard run from
executing visual specs without their visual config), not a disabled lane.

* fix(web): portal the New Project brand-preview flyout with the popover

The earlier DS-picker unclip portaled the popover list but left its companion
brand-preview flyout on the old inline `position: absolute` against the
trigger wrapper. Once the popover moved to a body portal, the flyout for a
finalized `user:<id>` brand was still clipped by the modal body and no longer
anchored to the popover. Portal the flyout too and place it beside the
popover with the same viewport-aware logic (right of it when the 320px card
fits, else flipped left, then clamped), mirroring the popover's up/down
vertical anchor.

Red spec: e2e/ui/new-project-ds-picker-clipping.test.ts
"finalized-brand preview flyout is not clipped by the modal body" — red with
the popover portaled but the flyout inline, green with this change.
2026-07-20 09:25:09 +00:00
3447f60a34 fix packaged payload desktop handoff (#5678)
* fix packaged payload desktop handoff

* fix beta mac full smoke fixture wiring

* fix tools-pack mac payload cold start

* test payload desktop update restart

* fix Nix daemon launcher protocol build

* fix(pack): harden Windows long-jump updates

* fix(pack): harden mac long-jump acceptance

* fix(handoff): defer armed journal writes until spawn and shutdown succeed

Previously executeLegacyPayloadDesktopHandoff wrote the armed handoff
journal, attempt, and runtime state before spawning the payload desktop
and before the old desktop accepted shutdown. When spawn() threw or the
shutdown request failed, the armed journal was stranded on disk, so the
next cold start bailed out of prepareLegacyPayloadDesktopHandoff() with
reason "already-armed" and the install stayed pinned to the old desktop
generation indefinitely.

Move the three writes to after both the payload child has spawned and the
shutdown has been accepted. The old desktop is still alive while it acks
the shutdown, and the payload waits for the old pid to exit before
resuming, so the state still lands before the payload reads it. Add
regression coverage for both the spawn-failed and shutdown-failed paths,
asserting the journal stays "prepared" and a later cold start can retry.

Generated-By: looper 0.10.3 (runner=fixer, agent=claude-code)

* fix(updater): await payload spawn acceptance

* fix(packaged): advance confirmed handoff recovery

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-20 02:21:49 +00:00
netteeandGitHub 6b90486c97 docs: reconcile stale documentation with current code (#5829)
* fix(docs): align question guidance with form flow

* docs: reconcile stale documentation with current code

* fix(docs): remove retired template metadata from guides

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(e2e): stabilize visual workspace helper

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)

* fix(docs): align localized template guide metadata

Generated-By: looper 0.10.6 (runner=fixer, agent=codex)
2026-07-18 03:41:08 +00:00
lefarcenandGitHub 19de7953c4 Fix Open Design example logo loading (#5765)
* Fix Open Design example logo loading

Generated-By: looper 0.0.0-dev (runner=worker, agent=codex)

* Stabilize visual home cold start checks

Generated-By: looper 0.0.0-dev (runner=worker, agent=codex)
2026-07-17 06:35:01 +00:00
lefarcenandGitHub cb5fd3baab fix(web): auto-fit wide html previews (#5751)
* fix(web): auto-fit wide html previews

Generated-By: looper 0.0.0-dev (runner=worker, agent=codex)

* test(e2e): allow auto-fit preview zoom

Generated-By: looper 0.0.0-dev (runner=worker, agent=codex)

* fix(web): gate preview auto-fit on content width

Generated-By: looper 0.0.0-dev (runner=worker, agent=codex)

* fix: measure preview width through iframe bridge

* fix: bridge powered preview sizing
2026-07-17 06:16:04 +00:00
265aa51630 feat(web): make Studio discovery visual and inline (#5496)
* feat(web): make Studio discovery visual and inline

Move clarification forms into the chat flow, add artifact-aware visual style choices, and keep follow-up actions hidden until discovery is complete.

* feat(web): keep clarification entirely in chat

Remove the legacy Questions workspace tab, preserve discovery analytics in the inline form, and keep Skip, Submit, and answered summaries in one conversation flow.

* docs: split Studio Chat input and response work

Frame visual discovery as the input-side initiative and record response aggregation as a separately reviewed follow-up so the current PR stays bounded.

* docs: reorganize Studio Chat experience plans

Separate the overall journey, visual discovery, and response architecture so each scope can be reviewed and delivered independently.

* docs: define first-artifact satisfaction prompt

Limit the feedback prompt to the first successful previewable artifact so it gathers a useful signal without interrupting every iteration.

* docs: keep Studio Chat plans independent

Preserve the existing discovery proposal as one document and keep response architecture as a separate review surface without an extra master layer.

* fix(web): preserve inline discovery behavior

Keep visual direction single-select while restoring custom input, optional auto-continue, analytics, and current end-to-end coverage for the inline flow.

* fix(web): preserve files when skipping discovery step

* fix(web): exclude skipped file answers

* fix(web): align inline discovery with slim prompt

Preserve the latest discovery contract while keeping inline forms, uploads, drafts, and schema-driven visual selections consistent after the rebase.

* feat(web): add style catalog preview images

* fix(web): clarify discovery form completion

* fix(web): preserve question form context

* fix(web): time out unanswered question forms

* test(web): cover inline question form next steps

* fix(web): roll back partial inline uploads

* ci: trigger validation after rebase

* fix(web): unlock blocked inline question submits

* fix(web): retain previewless visual answers

* fix(web): load visual style previews from R2

* fix(web): clean blocked inline uploads

* test(web): expect R2 style preview assets

* feat(web): show full visual style catalog

* fix(web): keep inline question answers consistent

---------

Co-authored-by: xiaoche-hub <298951296+xiaoche-hub@users.noreply.github.com>
2026-07-16 06:57:43 +00:00
lefarcenandGitHub 24c7876b37 fix(web): preserve delivery for in-place HTML edits (#5689) 2026-07-15 10:48:26 +00:00
lefarcenandGitHub d7463072a8 fix(web): Plan 模式生成/重写 HTML 后自动打开生成的文件 (#5602)
* fix(web): re-focus HTML rewritten in place when a turn ends

Plan mode's core loop is plan -> generate -> edit the plan -> regenerate.
On the second generation the deliverable (index.html) already exists, so
the turn-end auto-open — a pure pre/post file-NAME diff — saw no new file
and left the viewer stuck on the markdown plan. Protocols that emit no
Write tool events (codex, gemini, opencode, ACP agents) have no per-write
fallback, so nothing opened at all.

Turn-end selection now also considers pre-existing project files whose
mtime lands inside the turn window (same attribution as AssistantMessage's
inferProducedFilesFromTurn), ranked by the existing HTML > markdown
preview priority. Turns without a start stamp keep the produced-only
behavior.

Red spec: e2e/ui/real-daemon-run.test.ts "Plan mode regeneration re-opens
the existing generated HTML file" (red on main, green here), plus a
first-generation companion spec and unit coverage for the new selector.

Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)

* worker: Plan模式下,不会自动打开生成的HTML文件

Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)

* fix(web): scope the turn-window auto-open to agent-touched files and bound it by turn end

Review follow-ups on the Plan-mode auto-open selector: the mtime
attribution window [turnStartedAt - 1s, +inf) could attribute a file the
USER was editing to the turn - in Plan mode plan.md autosaves from the
split editor during a run, so a text-only turn could yank focus back to
it - and the missing upper bound let post-turn edits fall in-window on
the reload/reattach recovery call sites.

selectAutoOpenTurnArtifact now accepts:
- agentTouchedFileNames: when the protocol emits Write/Edit tool events
  (claude stream-json), mtime-window candidates are restricted to files
  the agent actually wrote; protocols with no write events (codex,
  gemini, opencode, ACP) pass an empty set and keep the pure time
  window - the case the window exists for.
- turnEndedAt: bounds the window at endedAt + 60s, matching
  AssistantMessage's inferProducedFilesFromTurn on both sides; callers
  without an end stamp keep the open-ended window.

All three call sites resolve the agent's raw tool paths to project file
names through the existing findTouchedProjectFile matching (new
resolveAgentTouchedFileNames helper) and pass their terminal timestamp.

Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)

* chore: untrack the looper task-attachment directory

The runner's fallback lifecycle commit (a838f8a) accidentally captured
.looper-attachments/bug15_1.png (1.2 MB task-reference screenshot).
Those files are task-local reference material and must stay out of git;
remove them from the tree without rewriting pushed history.

Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)
2026-07-14 11:58:53 +00:00
lefarcenandGitHub bc5b6f0588 fix(daemon): flag runs that end with unfinished work so status never reads "Completed" early (#5470)
A design-generation run that ended its turn with TodoWrite tasks still
pending / in_progress / stopped — or was truncated by max_tokens — was
stamped `succeeded` and read "Completed" on the Pet task center and the
project pill, while the chat footer simultaneously read "Stopped with
unfinished work". Users trusted "Completed", assumed the work was done, and
re-requested, creating duplicate generations and eroding trust in the
run-state UI (#1247 / #1060).

Root cause: the daemon equates "the turn/process ended" with "succeeded" and
never consults the agent's own declared work; multiple web surfaces then map
`succeeded` -> "Completed" without any completeness signal, even though the
chat footer already distinguishes unfinished work.

Fix — one canonical signal, consumed everywhere so the surfaces cannot drift:

- packages/contracts/api/run-completeness.ts defines the canonical
  "unfinished declared work" predicate (status !== 'completed', so pending /
  in_progress / stopped all count), matching the web footer's
  unfinishedTodosFromEvents exactly.
- Daemon folds the last TodoWrite snapshot + a max_tokens truncation off the
  agent event stream (every runtime, via the single emitAgentEvent choke
  point) and derives run.endedWithUnfinishedWork once at finish().
- The project-status projection derives `incomplete` from the already
  persisted events_json — no schema migration — so it survives reload/reattach
  instead of flashing "Completed" once the in-memory run ages out.
- Contracts carry endedWithUnfinishedWork on ChatRunStatusResponse and the SSE
  end payload (backward compatible: absent = finished), plus a new
  `incomplete` ProjectDisplayStatus.
- Web surfaces (Pet task center, project pill, DesignsTab) render `incomplete`
  as amber needs-attention, never the success color; the footer now sources
  the same shared predicate.

Truncation uses the display-only option (spec Option A): the run stays
`succeeded` but is flagged incomplete, avoiding the code===0 / stdin-close
hazards of reclassifying a truncated turn to failed.

Regression coverage, red on main / green here: an HTTP-boundary e2e
(e2e/tests/dialog/task-completeness.test.ts) drives the interactive chat path
for unfinished / stopped / truncated / finished runs; daemon + contracts +
web unit tests pin the projection and the canonical predicate.

Ref: https://plane.powerformer.net/open-design/projects/49832a02-3158-4faf-bf2f-d0e39c40c7e6/issues/011f6f51-7a25-4043-ae94-182e0b8b0931

Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)
2026-07-13 04:17:24 +00:00
bc6a246c65 feat(slides): enhance deck project experience (#5083)
* feat(deck): enhance slide deck functionality with speaker notes and navigation improvements

- Added a switch for including speaker notes in slide decks, defaulting to true.
- Updated keyboard navigation to include 'R' for resetting to the first slide.
- Implemented click navigation for half-slide transitions.
- Enhanced the deck framework to support hidden programmatic prev/next controls.
- Improved handling of file inputs in question forms to support file submissions.

This update aims to improve user experience in creating and presenting slide decks, ensuring better accessibility and functionality.

* feat(artifacts): enforce semantic naming for user-facing deliverables

- Updated guidelines to require semantic filenames derived from user briefs for new artifacts, moving away from defaulting to `index.html`.
- Enhanced documentation to clarify naming conventions for HTML files, emphasizing the use of descriptive names like `investor-pitch-deck.html`.
- Adjusted prompts and hints across the system to reflect these changes, ensuring consistency in user-facing outputs.
- Improved test coverage to validate the new naming conventions and ensure proper implementation in various contexts.

This update aims to enhance clarity and usability in project file management, promoting better organization and user experience.

* feat(file-viewer): enhance speaker notes display and improve file workspace functionality

- Updated the speaker notes section to include a styled placeholder for empty notes, improving user experience.
- Changed the icon in the file workspace from "slides" to "panel-left" for better clarity.
- Introduced new sub-category filtering options in the file workspace, enhancing organization and navigation.
- Improved styling for the page creator search input and added visual feedback for loading states.

These changes aim to enhance usability and visual consistency across the file viewer and workspace components.

* test(web): align workspace tests with pages switcher

* test(e2e): open design files through pages menu

* fix(deck): keep source mode reachable

* fix(workspace): restore uploaded file tabs

* feat(deck-thumbnail): implement virtualized thumbnail rail for improved performance

- Introduced a new `DeckThumbnailRail` component to optimize the rendering of deck thumbnails, reducing memory usage and improving load times.
- Enhanced the `FileViewer` to integrate the new thumbnail rail, allowing for lazy loading of thumbnails based on viewport visibility.
- Added tests for the `DeckThumbnailRail` to ensure correct functionality and caching behavior.
- Updated styles for better visual consistency and performance during thumbnail rendering.

These changes aim to enhance user experience by providing a smoother and more efficient way to navigate through deck slides.

* feat(deck): enhance deck rendering with thumbnail support and keyboard shortcuts

- Integrated `DeckSlideThumbnail` for rendering individual slides in a shadow root, improving performance and reducing main-thread load.
- Updated `DeckThumbnailRail` to utilize the new thumbnail component, allowing for efficient slide navigation.
- Implemented keyboard shortcuts for deck navigation, enhancing user experience during presentations.
- Added tests for `buildDeckRenderInput` to ensure proper functionality of the deck stage fallback.
- Improved styling for loading states in the viewer, providing a smoother visual experience.

These changes aim to optimize the deck viewing experience by reducing resource consumption and enhancing interactivity.

* feat(deck): improve thumbnail loading and speaker notes editing experience

- Refactored `DeckSlideThumbnail` to enhance loading states with a new shimmer effect, improving visual feedback during thumbnail rendering.
- Updated `DeckThumbnailRail` to manage loading states for thumbnails, ensuring a smoother user experience.
- Simplified the speaker notes editing interface by removing the toggle switch, allowing direct editing from the notes body.
- Enhanced accessibility by adding roles and focus states to speaker notes elements.
- Added tests to verify the new loading states and speaker notes functionality.

These changes aim to optimize the user experience in deck navigation and speaker notes management, providing a more intuitive and responsive interface.

* feat(file-viewer): enhance version export functionality and speaker notes interaction

- Introduced new export options for file versions, including PDF and image formats, improving the ability to download and share content.
- Implemented a streamlined process for exporting version content, with progress indicators and error handling for a better user experience.
- Enhanced speaker notes editing by refining event handling to prevent unintended focus shifts, ensuring a smoother editing experience.
- Updated styles for improved visual consistency in the file version download interface.
- Added tests to verify the functionality of version exports and speaker notes interactions.

These changes aim to optimize the file viewer's usability and enhance the overall experience when managing and exporting project files.

* fix(web): polish export menus and creator filters

* fix(file-viewer): fall back to preview exports

* test(file-viewer): cover version export fallbacks

* test(file-viewer): assert loading skeleton by role

* fix(file-viewer): restore html source mode affordance

* fix(file-viewer): capture full version fallback snapshots

* docs: trim slides handoff eof

* test(exports): cover full preview snapshot requests

* test(file-viewer): account for snapshot options arg

* refactor(file-viewer, file-workspace): streamline export functions and enhance page creator dialog visibility

* test(file-workspace): enhance slide template creation and mock plugin responses

* feat(export): add support for versioned exports and enhance HTML export functionality

* feat(export): implement versioned export support across multiple formats and enhance related tests

* feat(file-viewer): enhance manual edit functionality with commit sequence tracking and add test for inline text session saving

* style(speaker-notes): update filmstrip and thumb-frame styles for improved responsiveness and add corresponding tests

* feat(file-viewer): enhance comment composer functionality with portal metrics and improve draw toolbar layout for mobile views

* feat(analytics): track slide deck viewing experience

Add analytics for the new deck/slides experience introduced in this PR:
the deck viewer surface, in-deck slide navigation, thumbnail rail, and
speaker-notes authoring. Presentation entry stays on the existing
present_popover click to avoid double-counting.

- contracts: DeckViewerSurfaceViewProps (surface_view),
  DeckViewerClickProps (ui_click), SpeakerNotesSaveResultProps
  (new speaker_notes_save_result event), wired into the event unions.
- web: track* wrappers + fire helpers in FileViewer — deck_viewer
  surface_view on deck mount, slide_prev/next/reset, thumbnail_select,
  thumbnail_rail_toggle (expand/collapse), speaker_notes_edit, and
  speaker_notes_save_result (preview + presenter surfaces).
- tests: deck analytics suite asserting the emitted (event, props) pairs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(file-viewer, file-workspace): enhance export toast functionality and improve localization for page creation

* feat(home-view, plugins-home-section, agent-skill): update default facet preference, enhance category selection handling, and improve localization support

- Set `preferDefaultFacet` to true in HomeView component for better user experience.
- Introduced `handlePickCategory` function in PluginsHomeSection to manage category selection based on card layout visibility.
- Updated PRIMARY_CATEGORIES to reflect the new order and added localization for titles and descriptions in adaptAgentSkill.
- Enhanced tests to verify the correct handling of display copy and tags from SKILL frontmatter.

* feat(plugins-home, file-workspace): introduce commercial category labels and enhance deck handling

- Added a new module for resolving and localizing commercial category labels for plugins.
- Updated the FileWorkspace and PluginCard components to display the commercial category label on deck cards.
- Enhanced the PageCreatorPresetFrame to adjust frame classes based on deck presets.
- Refactored subcategory handling in facets to align with the new commercial category taxonomy.
- Improved localization support for new category labels across multiple languages.

* feat(deck-preview): implement deck preview scaling and enhance home hero layout

- Introduced `useDeckPreviewScale` hook to manage scaling of deck previews within a fixed 1280×720 logical viewport, ensuring proportional rendering across various templates.
- Updated `FileWorkspace`, `HomeHero`, and `PluginCard` components to utilize the new scaling functionality for improved visual consistency.
- Enhanced the layout of the home hero section to accommodate new subtype chips and descriptions, including a "More" dropdown for overflow handling.
- Improved localization support for new UI elements across multiple languages.

* fix(PreviewModal): clarify sidebar prop documentation and update test description

- Updated the documentation for the `PreviewSidebar` interface to specify that the sidebar's stage-edge handles are not shown when the sidebar prop is absent.
- Modified the test suite description for `PreviewModal` to be more concise and relevant.

* test(e2e): select prototype visual card

---------

Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 09:41:47 +00:00
9ef4f0daa6 [codex] Refine privacy consent choices (#5384)
* Refine privacy consent choices

* Add privacy consent value copy

* Polish privacy consent copy

* Refine privacy banner wording

* Fix privacy consent review issues

* chore: retrigger privacy consent CI

* Fix privacy banner dismissal in AMR onboarding tests

* Fix privacy choice telemetry preservation

* Preserve settings draft during privacy choice

* Preserve pending settings privacy choices

* Align privacy policy consent labels

---------

Co-authored-by: elifive555555 <296440099+elifive555555@users.noreply.github.com>
2026-07-10 02:39:28 +00:00
Marc ChanGitHubopen-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
b3356807b6 fix(amr): improve unavailable model gating (#5335)
* fix(amr): honor full model list metadata

* fix(amr): classify tier entitlement failures

* fix(amr): refine unavailable model upgrade affordance

* fix(web): restore stale AMR model fallback

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(web): surface AMR tier upgrade failures

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): mirror chat upgrade attribution

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): skip disabled default models

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): honor catalog default model

* chore(pack): bump vela cli to 0.0.20

* fix(amr): align locked catalog fallback state

* chore(nix): refresh pnpm deps hash

* fix(amr): refresh entitlement-aware model state

* fix(amr): refresh models after upgrade return

* fix(amr): preserve default model analytics

* fix(amr): tighten model gating follow-ups

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): repair default and refresh follow-ups

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): resolve explicit default before spawn

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): concretize default model in smoke paths

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): repair default model gating

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

* fix(amr): share connection-test model cache

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

---------

Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
2026-07-09 10:37:26 +00:00
AmyandGitHub 39c8eea0c5 test: cover recent daemon and e2e follow-ups (#5354)
* test(e2e): cover recent main follow-ups

* test: cover recent main automation gaps
2026-07-09 10:18:59 +00:00
08da51b3b4 test: expand daemon and UI e2e coverage (#5107)
* test: expand daemon and UI e2e coverage

* fix: refresh retry assistant metadata

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* fix: persist inherited run session mode

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* fix: stabilize AMR inline auth retry

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* fix: reconcile legacy chat assistant pins

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* test: stabilize fake AMR auth recovery

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* test: restore e2e interaction actionability

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* test: address review feedback for PR 5107

* test: stabilize PR 5107 CI interactions

* test: tighten PR 5107 review coverage

* fix: inherit run session mode after conversation fallback

* test: assert AMR promotion retry renders recovery

Generated-By: looper 0.10.1 (runner=fixer, agent=codex)

---------

Co-authored-by: Amy <1184569493@qq.com>
2026-07-09 03:05:42 +00:00
8ca68bbfe6 feat(web): pre-run Open Design Cloud balance gate with subscription dialog (#5103)
* feat(web): Open Design Cloud pre-run balance gate — two-tier dialogs with auto-resume

Gate every AMR chat send before any run spawns. HARD tier (definitive
empty wallet <= $0, or signed out) blocks with a subscription-invitation
dialog: distinct copy and CTA per cause (console wallet page vs in-app
sign-in), benefits card, and auto-resume — a completed sign-in or a
recharge observed by a bounded wallet watch resumes the parked task on
its own. SOFT tier (<= $4) shows a dismissible reminder with top-up /
start-anyway / persisted don't-ask-again (never silences the hard tier).

Blocked project sends park in the conversation queue with their full
payload and pause auto-drain until a send passes the gate; home submits
hold the create open (continuation promise) so drafts and staged context
are never lost, and the home decision carries into the project's first
auto-send to avoid double-prompting. Fail-open contract: unknown or
unparseable wallet answers never block; hard blocks are confirmed with
refresh=1 before firing. New amr_entry sources cover both surfaces and
tiers; nine chat.amrBalanceGate.* / chat.amrLowBalance.* i18n key groups
ship in all 19 locales.

* fix(web): a stale wallet-refresh echo must not confirm a hard block

A failed refresh returns the previous cached snapshot with stale=true and
an error; treating it as a fresh definitive $0 (or signed-out) answer
violated the gate's fail-open contract and could strand a user who just
topped up while the wallet endpoint hiccuped. (Review feedback.)

* chore: retrigger ci

* test(e2e): align AMR UI checks with balance gate

* fix(web): preserve AMR gated sends across conversation switches

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
Co-authored-by: Amy <1184569493@qq.com>
Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com>
2026-07-07 09:20:54 +00:00
AmyandGitHub cd6fb44c4d test: expand e2e coverage for main updates (#4998)
* test: expand e2e coverage for main updates

* test: remove unrelated landing contract coverage
2026-07-03 02:58:21 +00:00
ab45324124 [codex] Restore Kimi ACP and retire Gemini CLI runtime (#5023)
* fix(runtime): restore kimi acp and retire gemini cli

* test(e2e): drop retired gemini fake runtime from p0 sweep

* fix(daemon): clear retired Gemini config

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-07-02 07:47:05 +00:00
Tom HuangGitHubopen-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>Amy
6be4e56544 feat(workspace): add plan mode and Excalidraw sketch flows (#4862)
* feat(daemon): add 'plan' session mode and update related functionality

- Introduced a new session mode 'plan' alongside existing 'design' and 'chat' modes, allowing for editable document creation.
- Updated various functions and interfaces to accommodate the new session mode, including normalization and usage in commands.
- Enhanced markdown rendering capabilities by integrating micromark and its GFM extension for improved markdown processing.
- Added new input types for question forms, expanding the range of user interactions.
- Updated UI components to reflect changes in session modes and ensure proper handling of next steps based on the current mode.

* feat(chat): integrate SessionModeToggle into ChatComposer and HomeHero

- Added SessionModeToggle component to both ChatComposer and HomeHero for improved session management.
- Updated HomeHero styles to accommodate the new mode switcher layout.
- Adjusted countdown timer in QuestionsPanel to extend the skip countdown from 120 seconds to 10 minutes, enhancing user experience.
- Added tests to ensure the countdown functionality works as expected.

* feat(FileViewer): implement synchronized scrolling for Markdown editor and preview

- Added functionality to synchronize scrolling between the Markdown editor and preview panes.
- Introduced new types and utility functions for managing scroll behavior.
- Enhanced the MarkdownViewer component to handle scroll events and maintain scroll position across different modes.
- Updated the component's state management to accommodate the new scrolling features.

* feat(excalidraw): integrate Excalidraw into the project

- Added @excalidraw/excalidraw as a dependency in package.json.
- Updated vitest configuration to include an alias for Excalidraw.
- Imported Excalidraw CSS in the layout component for styling.
- Modified AssistantMessage component to handle optional projectId.
- Enhanced FileOpsSummary to display delete operations.
- Implemented new Excalidraw scene management in SketchEditor and FileWorkspace components.
- Updated MarkdownViewer to support file mentions and improved file handling.
- Refactored various components to accommodate Excalidraw integration and ensure compatibility with existing features.

* feat(files): improve sketch and file handoff flows

* test: align post-merge expectations

* chore(nix): refresh pnpm deps hash

* fix(workspace): stabilize sketch persistence and ci checks

* fix(workspace): address review blockers in editable files

* fix(workspace): persist cleared sketch scenes

* test(workspace): type sketch editor mock scene

* fix(workspace): serialize sketch autosaves

* fix(workspace): keep sketch save revisions current

* test(e2e): stabilize project workspace smoke flows

* fix(analytics): preserve plan mode for BYOK runs

* test(e2e): stabilize new project rail interactions

* fix(files): stop bash delete parsing at shell operators

* test(e2e): stabilize ui cold-start suites

* fix(viewer): preserve absolute markdown image sources

* feat(workspace): preload sketches and enhance markdown save options

- Added functionality to preload persisted sketches before opening the tab.
- Introduced new MarkdownSaveOptions type to manage save behavior.
- Updated saveMarkdownText to handle options for refreshing files and showing saving state.
- Enhanced FileViewer to maintain focus and selection during metadata refresh.
- Implemented a Toast component for user feedback on save and export actions.

* fix(web): stabilize markdown and sketch editor polish

* fix(web): finish sketch editor merge resolution

* chore(nix): refresh pnpm deps hash

* fix(plan): bypass discovery and stabilize markdown sync

* fix(web): simplify scene retrieval in SketchEditor component

* feat(web): enhance markdown viewer with auto-save functionality

- Implemented passive auto-save status in the MarkdownViewer component, replacing the manual Save button with an auto-save indicator.
- Introduced new hooks and state management for tracking auto-save events and displaying the last saved time.
- Added support for synchronized scrolling between the markdown editor and preview.
- Created a new markdown-scroll-sync module to handle scroll synchronization logic.
- Updated localization files to include new strings for auto-save messages.
- Added a SketchEnginePrewarm component to optimize Excalidraw loading times.

* feat(web): enhance session mode toggle with cost indicators

- Added cost tiers for each session mode in the SessionModeToggle component, providing users with a visual representation of usage costs.
- Introduced a new ModeCostTag component to display cost information alongside session mode labels.
- Updated localization files to include new keys for cost labels and notes.
- Enhanced styling for cost indicators to improve user experience and clarity.
- Refactored EntryShell to open the new project modal instead of creating a blank project directly from the rail.
- Implemented a utility function in markdown-scroll-sync to check for vertical progression in block offsets.

* feat(web): add max height adjustment for session mode description card

- Introduced maxHeight prop to the ModeDescriptionCard component to control the height of the description card based on available space.
- Implemented useLayoutEffect in SessionModeToggle to dynamically calculate and set the maximum height of the description card, ensuring it does not overlap with the project tab bar.
- Updated tests to verify that session modes display their expected usage/cost correctly in the UI.
- Enhanced localization files to include new cost-related strings for various languages.

* feat(web): implement goBack function for improved navigation and update auto-open logic

- Added a new `goBack` function to handle in-app navigation, allowing users to return to the previous route instead of a hardcoded destination.
- Updated the `navigate` function to maintain history state for better back navigation.
- Refactored auto-open logic to prioritize produced artifacts, allowing markdown files to be opened alongside HTML files.
- Updated tests to cover new navigation behavior and artifact selection logic.
- Enhanced localization files to include new descriptions for workspace actions.

* refactor(web): remove create design system functionality and update design files panel actions

- Removed the `onCreateDesignSystem` prop and associated button from the DesignFilesPanel component.
- Updated the empty state actions to include a button for creating a new document via the `onPaste` function.
- Adjusted tests to reflect the removal of the design system creation action and ensure the new document button is functional.
- Enhanced the MarkdownViewer component by adding a placeholder for the text area and removing the header bar for a cleaner interface.
- Updated localization files to include a new placeholder string for the markdown editor.

* fix(web): restore markdown placeholder translations

* refactor(web): streamline MarkdownViewer and enhance localization

- Removed unnecessary state management and reload functionality from the MarkdownViewer component for improved performance.
- Added a placeholder text for the markdown editor in multiple localization files to enhance user guidance.
- Updated styles for the save state indicator in the viewer to improve visual clarity and alignment.
- Adjusted tests to reflect changes in the MarkdownViewer and ensure proper functionality.

* fix(web): adjust SketchEditor button size and remove shortcut hints

- Reduced the icon size in the SketchEditor component from 13 to 12 for better alignment.
- Updated the removeSketchMermaidShortcutHints function to also remove the submit shortcut hints from the dialog, enhancing the user interface by decluttering unnecessary elements.
- Adjusted tests to verify the absence of shortcut hints in the modal after updates.

* fix(web): address plan mode follow-up polish

* fix(web): align ci expectations after merge

* test(e2e): stabilize project workspace helpers

* test(e2e): scale settings visual timeout

* fix(prompts): lock ElevenLabs voice picker choices

* test(e2e): pin project workspace P0 worker

* test(e2e): use rail new project entry

* test(e2e): relax app restoration startup waits

* fix(web): limit markdown pipe escaping to tables

---------

Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
Co-authored-by: Amy <1184569493@qq.com>
2026-07-01 04:38:31 +00:00
Tom HuangandGitHub ca89845d03 feat(brands): surface the draft design system live and browse images in a lightbox (#4777)
* feat(brand-extraction): enhance programmatic extraction with reconciliation and UI improvements

- Introduced `reconcileProgrammaticExtractionTranscript` to manage the state of brand extraction transcripts, ensuring accurate status updates during extraction processes.
- Updated the `cancel-extraction` route to handle asynchronous operations, allowing for better user feedback and immediate reconciliation of extraction states.
- Enhanced the `startBrandExtraction` function to support draft design system creation, ensuring that users can see their systems immediately, even if extraction fails or is stopped.
- Improved error handling and logging for reconciliation processes, providing clearer insights into failures during brand extraction.
- Added tests to validate the new reconciliation logic and ensure that the extraction process behaves as expected under various scenarios.

These changes improve the overall user experience by providing more robust handling of brand extraction states and enhancing the visibility of the extraction process.

* feat(brand-extraction): enhance brand preview rendering and UI feedback

- Added functionality to render brand previews into projects when a draft is stopped, improving user experience by providing immediate visual feedback.
- Updated the `startBrandExtraction` function to include metadata for design system IDs and statuses, ensuring accurate tracking of brand extraction states.
- Enhanced the `renderBrandPreviewIntoProject` function to support new status types, including 'draft', allowing for better representation of brand states.
- Introduced new localization strings for draft-related messages, improving clarity for users during the brand extraction process.
- Added tests to validate the new preview rendering and status handling, ensuring robustness in the brand extraction workflow.

These changes improve the overall user experience by providing clearer feedback and enhancing the visibility of brand extraction processes.

* feat(design-kit): browse design-system images in a lightbox carousel

The image-preview lightbox showed a single static image with no way to move
between samples. Replace the single-image state with an index into the
visible, non-broken samples so the modal becomes a carousel: prev/next
chevrons, an "N / total" counter, ArrowLeft/ArrowRight keys, and wrap-around.
Broken tiles are filtered once through a shared lightboxItems memo so the
gallery and lightbox indices stay aligned with the delete handler.

* feat(brands): reveal the draft design system the moment extraction starts

A brand extraction pre-creates a draft `user:` design system, but the project
view only rendered it once the registry summary had refreshed, leaving the
Design System tab empty for the whole extraction. Build a fallback summary
from project metadata so the draft renders immediately, auto-open the Design
System tab when extraction begins or is cancelled, and hydrate the freshly
created project with its brand metadata. Draft pre-create now records the
source URL in provenance and fails loudly instead of swallowing the error.

Because ProjectView imports DESIGN_SYSTEM_TAB at module scope, every
FileWorkspace test mock must export the constant.

* fix(design-system-picker): restore fullscreen preview styles dropped in routines.css reorg

The brand-extraction routines.css reorganization accidentally removed the
`.project-ds-picker-fullscreen` rule block, its `project-ds-picker-fullscreen-in`
keyframes, and its responsive overrides. The modal-window drag guard and two
style specs still depend on those rules (the fullscreen design-system preview
must stay above modal chrome), so they went red. Restore the block verbatim to
match main.

* feat(brand-extraction): add continue extraction functionality for incomplete brands

- Introduced a new API endpoint to restart the deterministic programmatic extraction for existing brands without creating duplicates.
- Implemented a tracking mechanism for ongoing extractions to manage their state effectively.
- Enhanced the UI components to support the new continue extraction action, including loading states and callbacks.
- Updated relevant tests to ensure the new functionality works as expected and integrates smoothly with existing workflows.

These changes improve the user experience by allowing users to resume brand extractions seamlessly, enhancing the overall efficiency of the brand management process.

* feat(skills): integrate skill management into the application

- Added a new SkillDetailsModal component to display detailed information about skills.
- Enhanced the ChatComposer and HomeHero components to support skill selection and details viewing.
- Updated the ComposerPlusMenu to include a skills submenu, allowing users to search and pick skills.
- Implemented functionality to handle skill details in various components, improving user interaction with skills.
- Refactored existing components to accommodate skill-related features, ensuring a cohesive user experience.

These changes enhance the application's capabilities by providing users with better access to skill information and management, streamlining workflows involving skills.

* feat(brand-extraction): improve brand assistant message handling and UI feedback

- Enhanced the AssistantMessage component to better manage events and display content, ensuring that messages are rendered correctly based on their content and events.
- Updated the ChatPane component to hide empty brand assistant messages and improve the visibility of relevant content, enhancing user experience during brand extraction processes.
- Introduced new utility functions to determine the visibility of brand assistant events and content, streamlining the logic for displaying messages.
- Refactored the ProjectView component to handle brand browser assist confirmations more effectively, ensuring that the UI responds appropriately to user interactions.
- Added tests to validate the new message handling logic and ensure that brand extraction messages are displayed correctly.

These changes enhance the overall user experience by providing clearer feedback and improving the management of brand assistant messages during extraction workflows.

* fix(brands): address browser assist review blockers

* fix(web): restore new project modal entrypoints

* fix(web): switch to replacement brand retry conversations

* fix(web): restore skill-change preview invalidation

* fix(brand): harden retry completion flow

* fix(brand): close extraction lifecycle races

* test(e2e): wait for privacy banner dismissal

* fix(brand): guard retry startup races

* fix(brand): isolate extraction retry attempts

* fix(design-systems): clean up partial draft creation

* fix(brands): let stop supersede stalled transcript

* fix(brands): fail thin browser html retries

* fix(brands): preserve stopped html retries

* fix(brands): reject off-path browser retries

* fix(brands): expose deterministic retry in cli

* fix(brands): serialize cancel with finalization

* fix(brands): bound cancel settlement wait

* fix(brands): bound retry takeover waits

* refactor(next-step-actions): replace titles with localized keys and update related prompts

* fix(brands): retry after browser read failures

* fix(brands): accept canonical browser redirects

* fix(brands): reset retry assist stall timer

* test(web): align picker compact preview assertions

* fix(brands): harden design kit cleanup paths

* test(e2e): stabilize AMR runtime recovery checks

* feat(brands): enhance brand extraction from post-wall pages

- Introduced `browserHarvestIsUnusable` function to determine if a harvested page lacks usable brand signals, allowing for more permissive extraction from content-rich pages that may embed anti-bot widgets.
- Updated `extractBrandFromHtml` to utilize the new function, ensuring that valid post-wall pages are processed correctly.
- Enhanced `isChallengePage` to differentiate between genuine content-rich pages and bot protection interstitials, improving the accuracy of brand extraction.
- Added tests to validate the new behavior, ensuring that pages with minimal color palettes or embedded widgets are handled appropriately.

* feat(brands): improve handling of recoverable extraction states

- Refactored brand extraction logic to maintain a `needs_input` status for recoverable scenarios, such as blocked pages or mid-load content, instead of marking them as `failed`.
- Updated related functions and routes to reflect this change, ensuring that the user interface presents a calm, retryable state rather than a terminal failure.
- Enhanced tests to validate the new behavior, confirming that the system correctly identifies and manages recoverable extraction attempts.

* feat(projects): add design-system project creation from existing projects

- Implemented a new command `od project create-design-system` to duplicate a regular project as a design-system workspace, including a prompt for design-system generation.
- Enhanced the API to support the creation of design-system projects, ensuring proper metadata and file copying from the source project.
- Added a detailed prompt structure for the design-system generation process, outlining requirements and expected outputs.
- Introduced tests to validate the new functionality, ensuring that design-system projects are created correctly with the appropriate context and files.
- Updated the UI components to integrate the new design-system creation functionality, allowing users to initiate the process seamlessly.

* feat(projects): add project duplication workflow

* fix(brand): keep browser assist recovery retryable

* fix(plugins): roll back failed template duplicates

* feat(brand): enhance browser assist functionality and improve user guidance

- Introduced a new `brandBrowserAssistOdCard` function to generate browser assist cards for better user interaction.
- Updated the content structure in `reconcileProgrammaticExtractionTranscript` to include browser assist cards when applicable.
- Enhanced user guidance in error messages for stalled and stopped extraction processes, providing clearer instructions for recovery actions.
- Added tests to ensure the new browser assist card functionality is correctly integrated and displayed in the chat interface.
- Improved localization for various user prompts and messages related to browser assist actions.

* feat(design-browser): enhance design file handling and user notifications

- Added support for opening design files directly from the status message in the DesignBrowserPanel.
- Introduced a new `actionTarget` property to differentiate between design files and regular files in status messages.
- Implemented a `stopLoading` function to halt page loading when necessary, improving user experience during snapshot captures.
- Updated localization files to include new status messages and project type labels.
- Enhanced toast notifications for browser snapshots with improved styling and functionality.
- Added tests to ensure new features work as expected and do not interfere with existing functionality.

* feat(app): implement design system project creation with preset prompts

- Updated project creation logic to route through the default design router, ensuring user interaction prompts for design system selection.
- Introduced a new localization key for the design system creation prompt, enhancing user guidance.
- Adjusted plugin ID to avoid assumptions about prototypes, improving the flexibility of project creation.
- Updated tests to reflect changes in project creation behavior and ensure correct routing and prompt handling.

* feat(chat): update icon sizes and implement draft persistence in HomeView

- Increased icon sizes in ChatComposer from 13px to 16px for better visibility.
- Added localStorage persistence for the Home composer prompt and design system selection to retain user input across tab switches.
- Implemented functions to read and write drafts to localStorage, ensuring a seamless user experience.
- Cleared drafts upon run creation to prevent reappearance of previous inputs.
- Enhanced Toast component to handle auto-dismissal correctly, even with changing parent components.

* fix(pr): address review blockers

* fix(web): preserve authoring prompt confirmation

* test(daemon): cover project CLI copy commands

* fix(web): surface skill detail load failures
2026-06-30 13:22:29 +00:00
3652fb7237 [codex] restore AMR wallet balance follow-ups (#4771)
* feat: show AMR wallet balance

* fix: preserve AMR wallet reauth state

* chore: retrigger PR validation

* fix: bound AMR wallet balance fetch

* chore: retrigger wallet validation

* chore: bump bundled Vela CLI to 0.0.18

* chore: retrigger Vela CLI validation

* chore(nix): refresh pnpm deps hash

* feat(web): reposition AMR as Open Design's cloud subscription (#4684)

* feat(web): reposition AMR as Open Design's cloud subscription

Fold the standalone "AMR" product into Open Design's own cloud service:
unify all user-facing copy, surface the signed-in account's plan +
wallet balance, and add upgrade CTAs.

- Copy: user-facing "AMR" / "Open Design AMR" -> "Open Design" across
  19 locales, agent labels, and daemon error strings (balance/recharge
  wording preserved).
- Account: daemon reads plan + balance via `vela billing summary`
  (CLI route, control-key) and injects them into the vela status; web
  shows plan + balance on the settings card, the model-switcher account
  row, and the runtime-switcher avatar row (balance field aligned with
  the console wallet's headline balanceUsd).
- Upgrade: filled "Upgrade" CTA next to the plan on all three surfaces
  when the tier is below max; opens the console wallet at ?view=plans.
- Runtime-switcher Open Design row restructured to carry account info
  inline, with a selected-state highlight.
- Analytics: new amr_entry elements settings_amr_upgrade /
  inline_amr_upgrade / avatar_amr_upgrade / avatar_amr_agent_card.
- specs/: design doc for the Open Design account/avatar direction.

* fix(daemon): surface live account for env-backed auth + isolate cache per credential

Address @nettee review on #4684:
- applyVelaLiveAccount() now populates plan/balance even when the login
  status has user:null (VELA_RUNTIME_KEY / VELA_LINK_URL env auth), so
  env-backed Open Design sessions no longer drop the fetched billing data.
- Key the live-account cache by the full credential revision (auth source
  + profile + userId + config mtime), not just profile, and clear it on
  logout — a logout / account switch can no longer surface the previous
  account's plan or wallet balance before the background refresh runs.
- Regression tests for both in tests/integrations/vela.test.ts.

Sync tests to the AMR -> Open Design copy:
- web: tests/providers/sse.test.ts error-string assertions.
- e2e: onboarding / logout / run-failure / login-pill specs + visual fixture.

* fix(i18n): drop duplicated "Open Design" in switchBody fallback copy

The AMR -> Open Design rename sweep collided with the existing brand
mention in chat.amrCard.switchBody, rendering "Open Design official
Open Design model service" across 13 locales (zh-TW, ja, ko, ar, es-ES,
hu, id, fa, pl, tr, ru, pt-BR, uk). Remove the redundant second mention
so the retry/switch card reads cleanly. Flagged by @nettee on #4684.

Also start aligning InlineModelSwitcher unit tests to the new copy
(agent display name AMR -> Open Design, compact error string).

* fix(amr): resolve live billing before first /status; hide Upgrade until plan known

Address @nettee review on #4684 (two correctness issues in the new
plan/balance path):

- Cold cache: the signed-in /status handler now BLOCKS the first response
  on fetchVelaBillingSummary() when the cache is empty, instead of
  returning config-only and refreshing in the background. The new account
  surfaces read /status once and never re-poll, so the old flow left
  plan/balance hidden until the user refocused. Warm cache keeps the
  non-blocking fast path. fake-vela gains a `billing summary` handler and
  vela.routes.test.ts covers the cold-cache-first-open case.
- Upgrade CTA: canUpgradeVelaPlan() now treats an unknown/empty plan as
  NOT upgradeable, so a signed-in session whose live summary hasn't
  resolved no longer flashes Upgrade at top-tier users. Unit-tested.

* style(amr): bold the plan/balance text in the switcher + avatar account rows

The settings card already renders both bold (the plan value reuses
.agent-card-amr-balance-value); align the inline switcher account row and
the runtime-switcher avatar row so plan + balance read with the same
emphasis everywhere.

* fix(amr): single-flight cold billing fetch + surface plan/balance on its own field

Address @nettee follow-up review on #4684:

- Race: the cold-cache decision keyed off the refresh throttle, so a second
  /status arriving during the first billing fetch saw refreshAccount=false,
  fell through, and returned config-only — which the read-once surfaces can't
  recover from. Now `peekVelaLiveAccount(key) === null` is the cold signal and
  the billing fetch is single-flighted per credential revision: concurrent
  cold callers await the same in-flight promise. setVelaLiveAccount stamps the
  fetch time so the warm path doesn't immediately re-refresh.
- Identity: applyVelaLiveAccount no longer fabricates a `{ id: '', email: '' }`
  user for env-backed sessions. The live billing projection now rides on a new
  VelaLoginStatus.account field, so `user` stays null (preserving the analytics
  `user.id` null signal) and plan/balance are surfaced uniformly. SettingsDialog
  / InlineModelSwitcher / AvatarMenu read status.account.{plan,balanceUsd}.

Regression coverage updated in vela.test.ts (applyVelaLiveAccount) and
vela.routes.test.ts (cold-cache first open now asserts body.account).

* style(amr): match the switcher plan text color to the balance

The inline switcher account row showed the balance in --text-strong but
the plan in --text-muted, so "$247.51 Plus" read with two different
weights of grey. Use --text-strong for the plan too so balance + plan
sit at the same emphasis.

* fix(amr): treat tier-less billing summary as free; register new entry sources

Address @nettee review on #4684:

- Free vs unknown: fetchVelaBillingSummary() returned plan:undefined when
  `membershipTier` was absent, but that field is omitted for free accounts. The
  new surfaces read status.account.plan for both display and canUpgradeVelaPlan,
  so a successful free-account read rendered as "unknown" — plan hidden and the
  Upgrade CTA suppressed for the exact users who should see it. A successful
  summary without a tier now normalizes to the explicit 'free' sentinel;
  "unknown" stays signalled by a null account (failed fetch). Regression in
  vela.routes.test.ts (balance, no tier → account.plan === 'free').
- Analytics: the four entry sources this PR adds (settings_amr_upgrade,
  inline_amr_upgrade, avatar_amr_upgrade, avatar_amr_agent_card) were in the
  source→page map but not in the AMR_ENTRY_SOURCES validator set, so
  parseAmrEntryAnalyticsPayload rejected them and /analytics-entry 400ed for the
  new buttons. Added them to the set; parser regression covers all four.

* fix(amr): invalidate the env-backed live-account cache on config/account change

Address @nettee 11:19 review (the inline comment did not post, but the flagged
env-backed live-account cache path has a real leak): readVelaCredentialRevision
forced configMtimeMs to null for env-backed auth, so the live-account cache key
became `env|profile|1||` with nothing to distinguish accounts. Because the live
billing summary is fetched with the config profile's controlKey, a config
rewrite (account switch) left an env-backed (VELA_RUNTIME_KEY) session serving
the previous account's plan/balance. Keep configMtimeMs for env auth too so a
config/account change yields a fresh key. Regression added in vela.test.ts.

* fix(amr): fingerprint the configured AMR env in the live-account cache key

Address @nettee 11:35 review on #4684: configMtimeMs alone wasn't enough. The
AMR env credentials (VELA_RUNTIME_KEY / VELA_LINK_URL) can come from
agentCliEnv.amr in app-config, and env-backed sessions report user:null — so
switching the Settings-backed credential from account A to B on the same
profile, without touching ~/.amr/config.json, left the revision at
`env|profile|1||<same-mtime>` and let B reuse A's cached plan/balance.

readVelaCredentialRevision now adds a non-secret credentialFingerprint (sha256
of the runtime key + link url, truncated) and velaLiveAccountCacheKey includes
it. Regressions: a unit test (env key differs by fingerprint) and a route test
that rewrites agentCliEnv.amr's VELA_RUNTIME_KEY without touching the config and
asserts the second account does not inherit the first's cached billing.

* feat(amr): label + stack balance/plan in the switcher account row; fix its tests

UI: the inline switcher Open Design account row rendered "$247.51 Plus" with no
labels, so users couldn't tell what the two values were. Balance and plan now
stack on two labelled lines ("可用余额 / Available balance" and "当前套餐 /
Current plan"), with the Upgrade CTA on the plan line. The settings.amrBalance /
settings.amrPlan labels are made descriptive across all 19 locales (the settings
card reuses them), so the meaning is explicit everywhere.

Tests: rewrite InlineModelSwitcher.test.tsx for the account-row structure — the
agent radio now carries status only in its aria-label (icon-only visible), and
the sign-in / signing-in / cancel affordances live on the
inline-model-switcher-account-action button. Redundant within(amrButton)
getByText assertions are dropped (the radio-name query already asserts status);
pending/error assertions target the account row. 22/22 green.

* test(amr): align AmrLoginPill tests to the Open Design copy

Account-status group is labelled 'Open Design account status', the console
link is 'Console', and the compact sign-in error reads 'Sign-in failed.' —
update the queries to match. 29/29 green.

* feat(amr): redesign the account row — tier badge + balance subtitle; short labels

Iterated on the Open Design account row in both the inline model switcher and
the runtime-switcher (avatar) list so the plan/balance no longer collide:

- Plan tier renders as a small neutral pill right after the "Open Design" name
  (identity + tier read as one group, à la Claude's "name · Max").
- Balance moves to a second line below the name, labelled "余额 $247.51"
  (small grey label + bold value) so users know what the number is.
- Upgrade stays as the trailing action, vertically centred against the two
  lines. Account logo bumped to 24px to balance the taller row.
- Revert the amrBalance / amrPlan labels back to the short "余额 / 套餐"
  ("Balance" / "Plan") across all 19 locales.

* test(amr): align remaining web specs to the Open Design copy + account row

Update the rest of the web component specs that still asserted the pre-rename
wording / old account-row shape (the `Web workspace tests` red CI @nettee
flagged):

- EntryShell.onboarding: "Sign in to Open Design Cloud" -> "Sign in to Open
  Design"; "AMR sign-in failed." -> "Sign-in failed.".
- SettingsDialog.execution: AMR card queried as /^Open Design\b/ (was
  /^Open Design AMR\b/).
- HandoffButton: agent label "Open Design"; website link "打开 Open Design 官网".
- AvatarMenu: drop the two obsolete avatar console-shortcut specs (the avatar
  console link was removed when the row was consolidated; the upgrade entry
  remains covered by the daemon parser + contract).

Full web suite green: 3403 passed.

* test(amr): cover the avatar-row upgrade CTA (plan/balance + stamped link)

Replaces the two removed avatar console-shortcut specs with focused coverage
for the new runtime-switcher upgrade path (@nettee): mocks a signed-in
/api/integrations/vela/status, opens the menu on the non-prod `test` profile,
asserts the rendered plan badge + balance, and verifies the clicked upgrade
link carries view=plans and od_entry_source=avatar_amr_upgrade attribution.

* test(e2e): update avatar visual spec to the redesigned account row

The Playwright visual (settings-workspace) job was red on a functional
assertion, not a pixel diff: the spec queried the removed
`.avatar-amr-account-link` console entry and 'AMR account' / 'Balance &
recharge' copy. Rewrite it to override the signed-out status with a signed-in
plan/balance, then assert the Open Design row renders the Plus badge + $247.51
and the upgrade link points at ?view=plans.

* chore: re-trigger CI on updated main — needs-validation gate moved to merge_group (#4714)

* test: capture Open Design account balance visuals

* chore: retrigger workspace validation

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
Co-authored-by: lefarcen <935902669@qq.com>
Co-authored-by: a1chzt <chizblank@gmail.com>

* [codex] keep AMR wallet balance stable during refresh (#4730)

* fix: keep AMR wallet balance visible during refresh

* fix: remove AMR wallet refresh hover tooltip

* chore: retrigger validation

* fix(ci): align AMR wallet branch validation

* feat(web): Open Design 云账户入口 UI 优化(名牌/置顶/新 logo) (#4787)

* feat(web): polish Open Design cloud account surfaces (plan badge, pin-to-top, new logo)

- 模型切换器(InlineModelSwitcher): Open Design 账号卡片上位为可点选入口并置顶, 移除重复的代理行
- 头像菜单(AvatarMenu): Open Design 置顶代码代理列表; 执行模式选中态改为勾选标记(不再与代理选中态争色块)
- 统一套餐名牌: 新增共享 PlanBadge 组件(全局 CSS, 跟随主题色), 替换设置页/切换器/头像菜单三处各自实现
- 设置页 CLI 卡片: 删除无用的钱包刷新按钮与"更新于…缓存"行; 余额统一为两位小数
- 全局替换 AMR logo 资产(amr.svg)

* test(web): align AgentIcon AMR assertion with new logo fill

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>

* fix(web): preserve AMR wallet balance in switcher

* fix(amr): avoid stale wallet status on refresh failures

* fix(web): align avatar AMR balance row

* fix(web): avoid stale AMR wallet snapshots

* fix(web): keep avatar AMR console link

* fix(amr): support wallet fallback for older vela cli

---------

Co-authored-by: michaeltaxman911-hue <michaeltaxman911@gmail.com>
Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
Co-authored-by: lefarcen <935902669@qq.com>
2026-06-30 03:04:52 +00:00
AmyandGitHub b55376554b test(e2e): expand onboarding, AMR, automation, and home coverage (#4759)
* test(e2e): cover onboarding and automation flows

* test(e2e): stabilize AMR project runtime P0 group

* test(e2e): cover updated home creation surface

* test(e2e): align onboarding coverage with build step

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)
2026-06-29 03:56:19 +00:00
aad9771a6f fix(e2e): reduce noisy visual regression diffs (#4744)
* fix(e2e): reduce noisy visual regression diffs

* fix(e2e): keep visual captures full viewport

* test(e2e): add entry popover visual targets

* test(e2e): tighten model dropdown visual targets

* Revert "test(e2e): tighten model dropdown visual targets"

This reverts commit 52172f05591e1a5c2bed7b6fc12d05d364d5b27d.

* fix(e2e): relax visual report diff ratio threshold

* fix(e2e): render visual report comparisons horizontally

* fix(e2e): tighten accepted visual diff ratio

* fix(e2e): surface missing visual baselines as new cases

* fix(e2e): render new visual baselines in a grid

* fix(e2e): compact visual report case layout

* fix(e2e): keep large visual diffs surfaced

Generated-By: looper 0.9.11 (runner=fixer, agent=codex)

* fix(e2e): seed privacy consent in project-runtime tests

* fix(e2e): harden project-runtime settings mocks

* fix(e2e): stabilize project-runtime follow-ups

---------

Co-authored-by: mrcfps <mrc@powerformer.com>
2026-06-26 10:30:22 +00:00
488e3d6a6d [codex] Refine rich design-system chip previews (#4806)
* fix(web): refine design system chip preview

* fix(e2e): extend home catalog visual capture budget

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(web): restore home ask mode toggle

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(e2e): dismiss consent before settings menu click

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(web): remove Hyundai preset brand

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-06-26 06:37:25 +00:00
AmyandGitHub a5e2f1bcff test(e2e): add target-level visual baselines (#4765) 2026-06-25 07:10:03 +00:00
0bf1b6d6b8 [codex] converge release workflows and stable dry-runs (#4390)
* fix(tools-pack): use junctions for Windows standalone peer deps

* fix(desktop): expose IPC during startup

* fix(tools-pack): preserve Windows inspect diagnostics

* fix(tools-pack): report Windows inspect status errors

* fix(packaged): use Electron net fetch for app protocol

* fix(packaged): load Windows renderer from web sidecar

* fix(desktop): show Windows packaged window during startup

* fix(packaged): disable Windows GPU startup

* fix(tools-pack): keep Windows core smoke observable

* fix(packaged): remove Windows startup probes

* fix(tools-pack): trace Windows desktop IPC status

* fix(tools-pack): add Windows IPC diagnose loop

* fix(release): default beta-s Windows updater feed

* chore: clean merged test eof

* refactor(release): unify prerelease channel model

* chore(release): close prerelease doc escape hatches

* refactor(release): converge release channel workflows

* fix(release): install toolchain in metadata jobs

* fix(release): build release package before contracts

* chore(release): bump development version to 0.10.1

* fix(e2e): seed windows packaged smoke runtime config

* fix(release): install toolchain for metadata publish

* fix(release): materialize betas metadata checkout

* chore(release): bump development version to 0.10.2

* fix(release): allow betas metadata cold start from s3

* fix(e2e): support betas packaged update scenarios

* fix(release): pass betas channel into packaged smoke

* fix(release): set betas channel during self-hosted builds

* fix(release): verify counted channel reservations

* fix(release): use pnpm cmd for betas windows publish

* fix(release): add betas manifest artifact fallback

* fix(release): skip beta-s public metadata fetch

* fix(release): read beta-s manifests from storage

* fix(release): cache beta windows tools-pack builds

* fix(release): inline beta mac tools-pack builds

* fix(pack): deep sign unsigned mac bundles

* docs(pack): document payload-first beta updater validation

* fix(release): align preview tools-pack cache flow

* fix(release): align prerelease tools-pack cache flow

* fix(release): pass github token to prerelease metadata

* fix(release): setup pnpm before feishu notify

* fix(release): add stable dry-run prepublish flow

* fix(release): accept completed prerelease metadata gate

* fix(release): require stable release branches

* fix(release): converge r2 access checks

* fix(updater): use release channel parser for defaults

* fix(updater): harden windows payload relaunch

* fix(release): converge updater smoke fixture contract

* test(e2e): require silent updater fixture output

* fix(release): align stable windows smoke build path

* fix(ci): include release workspace in validation

* fix(ci): repair release validation lanes

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(ci): restore zero-install Feishu notification

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-06-23 06:13:21 +00:00
86824a30d8 feat(web): unify task-failure error card across all failure states (#4656)
* feat(web): unify task-failure error card across all failure states

Collapse the three divergent failure UIs (gray .msg.error card, red
.status-pill.is-error pill, accent .amr-card) into one neutral run-error
card with a consistent four-part structure: ① error-type title, ② detail
copy, ③ 1–2 fix CTAs anchored bottom-right, ④ collapsible error-source
(code-line styled, one line collapsed, expand/copy on the source row).

- amr-guidance: add titleKey mapping (code → title i18n); split "sign-in
  required" into AMR (inline AmrLoginPill, single CTA, no promotion) vs
  non-AMR ({agent} copy, retry + use-official-agent) per the PRD.
- ChatPane: rebuild the error card JSX into the unified shell, preserving
  every recovery handler (authorize/recharge/resume/retry/BYOK); interpolate
  {agent} via t(key, {agent}) + agentDisplayName.
- AmrLoginPill: drop the redundant device-code chip (the activation URL
  already carries the code); reword the activation hint.
- i18n: add run-error title/source/sign-in keys across all 19 locales.
- tests: update amr-guidance + AmrLoginPill specs for the new behavior.

* test(e2e): align run error assertions with unified card

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
Co-authored-by: Mason <jinmeihong0201@gmail.com>
2026-06-23 04:08:24 +00:00
d19c53d274 Agent-driven brand extraction + two-loop memory overhaul (#4260)
* Implement brand management routes and CLI support

- Added `brand-routes.ts` to handle HTTP endpoints for brand operations: listing, extracting, retrieving details, deleting, and serving logos.
- Introduced `brands-cli-help.ts` for CLI commands related to brand management, including usage instructions for listing, creating, retrieving, and deleting brands.
- Updated `cli.ts` to integrate brand commands into the existing CLI structure, allowing headless management of brands via the command line.
- Created supporting files for brand metadata handling, including `design-md.ts` for rendering brand information in markdown format and `index.ts` for the brand engine API.
- Implemented `prefetch.ts` to fetch and process brand material from specified URLs, ensuring a streamlined extraction process.
- Enhanced server setup in `server.ts` to register brand routes and manage brand-related data effectively.

This commit establishes a comprehensive framework for managing brands within the application, facilitating both HTTP and CLI interactions.

* Enhance memory management and onboarding experience

- Introduced canonical profile labels to ensure consistent handling of user input in profile forms, preventing duplicate entries.
- Updated the `parseProfileBody` and `captureProfileFromForm` functions to utilize the new canonical label matching.
- Added a memory callout section in the onboarding view to highlight the benefits of memory usage, including personalized responses and reduced setup questions.
- Implemented new UI elements in the onboarding view to improve user engagement with memory features.
- Expanded i18n support for new onboarding messages related to memory benefits across multiple languages.

* Refactor onboarding flow and enhance design system integration

- Updated the onboarding process to include a new brand extraction step, replacing the previous newsletter step.
- Adjusted the tracking logic to reflect the new onboarding steps, ensuring accurate analytics for user progress.
- Improved the UI for the onboarding view, including new input fields for email collection during the brand extraction phase.
- Refined the EntryShell component to remove outdated comments and clarify the onboarding renderer's purpose.
- Enhanced CSS styles for the onboarding steps to improve layout and user experience.
- Updated internationalization strings across multiple languages to reflect changes in the onboarding flow and brand extraction messaging.

* Add brand management features and enhance font handling

- Introduced new modules for managing brand assets, including `chrome.ts` for headless Chrome operations and `fonts.ts` for self-hosting web fonts.
- Implemented `prefetch.ts` to streamline the brand material extraction process, allowing for efficient harvesting of colors, fonts, and logos.
- Enhanced the brand system with new schema definitions in `schema.ts` to support brand color and font management.
- Developed the `engine` module to integrate brand building and rendering processes, including token derivation and artifact generation.
- Improved the overall structure and organization of brand-related files for better maintainability and scalability.

* Enhance brand extraction and project management features

- Updated `brand-routes.ts` to include new dependencies for project management, allowing for the registration of brand-related projects.
- Modified the `extractBrand` function to support project ID and system files, improving the brand extraction process.
- Enhanced the CLI commands in `cli.ts` to handle project IDs during brand creation, enabling better tracking of brand projects.
- Updated the server setup in `server.ts` to register new project-related routes.
- Improved the UI components to display project information associated with brands, including buttons for opening projects in the `BrandDetailView` and `BrandsTab`.
- Added new metadata fields in the contracts to support project tracking and management for brands.

This commit establishes a more robust framework for managing brand projects, enhancing both backend and frontend functionalities.

* Enhance onboarding profile management and memory persistence

- Added new canonical profile labels for 'Organization size', 'Use cases', and 'Discovery source' to improve user input consistency.
- Introduced `OnboardingProfileState` type to manage onboarding profile data more effectively.
- Implemented functions to build and persist the onboarding profile body to memory, ensuring user selections are saved accurately.
- Updated the `OnboardingView` component to handle profile persistence during navigation and submission steps.
- Enhanced tests to verify that user selections are correctly persisted to the memory profile.

This commit improves the onboarding experience by ensuring that user inputs are consistently captured and stored, enhancing overall user engagement with the application.

* Reflow brand extraction into an agent-driven, live flow

Replace the deterministic SSE prefetch/preview/system pipeline with an
agent-driven extraction: POST /api/brands now reserves the brand and stands
up a backing project with the target site open in an in-app browser tab plus
a seeded prompt, so the agent measures, synthesizes brand.json incrementally,
and the user can clear anti-bot walls by hand. New /preview and /finalize
routes let the agent render the kit page live and register the resulting
user:<id> design system, so extracted brand facts persist as a structured,
reusable brand kit instead of a one-shot deterministic guess.

Adds the brand-extract skill (SKILL.md + brand-kit.html template), kit-render
engine, brand-extraction-engine tests, brand project covers in the Designs
tab, onboarding extract handoff, and the matching od brand extract/preview/
finalize CLI subcommands and contract updates.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Sediment finalized brands into structured memory

Reflow a finalized brand into the memory store (brandToMemoryEntries +
reflowBrandToMemory) so future chats can ground vague requests in the
brand's palette, type, voice and rules. finalizeBrand now wires through
the runtime dataDir and best-effort persists the brand, MemoryChangeEvent
gains a 'brand' source, and the brand kit render hardens its inline JSON
escaping. Adds brand.previewEmpty / brand.viewDetails across all locales.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Implement logo fallback and imagery support in brand extraction

- Introduced a deterministic logo fallback mechanism to ensure that brand extraction processes can retrieve and save site logos, even when the agent fails to do so.
- Enhanced the `startBrandExtraction` and `finalizeBrand` functions to utilize the new logo fallback, allowing for better handling of logo assets.
- Added support for imagery samples in brand validation, enabling the inclusion of representative images in the brand kit.
- Updated the brand kit rendering to include self-hosted fonts and imagery, improving the overall presentation of brand assets.

This commit strengthens the brand extraction workflow by ensuring that logos and imagery are reliably captured and displayed, enhancing the user experience in brand management.

* Enhance memory management with rule proposal and verification features

- Introduced new functionality for distilling annotations into rule proposals, allowing users to suggest rules based on in-canvas annotations through the `od memory rule suggest` command.
- Implemented a verification system that programmatically enforces compliance with active rules during artifact generation, ensuring that all active rules are covered in the self-verify scorecard.
- Added endpoints for managing verification outcomes, including listing, removing, and clearing verification records, enhancing the transparency of the verification process.
- Updated the memory management system to support the retrieval of active rule entries, ensuring that only linked rules are considered during verification.
- Enhanced tests for both rule proposal generation and verification processes to ensure reliability and correctness.

This commit strengthens the memory management capabilities by integrating rule proposals and verification, improving the overall user experience in managing design rules and ensuring compliance.

* Distill review annotations into memory and enforce self-verify scorecard

Add distillAnnotationsToMemory to mine inline preview comments/highlights/
marks into durable feedback + rule memory via a dedicated distiller prompt,
threaded through the existing extract pipeline with an 'annotation' change
source. Tighten the self-verify prompt (daemon + contracts) to state the
daemon programmatically checks the scorecard, so a missing or uncovered
scorecard on an artifact turn is an enforcement failure. Cover the rule
suggest and verification-history routes with tests.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Apply brand design system through web config on "Use in new chat"

Thread onApplyDesignSystem from the entry shell into BrandsTab so the brand's
registered design system is applied via the web config channel instead of a
bare daemon PATCH that left the Home composer stale. Add a transient
home-intent latch + event so the Brands tab can request the Prototype chip on
the already-mounted HomeView, which consumes it once the plugin catalog loads.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Wire annotation distillation into background memory extraction

Add a background distill pass that mines inline review annotations
(comments / highlights / drawn marks) from a turn into durable memory
alongside the general LLM extraction, surface an `annotation` memory
toast source in the web UI, and cover the flow with a unit test.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix brand design system not applying to composer on "Use in new chat"

Selecting a brand's "Use in new chat" applies the brand's design system as
the default and fires the Prototype chip intent in the same synchronous click
handler. HomeView consumed that intent inside the event listener, so `pickChip`
ran before React committed the config change and seeded the composer's
design-system field from the stale (empty) default — the composer showed
"No design system" instead of the brand until a reload.

Split the intent handling: the listener now only bumps a tick, and a separate
effect consumes the chip after the re-render lands, so the seeded design system
reflects the freshly-applied brand. Add the previously-untracked home-intent
latch test coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(web): rework Brands into Brand Kit and add Home create entry

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(brands): harvest real cover/hero images for the Images module

The brand kit's Images gallery only populated when the extraction agent
remembered to save imagery — so a forgetful or bot-blocked agent (and the
pre-imagery "Open Design" brand) left it empty. Add a deterministic,
server-side imagery fallback (imagery-fallback.ts), mirroring the logo
fallback: it parses og:image/twitter:image, large <img> (highest-res
srcset/<picture>), <link rel=preload as=image>, and CSS background-image
hero blocks, fetches candidates with browser-shaped headers, decodes
PNG/GIF/JPEG/WebP dimensions to keep only big representative images
(dropping icons/sprites/logos/tracking pixels), dedupes by content hash,
and saves up to 8 of the largest into imagery/ with labeled samples.

finalizeBrand runs it as a timeout-bounded, failure-tolerant safety net
(injectable so tests stay offline) when the agent captured too few
samples, first adopting any on-disk images. The extraction prompt and
brand-extract SKILL now explicitly direct the agent to harvest the site's
large/cover/hero images, filtered by rendered size.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(qa): implement deck layout validation and safety checks

Add a new QA module for validating the layout of generated brand decks to ensure robustness against clipping and truncation issues. The `analyseDeckLayout` function checks for critical layout invariants, including the presence of `.slide` sections, correct container types, and necessary runtime layers. Introduce `assertDeckLayoutSafe` to enforce these checks during brand system rebuilds, preventing the deployment of decks that fail validation. Additionally, create comprehensive tests to verify the functionality of the new layout validation features.

* fix(brands): apply deck shrink-to-fit synchronously so slides never clip

The no-clip runtime scheduled its fit pass through requestAnimationFrame,
whose callbacks are throttled while the deck is offscreen or occluded. A
slide could therefore stay unscaled — and clip its content — until first
paint. Fit synchronously on resize/load/fonts-ready with a trailing
setTimeout settle pass for late reflow, removing the rAF dependency.

Verified at the previously-broken 1024x620 viewport: container-type:size,
zero truncations, runtime auto-applies scale (Problem 0.71, ASK 0.87,
Product 0.97, Competition 0.97) and frame clip count drops to 0.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(web): let New Brand modal embed scrollable brand reference picker

Add a fillHeight mode to BrandReferencePicker so the heading, quick-pick
row and controls stay pinned while only the gallery scrolls inside a
bounded-height parent. Wire it into NewBrandModal with a stable, spacious
dialog and refresh the related newBrand/brandPicker copy across all 18
locales.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(brands): enhance brand extraction with deterministic seed harvesting

Introduce a new `seed-fallback` module to provide a server-side deterministic palette and typography seed during brand extraction. This ensures that the brand kit's initial display includes a harvested logo, an approximate color palette, and font families, improving the user experience by reducing the all-skeleton appearance during the first paint. Update the `startBrandExtraction` function to utilize this new module, allowing for a more seamless and visually appealing brand extraction process.

Additionally, enhance the `BrandReferencePicker` component to reflect loading states and errors during brand extraction, ensuring users receive immediate feedback on their actions. Update related tests to verify the idempotency of the `finalizeBrand` function, ensuring that re-finalizing a brand correctly reuses the existing design system without duplication.

* feat(brand-extract): enhance BrandReferencePicker and localization updates

Updated the BrandReferencePicker component to reflect loading states and errors during brand extraction, improving user feedback. Added a new localization key for the brand extraction process and updated existing translations in English, Simplified Chinese, and Traditional Chinese to enhance clarity and user experience. Additionally, introduced new styles for better interaction with brand assets in the brand kit template.

* feat(brands): wire in-page lightbox/masonry/asset preview + refine seed

Brand-kit preview improvements for the live extraction kit:
- brand-kit.html: add in-page overlay system (sandboxed iframe has no
  top-nav) — clickable image lightbox with prev/next, a "view all"
  masonry modal, and a full-page asset preview modal that loads
  system/artifacts/<kind>.html in an iframe. Defer auto-reload while an
  overlay is open so it never yanks the modal out mid-interaction.
- seed-fallback.ts: prefer vivid mid-luminance hues for the seeded
  accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.)
  from the typography seed so specimens never render glyph soup.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(brands): wire in-page lightbox/masonry/asset preview + refine seed

Brand-kit preview improvements for the live extraction kit:
- brand-kit.html: add in-page overlay system (sandboxed iframe has no
  top-nav) — clickable image lightbox with prev/next, a "view all"
  masonry modal, and a full-page asset preview modal that loads
  system/artifacts/<kind>.html in an iframe. Defer auto-reload while an
  overlay is open so it never yanks the modal out mid-interaction.
- seed-fallback.ts: prefer vivid mid-luminance hues for the seeded
  accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.)
  from the typography seed so specimens never render glyph soup.

Co-authored-by: Cursor <cursoragent@cursor.com>

* i18n(web): add brandPicker.opening across remaining locales + picker test

Completes the brand-reference picker i18n key that was committed only for
en/zh-CN/zh-TW, so every locale satisfies the typed Dict, and lands the
BrandReferencePicker extraction-feedback test left untracked by the
concurrent worker.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(EntryShell): enhance AMR cloud card visibility post-detection

Updated the EntryShell component to ensure the AMR cloud card remains visible after detection settles, even when the AMR runtime is unavailable. This change prevents the card from disappearing and allows it to degrade gracefully to fallback content and sign-in flow. Additionally, added tests to verify the new behavior, ensuring a better user experience during onboarding.

* feat(brands): programmatic-first design system extraction + rename

Make brand extraction two-phase so a usable design system is ready the
moment the user enters a URL — the instant "aha" — instead of waiting on
the AI agent:

1. PROGRAMMATIC-FIRST (synchronous): startBrandExtraction now harvests the
   site deterministically (logo, palette, typography, one-line description,
   cover imagery, source URL) via prefetchBrand, synthesizes a valid design
   system with brandFromMaterial (no LLM), and finalizes + registers it
   before returning. finalizeBrand is refactored into a reusable
   finalizeBrandCore shared by both the programmatic path and the agent path.
2. ASYNC AI ENRICHMENT: the seeded agent prompt is reframed to enrich the
   already-usable design system and re-finalize in place (same user:<id>),
   updating every artifact/template.

Bounded + best-effort: a blocked/unreachable origin skips phase 1 and stays
`extracting` for the agent to drive. Gated on userDesignSystemsRoot so the
legacy agent-only path stays intact for tests.

Also rename the user-facing "Brand Kit" surface to "Design System" across
en + zh-CN strings, project names, and the enrichment prompt.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(brands): restore design-systems nav entry + reconcile BrandsTab on re-activation

Address review feedback on PR #4260:

1. EntryNavRail dropped the only control that reached view==='design-systems'
   when Brands replaced it in the rail, leaving the still-rendered/routed
   design-system manager deep-link only (the entry-nav-design-systems e2e
   specs assert this). Restore a reachable rail entry (blocks icon, existing
   navDesignSystems key) alongside Brands.

2. BrandsTab only fetched once on mount, but EntryShell keeps sub-views
   mounted and toggles visibility, so a brand finishing extraction in its
   backing project never reconciled until a full reload. Refresh whenever the
   Brands view becomes active again, and poll while any brand is extracting
   (torn down once settled / when hidden).

Red spec: tests/components/BrandsTab.refresh.test.tsx (fails pre-fix:
fetchBrands called once, not twice).

* fix(web): surface missing backing projects

* fix(web): re-enable brand actions after use

* fix(daemon): serve brand logos from data roots

* fix(brands): reconcile failed extractions

* fix(brands): non-blocking extraction start + lifecycle-accurate status (#4470)

Acceptance fixes for the Brand Kit surface (PR #4260, even-ferry),
addressing five reported issues:

- Perf: `startBrandExtraction` no longer blocks the POST /api/brands
  response on the synchronous programmatic harvest+finalize. It now waits
  only a short budget (~1.2s) so fast origins still land on a ready,
  applyable design system (the instant "aha"), while slow/blocked origins
  return immediately on the "Extracting…" skeleton and finalize in the
  background. Measured: example.com POST dropped from a ~19s block to
  ~1.2s, then finalized to `ready` in the background.

- Brand Kit stays stuck on "Extracting…" after a manual stop: the backing
  run's canceled/failed status now reconciles the brand to `failed` with a
  reason (this extends the existing reconcile; adds a regression spec).

- Brand Kit ignores a backing run that is awaiting user input
  (anti-bot wall / question form): new reversible `needs_input` brand
  status, derived on read (never persisted) so it flips back once the user
  answers. Surfaced as a "Needs input" badge + hint in the card and a
  distinct status dot in the list; the list keeps polling while paused.

- Home → Recent projects showed brand-extraction projects as
  "Not started": /api/projects now falls back to the brand lifecycle for
  brand projects whose run-derived status is `not_started`
  (extracting→running, needs_input→awaiting_input, ready→succeeded,
  failed→failed), so a live extraction is never shown as not started.

- "Use in new chat" produced no visible result: it now carries a
  confirmation notice through the Home intent channel so Home shows a
  "Using <brand>" toast, making the navigate+apply verifiable (the
  composer already preselects the brand's design system).

Tests: daemon brand-routes (canceled→failed, needs_input transient) and
brand-extraction-engine (fast return + background finalize) specs; web
BrandPreviewCard specs (needs_input badge/hint, Use-in-new-chat notice).
#4 validated end-to-end against a real daemon. guard + typecheck green.

* [codex] Fix brand extraction incomplete states (#4486)

* fix brand extraction incomplete states

* fix web memory tests for advanced modal

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix onboarding P0 brand-step navigation

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix daemon brand extraction test timeout

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix brand extraction fallback prompt state

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>

* [codex] Fix brand extraction terminal status reconciliation (#4532)

* Fix brand extraction terminal status reconciliation

* Keep prefetched brand pages previewable

* fix(brands): preserve ready extraction status

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(brands): persist terminal extraction signal

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(brands): clear stale terminal retry markers

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>

* Fix brand kit modal intent handling (#4528)

Co-authored-by: Siri-Ray <2667192167@qq.com>

* fix(web): let design system contents scroll in narrow review layout (#4526)

Co-authored-by: Siri-Ray <2667192167@qq.com>

* [codex] Fix Brand Kit preview lifecycle guards (#4527)

* Fix brand kit preview lifecycle guards

* fix(brands): keep detail selected on delete failure

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* fix(brands): handle delete HTTP failures

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>

* ci: retrigger pull_request checks

* test(e2e): stabilize entry settings shard

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: PerishCode <perishcode@gmail.com>
Co-authored-by: lefarcen <935902669@qq.com>
Co-authored-by: PerishFire <39043006+PerishCode@users.noreply.github.com>
Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-06-22 08:34:05 +00:00
6cf48c29b5 ci: reduce Blacksmith usage and stabilize PR checks (#4603)
* ci: move lightweight workspace checks to hosted runners

* ci: split UI P0 project runtime shard

Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex)

* Stabilize UI P0 project runtime tests

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-06-22 04:51:04 +00:00
PerishFireandGitHub 15d3759834 [codex] Optimize CI topology and Playwright suites (#4460)
* Consolidate PR validation into ci

* Tune absorbed CI runner tiers

* Fold visual validation into CI Playwright shards

* Run PR shards during manual CI dispatch

* Optimize CI topology and scopes

* Increase UI P0 Playwright workers

* Relax visual Playwright timeout
2026-06-17 08:24:52 +00:00
AmyandGitHub 8ff19c6b41 [codex] Add main-risk smoke and E2E coverage (#4322)
* test(e2e): cover daemon reload artifact recovery

* test(e2e): expand critical flow coverage

* test(daemon): add startup and recovery smoke coverage

* test(e2e): add visual and desktop chrome smoke coverage

* ci: gate packaged onboarding smoke to nightly

* fix(web): repair artifact replay type narrowing

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(ci): repair preflight smoke coverage checks

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): tighten artifact recovery polling

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): keep error recovery retries alive

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(e2e): relax brittle UI P0 assertions

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): recover pointer artifact outputs

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(e2e): stabilize manual edit reload smoke

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(e2e): avoid noisy win onboarding cleanup

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): stop failed artifact recovery polling

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(daemon): isolate startup smoke data root

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): recover standalone html artifacts

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(web): guard pointer artifact recovery by run time

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(ci): narrow strict visual gate to critical smoke

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* fix(ci): limit PR visual capture to critical cases

* fix(ci): keep PR visual capture complete

* fix(web): keep reload artifact recovery retryable

* fix(ci): clarify PR visual gate layering

* fix(e2e): stabilize visual home P2 capture

* fix(e2e): align visual gallery detail clicks

* fix(e2e): preserve packaged install during onboarding cleanup

* fix(ci): shard PR visual capture

* fix(ci): remove duplicate nix validation from ci

* fix(ci): keep visual capture screenshots flat

* fix(ci): point nix hash autofix at ci-nix

* fix(ci): stabilize PR P0 recovery gate

* fix(web): ignore stale artifact pointers during recovery

* fix(web): reset BYOK model after clearing key

* ci: run critical UI P0 subset on PRs

* ci: combine PR UI P0 critical shards

* ci: combine PR visual capture shards

* ci: preserve visual capture shard manifests

* fix(web): clear ProjectView delayed timers on unmount

* test(e2e): harden onboarding connect gate coverage

* test(e2e): align AMR auth recovery and visual catalog timeout
2026-06-17 16:01:53 +08:00
PerishFireandGitHub 891981d460 [codex] Optimize CI runtime topology (#4450)
* Optimize e2e tools-dev runtime parallelism

* Remove visual networkidle wait

* Optimize e2e vitest parallelism

* Optimize Nix flake caching

* Test CI on Blacksmith runners

* Allow parallel manual CI runs

* Tier CI runner sizes

* Temporarily narrow CI debug scope

* Instrument watcher CI timeouts

* Instrument watcher event diagnostics

* Avoid default polling in watcher tests

* Skip runtime trace during watcher debug

* Probe ARM runner tiers for CI

* Focus CI runner probe on x64 browser

* Probe browser workers by runner size

* Probe Playwright file parallelism

* Probe Playwright worker scaling on 8v

* Reshape CI topology

* Fix split E2E Vitest CI lane

* Simplify daemon CI topology

* Optimize Windows payload CI setup

* Revert "Optimize Windows payload CI setup"

This reverts commit 5cbc48c0af.

* Cache better-sqlite3 Nix binding separately

* Revert "Cache better-sqlite3 Nix binding separately"

This reverts commit 0384e3787e.

* Remove unused Nix cache setup from CI

* Use Blacksmith ARM for lightweight CI jobs
2026-06-17 12:53:06 +08:00
Marc ChanandGitHub 6c555f93d6 chore(ci): stabilize visual regression screenshots (#4290)
* Stabilize visual regression screenshots

* Stabilize BYOK visual settings states
2026-06-15 02:53:00 +00:00
AmyandGitHub 571b43dce0 [codex] Expand UI E2E coverage and P0 CI signal (#4196)
* add PR UI P0 gate

* fix(ci): keep critical UI check in required workflow

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)

* ci: split workspace restoration P0 shard

* ci: reduce visual and daemon test wall time

* ci: skip duplicate critical UI gate on PRs

* ci: increase daemon test sharding

* test(e2e): expand critical UI flow coverage

* test(e2e): promote critical onboarding and automation flows

* test: expand ui e2e coverage

* test: repair PR P0 onboarding and media sync checks

Generated-By: looper 0.9.7 (runner=fixer, agent=codex)
2026-06-12 04:41:49 +00:00
lefarcenandGitHub 6a10e8e178 fix(daemon): classify Claude mid-stream socket drops as retryable (#3937)
* fix(daemon): classify Claude mid-stream socket drops as retryable

When the Claude Code CLI's connection to the Anthropic API (or a custom
ANTHROPIC_BASE_URL relay) drops mid-response, the SDK surfaces 'The socket
connection was closed unexpectedly...'. The daemon relayed this raw SDK
string verbatim into the error bubble because diagnoseClaudeCliFailure had
no branch for an established-then-dropped connection (distinct from the
existing connection-refused case).

Add a connection-drop branch that classifies socket-close / ECONNRESET /
socket hang up / fetch failed / premature close into a human-readable,
retryable diagnostic, pointing at the proxy when a custom endpoint is set
and at the network otherwise. Most visible on long, large generations.

The fake-agent CLI gains a 'Return a daemon socket-drop failure' mode whose
claude shape was captured from the real Claude Code CLI 2.1.168 driven at a
socket-dropping endpoint (error on stdout as a synthetic assistant block +
result{is_error:true}, exit 1, empty stderr), so the e2e path exercises the
real failure shape rather than a guessed one.

* fix(daemon): use OpenClaude socket-drop diagnostics

Generated-By: looper 0.9.7 (runner=fixer, agent=opencode)

* fix(daemon): harden Claude connection-drop diagnostic from real repro

Reproduced end-to-end against the real Claude Code CLI (2.1.168, official
auth, no ANTHROPIC_BASE_URL) by tunneling through a local proxy that resets
the TLS stream mid-response. Two real error faces observed: 'The socket
connection was closed unexpectedly' (SSE cut) and 'Unable to connect to API
(ECONNRESET)' (tunnel reset); the CLI retries internally for minutes before
surfacing either, which is why long runs appear to abort after a while.

Broaden the connection-drop matcher with 'unable to connect to api' and
ETIMEDOUT, and lock the real ECONNRESET transcript into the test suite.

* fix(daemon): narrow Claude API drop matcher

Generated-By: looper 0.9.7 (runner=fixer, agent=opencode)

* feat(daemon,web): structured AGENT_CONNECTION_DROPPED code + localized message

Promote the Claude connection-drop diagnostic from a raw English string to a
stable, machine-readable failure class so the web can localize it and triage
can count it by code.

- contracts: add AGENT_CONNECTION_DROPPED to API_ERROR_CODES.
- daemon: ClaudeCliDiagnostic carries an optional code; the connection-drop
  branches stamp AGENT_CONNECTION_DROPPED; server.ts prefers diagnostic.code
  over the generic service-failure sniff so the run records the specific class
  (flows into run_finished error_code + routine_runs.error_code for triage).
- web: resolveRunFailureUi maps AGENT_CONNECTION_DROPPED (any agent) to the
  localized chat.connectionDropped message, plain retry, no AMR promotion.
- i18n: add chat.connectionDropped to types.ts and all 19 locale bundles.

* fix(daemon): classify Claude in-stream connection-drop error frame

End-to-end repro on a real daemon + fake Claude CLI revealed the diagnostic
never fired: Claude surfaces a connection drop as an in-stream `error` frame
(assistant error:"unknown" + the raw SDK string), which claude-stream emits
as a type:'error' event. The daemon's stream-error handler sent that raw
string verbatim as a non-retryable AGENT_EXECUTION_FAILED and set
agentStreamError, so the child-exit diagnoseClaudeCliFailure path was skipped
entirely.

Run the same per-agent diagnostic in the stream-error handler so a connection
drop emits AGENT_CONNECTION_DROPPED (retryable, with localizable copy +
triage-countable code) instead of the raw SDK string. Verified end-to-end via
the real-daemon-run Playwright test, which now asserts the localized card copy.
2026-06-09 11:12:54 +00:00
AmyandGitHub 90817ce72c Rebalance Playwright critical gate (#3904)
* Rebalance Playwright critical gate

* Fix staged attachment e2e selectors

* Run critical gate before visual PR checks

* Expand strict PR visual coverage

* Widen visual harness config fixtures

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Expand strict visual suite to 35 cases

* Stabilize critical app artifact selectors

* Fix onboarding visual model assertion

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Stabilize settings dialog e2e entry

* Reduce UI extended E2E failure fanout

* Handle nested settings menus in e2e helper

* Sync AMR logout status to settings card

* Centralize agents route mocks in E2E

* Fix critical smoke settings grep

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Consolidate E2E agents route fixtures

* Stabilize critical project instructions test

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Let nested agents mocks handle routed requests

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Stabilize project instructions critical gate

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* Stabilize visual home plugin surfaces

* Upload critical gate artifacts in visual PR job

* Fix visual PR gate reports and fixtures

* Address PR 3904 review paths

* Localize project instructions control
2026-06-09 10:07:37 +00:00
5e5134ba86 fix(web): interrupt the active run when sending a queued chat now (#3959)
* fix(web): interrupt the active run when sending a queued chat now

Clicking the up-arrow ("send now") on a queued chat send while the
agent is still working only moved that item to the front of the queue.
For the common single-item case that is a no-op: the button looks like
a send action but nothing happens until the in-flight turn finishes on
its own, so it reads as broken.

Make "send now" do what it says: when the conversation is busy, stop the
active run and prioritize the chosen item. Stopping flips the conversation
out of its busy state and the existing auto-start effect then flushes the
now-first queued send through the same path as a natural completion, so
runs still never overlap.

handleStop moves ahead of the queued-send handlers so sendQueuedChatSendNow
can call it.

* fix(web): preserve replacement run streaming on stale cancel

Generated-By: looper 0.9.7 (runner=fixer, agent=opencode)

* fix(web): ignore stale run finalization after queued send

Generated-By: looper 0.9.7 (runner=fixer, agent=opencode)

* fix(web): ignore a superseded run's late stream error

Final stale-callback edge in the "send now" interrupt path. The stream
onError handler unconditionally painted a global failure banner, appended
an assistant error event, and marked the assistant message failed. A run
interrupted by send-now can still land in onError (e.g. a canceled stream
that lost its terminal SSE and whose fallback status fetch sees a
non-terminal run), so the superseded run could flash a stale failure
banner while the replacement run is already streaming.

Gate the banner / message finalization on the same controller-pair
ownership check used for the marker and latest-run teardown. Only the run
that still owns the active controllers surfaces the error.

* fix(web): ignore stale run completion side effects

Generated-By: looper 0.9.7 (runner=fixer, agent=opencode)

* fix(web): guard reattach terminal callbacks for superseded runs

The send-now interrupt's real target is often a reattached run (the agent
was already streaming when the user queued). Apply the same controller-pair
ownership guard the stream path uses to the reattach terminal callbacks: a
superseded reattached run's late onDone must not persist artifact /
produced-file output, and its late onError (or the consume catch) must not
paint a global failure banner, over the replacement run that now owns the
conversation. Normal completion is unchanged.

* test(web): cover the interrupted reattached run's late error

Red-green regression for the reattach guard: a reattached run interrupted
by send-now, whose late onError lands after the replacement queued send has
started, must not paint a global failure banner. Goes red without the
controller-pair ownership guard on the reattach error path.

* fix(web): don't drop a normal run's completion after its terminal status

The superseded-run guards checked ownership as
`abortRef === controller && cancelRef === cancelController`, but the daemon
emits the terminal onRunStatus *before* onDone, and that terminal status
clears the run's active refs. So for a normal successful run the refs were
already null by the time onDone ran, the guard read false, and onDone bailed
— skipping artifact persistence and produced-file attachment. (Caught by the
artifact-consistency e2e: the saved file metadata never aligned.)

Reframe the check as "a newer run owns the active slot": a run may finalize
when abortRef is null (its own terminal status cleared it — the normal path)
or still points at its own controller; only a live replacement (abortRef set
to a different controller) means it was superseded. Applied to every stream
and reattach terminal callback. Adds a unit regression that fires the terminal
status before onDone and asserts the completion flow still runs.

* fix(web): tag superseded runs at interrupt time, not via abortRef

The previous guard read ownership off abortRef in each terminal callback,
but that is unreliable: a normal run's terminal onRunStatus clears the refs
before onDone, and handleStop() clears them before a canceled run's late
callbacks arrive — so abortRef === null was ambiguous between "completed
normally" and "interrupted, replacement not yet attached". The latter let a
superseded run still run its completion flow and repaint the shared artifact.

Record the interrupted run's abort controller in a WeakSet synchronously in
sendQueuedChatSendNow — before handleStop() clears anything — and have every
stream/reattach terminal callback skip its current-run side effects when its
controller is tagged. This is independent of abortRef churn and holds even
before the replacement send attaches. The reattach onDone also bails ahead of
parser.flush()/setArtifact()/message finalize so a stale run can't repaint the
artifact preview; only run bookkeeping is released for a superseded run.

Adds a regression that interrupts a reattached run and delivers its late
onDone, asserting the completion flow (file refetch) does not run.

* fix(web): reset applying comment status when send-now interrupts

A turn moves its preview-comment attachments to 'applying' when it starts.
Now that send-now suppresses the interrupted run's terminal callbacks, those
callbacks no longer flip the comments to 'needs_review'/'failed', so they were
left stuck as 'applying' after the replacement send took over — the UI kept
showing an interrupted review comment as still being applied.

Reset the conversation's 'applying' preview comments back to 'open' in the
send-now interrupt path (local state + persisted), so a canceled turn's
comments don't strand mid-apply. Adds a red-green regression.

* fix(web): only reset the in-flight run's stuck applying comments

The previous reset flipped every 'applying' comment in the conversation to
'open', but queued sends (including the one being prioritized by send-now)
also hold their attachments in 'applying'. Resetting those raced the
replacement run's re-apply and reopened comments still reserved by other
queued work.

Scope the reset to the interrupted in-flight run's comments only — the
'applying' ones not owned by any queued send. Regression flipped to assert a
queued comment-bearing send's own comment is NOT reset to 'open' when
send-now flushes it.

* test(e2e): cover send-now interrupt end-to-end

Browser-level e2e against a real daemon + fake agent for the send-now
queued-send feature: start a held (never-finishing) run so the conversation
stays busy, queue a second turn, click the queued item's send-now arrow, and
assert the held run is canceled and the queued turn dispatches as a fresh run
while the queued strip drains.

Adds a 'Hold the daemon run open until canceled' fake-agent mode that stays
alive until the daemon cancels it, and a data-testid on the queued send-now
button for a stable selector.

---------

Co-authored-by: audit <a@b.c>
2026-06-09 08:50:04 +00:00
7a1ad1a438 feat(packaged): add launcher payload updates (#3812)
* feat(packaged): add launcher payload runtime

* ci: focus launcher payload windows smoke

* ci: publish beta mac x64 launcher payload

* test(e2e): harden payload updater smoke

* fix(pack): inject launch config for installed windows smoke

* fix(daemon): allow packaged payload resource roots

* fix(updater): relaunch after payload update

* test(e2e): refresh windows updater UI status

* test(e2e): ensure windows smoke reaches main shell

* test(e2e): skip onboarding before windows updater smoke

* fix(updater): detach windows payload relaunch helper

* test(e2e): run payload smoke without updater dry run

* fix(desktop): relaunch windows payload updates on quit

* fix(updater): preserve installed payload relaunch target

* fix(updater): require launcher target for payload updates

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* test(e2e): align mac x64 artifact mode assertion

* test(e2e): canonicalize launcher relaunch root

* fix(updater): validate launcher payload config before activation

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

* fix(updater): require live launcher target for payload updates

Generated-By: looper 0.9.5 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-06-07 07:38:57 +00:00
AmyandGitHub 9498e6b9e6 [codex] stabilize main P0 CI alerts (#3740)
* test: stabilize main P0 CI alerts

* fix: address main CI alert review feedback

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* test: cover manual edit bridge selection

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix: restore project instructions UI coverage

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix: address project instructions and restoration feedback

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* test: preserve file route active-tab assertions

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)
2026-06-05 11:53:49 +00:00
AmyandGitHub b384c64716 test(e2e): align main P0 UI coverage (#3720)
* test(e2e): align main P0 UI coverage

* test(web): align BYOK model search assertion

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix: address P0 coverage review feedback

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix: restore picker keyboard and recent-project coverage

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(web): repair design-system picker type checks

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* ci: classify main CI Feishu alerts

* fix: restore active-tab P0 coverage

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* ci: add E2E coverage reminder

* ci: run E2E coverage reminder at 18:00

* ci: avoid unsafe E2E reminder pagination exits

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)
2026-06-05 08:47:16 +00:00
234a11aa05 feat(web): collapsible entry rail + quiet new-user templates + icon-only topbar chips (#3617)
* feat(web): collapsible entry rail + quiet new-user templates + icon-only topbar chips

Rework the entry view to keep new users focused on the hero composer:

- Nav rail collapses to a single topbar toggle by default and docks as an
  overlay on demand; a hover-reveal collapse button on the logo folds it back.
- For users with no projects, the Community templates gallery starts hidden
  behind a faint bottom hint; an upward scroll gesture or click smoothly
  reveals it, with a pinned collapse pill to fold it away again.
- Collapse the Discord / model-switcher / Use-everywhere topbar chips to
  icon-only with hover tooltips; the GitHub Star chip stays a full pill.

* test(e2e): expand collapsed nav rail before driving rail destinations

The entry nav rail now starts collapsed, so the UI smoke tests that click
`entry-nav-*` items (or assert the rail/logo is visible) timed out. Add an
idempotent `ensureRailOpen` helper and call it before rail nav interactions
across the e2e/ui suite; adjust the two rail-structure assertions to expand
first.

* test(e2e): reach home via Home nav and expand rail for help launcher

The logo now doubles as a hover-to-collapse control, so clicking it to return
home is intercepted by the collapse overlay — route via the explicit Home nav
item instead. Also expand the rail before opening the rail-footer help menu,
and guard the execution-pill nav loop with ensureRailOpen.

* fix(web): make collapsed rail inert and restore Discord chip title

Address review feedback:
- The collapsed nav rail kept its logo + nav buttons mounted and focusable, so
  a fresh Tab on the home view landed on invisible rail controls before the
  visible toggle/hero. Mark the rail `inert` while collapsed so its descendants
  leave the keyboard tab order and pointer flow; add a keyboard regression test.
- Restore the Discord chip's native `title` alongside `data-tooltip` so the
  existing topbar contract test (entry-topbar.test.ts) keeps passing.

* fix(web): make collapsed templates gallery inert and keep rail foldable on touch

Address second review pass:
- The collapsed new-user templates gallery was only aria-hidden + height-clipped,
  so its still-mounted buttons/tabs/search stayed in the keyboard tab order.
  Mark the gallery body `inert` until revealed (deps include `enabled` so it
  applies once the async-mounted body appears); add a keyboard regression test.
- On coarse-pointer / non-hover devices the hover-only collapse button plus the
  display:none topbar toggle could strand the rail open. Keep the collapse
  control visible + tappable under `@media (hover: none)`; add a CDP-emulated
  touch regression test.

* fix(web): keep inline switcher chip accessible name in icon-only topbar

---------

Co-authored-by: qiongyu1999 <2694684348@qq.com>
2026-06-04 11:54:39 +00:00
dbc74a397c feat(agents): CLI detection self-rescue with actionable diagnostics (#3560)
* feat(agents): surface actionable CLI diagnostics

Detect unavailable CLI agents with structured diagnostics, stream agent discovery results to the settings UI, and render actionable fix controls for common setup failures.

Also harden the streamed agents client so server error events and dropped streams surface as failures instead of replacing state with a truncated agent list.

* fix(agents): gate streamed rescan loading

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(agents): distinguish non-executable CLI diagnostics

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(agents): defer OAuth diagnostics without producer

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

---------

Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local>
Co-authored-by: Looper <looper@noreply.github.com>
Co-authored-by: Looper Fixer <looper-fixer@noreply.github.com>
Co-authored-by: looper-fixer <looper-fixer@users.noreply.github.com>
2026-06-04 03:18:37 +00:00
lefarcen fa59871428 Merge origin/main into release/v0.9.0 — back-merge to reconcile v0.9.0 with main
Syncs release/v0.9.0 with main so PR #3282 (release/v0.9.0 → main) merges
cleanly. 17 conflicts resolved by commit-time + per-area ownership:

- Comment/edit/preview: keep main (newer). FileViewer combines main's #3438
  (pin manual-edit inspector, no full-height panel) + #3347 deck/queue work
  WITH release's #3401 hover-card anti-flicker grafted on; #2879 Button kept.
- Toolbar: footer layout (reviewer-validated, ca03a7e0f) overrides main #3447 —
  CLI/agent selector in the composer footer, settings gear in the header, no
  settings item in the AvatarMenu dropdown.
- AMR: keep release's client-side model polling (mergeAmrModelsIntoAgents) and
  all release AMR fixes (#3450 sign-out, #3504 console, #3487 acp tool-only
  guard, amrCloudVisible onboarding, #3511 analytics provider id).
- Pet composer button stays removed (release decision); only /pet slash props
  retained.
- Pickers: main's providerModelsCache approach.

Validation: web typecheck + guard + full web suite (2638) + daemon suite green.
2026-06-03 17:21:00 +08:00
Denis RedozubovandGitHub b70791b0c6 Harden sandbox-mode media and tools-dev smoke (#3428)
* Harden sandbox media smoke path

* fix(daemon): keep stream-json stdin open after host answer
2026-06-03 03:30:10 +00:00
AmyandGitHub ec62f39ade [codex] expand project and onboarding coverage (#3513)
* test: expand project and onboarding coverage

* fix: omit undefined AMR recovery test options

* test: fix CI typecheck regressions
2026-06-03 03:28:54 +00:00
netteeandGitHub 601183efbb feat(daemon): load AMR model presets before remote catalog (#3425)
* spec

* impl

* fix

* remove default model content

* fix(amr): keep model catalogs fresh across env changes

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(amr): bust logout cache and stop preset polling

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* test(amr): cover logout cache invalidation and bounded polling

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(amr): start preset polling before agent probe

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(amr): clear stale web cache on env rescan

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(amr): restart preset polling after sign-in

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)

* fix(daemon): remove extra AMR spawn env arg

Generated-By: looper 0.9.2 (runner=fixer, agent=codex)
2026-06-01 20:20:25 +08:00
Denis RedozubovandGitHub a1f01e6fb7 feat(daemon): add project export manifest (#3245)
* feat(daemon): add project export manifest

* fix(daemon): honor export manifest primary refs

* fix(daemon): bind headless runs to default conversation

* test(e2e): retry tools-dev namespace startup collisions

* test(daemon): reject sandbox imported export manifests

* fix(daemon): honor artifact manifest entry refs

* fix(daemon): update renamed artifact manifest entries

* fix(daemon): update artifact refs during rename

* fix(daemon): preserve export refs across directory moves
2026-05-31 15:48:44 +00:00