Commit Graph
574 Commits
Author SHA1 Message Date
lefarcen 3960706541 test: restore worker runtime after billing stream fault 2026-10-17 18:08:16 +08:00
lefarcen b4b546cc73 test: append billing query after tools-dev path construction 2026-10-17 17:48:23 +08:00
lefarcen 28fd20f41b test: preserve real billing reconnect rejection response 2026-10-17 17:45:35 +08:00
lefarcen bbff7fa488 test: route RUN010 stored control profile through real stream proxy 2026-10-17 17:42:36 +08:00
lefarcen 0b3d92e3e7 test: observe actual workspace stream reconnect for RUN010 2026-10-17 17:32:47 +08:00
lefarcen a7c07d3d4d test: fund auxiliary prelude before running-debt reconnect 2026-10-17 15:04:51 +08:00
lefarcen 0c751cda02 test: verify task reconnect and explicit retry after exhaustion 2026-10-17 15:01:26 +08:00
lefarcen f5349f20ae test: bind task exhaustion to immutable settlement evidence 2026-10-17 14:54:15 +08:00
lefarcen c0fcbaf68d test(e2e): wait on actual wallet delivery before checking source deadline 2026-10-17 14:47:34 +08:00
lefarcen 59e182df51 test(e2e): tie RUN005 notification latency to negative wallet transaction 2026-10-17 14:32:10 +08:00
lefarcen e7c673620e test(billing): require real wallet notification within one second 2026-10-17 14:19:24 +08:00
lefarcen 905f292039 test(billing): witness natural lease expiry after an owned host crash
RUN-009 starts two independent tools-dev hosts, SIGKILLs only the first canonical receipt PIDs, observes the real 90-second lease while the survivor heartbeats, and checks no automatic retry, stale-token rejection, and one manual replacement. Guard and root/e2e typechecks pass; live acceptance pending.
2026-10-17 14:00:27 +08:00
lefarcen 97c40e6560 test(billing): prepare tool-round and reconnect boundary acceptance
RUN-005 requires a funded two-round control before testing depletion. RUN-010 observes a real browser offline/reconnect cycle without manual submit and asserts the manual retry retains workspace identity. Guard, root and e2e typechecks pass; live network acceptance remains pending and RUN-009 is not yet implemented.
2026-10-17 13:53:03 +08:00
lefarcen c0e9aacdba test(chat): verify uploaded message against the run request contract 2026-10-17 10:24:39 +08:00
lefarcen bd3a9b63c4 fix(chat): retain drafts while attachments are uploading 2026-10-17 10:05:39 +08:00
lefarcen 4786f52088 test(chat): wait for uploaded task attachment before admission 2026-10-17 09:55:44 +08:00
lefarcen 5f72382e68 fix(chat): restore denied task drafts across editor reset commits 2026-10-17 09:44:54 +08:00
lefarcen f2ef798ddc test(billing): verify OD rejects task start after payment authority changes 2026-10-17 09:33:05 +08:00
lefarcen 405e08ad5a test(billing): verify roster events stop live tasks before periodic heartbeat 2026-10-17 07:17:22 +08:00
lefarcen d84750d8d3 fix(billing): retain composer drafts until task admission starts execution 2026-10-17 07:11:02 +08:00
lefarcen c7c5b3a2e4 test(billing): verify auxiliary role cannot bypass Free permissions 2026-10-17 05:32:02 +08:00
lefarcen ef5e64f21e test(amr): exercise real task cancellation retry and removal 2026-10-17 05:15:24 +08:00
1eaa2381aa feat(release): validate version-only bumps before approval-exempt queueing (#8800)
Co-authored-by: lefarcen <935902669@qq.com>
2026-10-16 04:11:27 +00:00
5a221d5043 fix(amr): refresh retained Home funding blocks after billing updates (#8786)
* fix(amr): invalidate Home funding hints on billing changes

* test(amr): stop replaying funding events on fixture reconnect

* fix(amr): retain confirmed Home funding blocks until recovery

* fix(amr): recheck blocked Home funding after billing refresh

---------

Co-authored-by: lefarcen <935902669@qq.com>
2026-10-16 03:28:03 +00:00
open-design-release-bot[bot]GitHubopen-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
41afc74c88 chore(release): bump main to 0.25.1 ahead of stable 0.25.0 (#8787)
Co-authored-by: open-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
2026-10-16 02:06:03 +00:00
7abd6fc2b1 fix(amr): keep Home blocked on unknown funding confirmation (#8775)
* fix(amr): keep Home blocked on unknown funding confirmation

* test(web): await sign-in callout state independently

---------

Co-authored-by: lefarcen <935902669@qq.com>
2026-10-15 11:16:53 +00:00
CheemsandGitHub 6410d3622a fix(od-next): restore production follow-up host instructions (#8770)
* fix(od-next): restore production follow-up host instructions

Compose production host instructions with the same fresh key persisted on the run, including native resume, cold-start input, and UI locale. Keep the instructions independent of retired model state declarations and exclude the nonce-bearing text from internal continuation retry identity.

Verify optional suggestions, message persistence, and repeated preparation through the real server and run registry. Validated with main red specs, focused regression tests, guard, and the workspace typecheck.

* test(od-next): preserve production test entry points

Keep the existing production test header and fixture setup while sharing host-protocol assertions with a separate suggestions case. This avoids adding a conflict with the pending agent rollout tests.

Validated with the focused real-server regressions, guard, and the full workspace typecheck.
2026-10-15 09:28:23 +00:00
ae321ab2e6 fix(cms): fence offline replay across revocation and process death (#8676)
* fix(cms): fence offline replay across revocation and process death

* feat(cms): define paginated Test catalog and immutable runtime context

* fix(cms): synchronize Test and Production host presentation lifecycles

* test(cms): retain cross-host lifecycle and browser acceptance regressions

* fix(cms): retain request tickets through body classification

---------

Co-authored-by: heggria <bshengtao@gmail.com>
Co-authored-by: ivy-tinggg <986810707@qq.com>
2026-10-15 07:37:41 +00:00
535fa8eab7 fix(amr): restore Home funding checks and decouple run feedback (#8688)
* fix(web): surface live AMR funding failures without delaying sends

* fix(amr): check funding independently of agent startup

* chore(amr): pin Vela funding feedback test package

* fix(amr): route early funding hints through isolated CLI command

* fix(amr): restore scoped Home funding cache gate

* fix(amr): restore Home wallet and plan memory gate

* test(amr): align send audits with independent funding checks

* chore(amr): bundle Vela CLI 0.1.5 for funding checks

---------

Co-authored-by: lefarcen <935902669@qq.com>
2026-10-15 07:11:50 +00:00
Ray XiandGitHub 784025c04a fix(daemon): resolve the AMR default model from the caller's catalog (#8519)
* fix(daemon): resolve the AMR default model from the caller's catalog

A run that asked for `default` before the caller's `vela model list` had
arrived was concretized from the bundled `vela model preset` seed. The
seed is the same for every plan and OD orders deepseek-v4-flash first, so
free-tier callers (entitled only to deepseek-v4.1-flash since 09-24) had
Vela reject `session/set_model` before any work began. On 0.24.1 that was
22 runs from 21 users in the last 7 days, 13 of 16 bundled runs showing
the user's choice as `default`.

- When `default` is requested and only the preset is cached, wait up to
  12s for the caller's remote catalog (`getAuthoritative`).
- Remember remote catalogs separately; a later preset seed never displaces
  one when a default model is chosen.
- Order deepseek-v4.1-flash first: it is the one chat model every plan,
  including free, is entitled to, so a flagless list still lands on it.

* fix(daemon): bound the AMR default-model catalog wait per refresh

CI follow-up. A `default` run looked the catalog up twice (the resume probe
and the run itself) and each lookup waited up to 12 s for the caller's
remote catalog, so a slow or broken `vela model list` held the run queued
for up to 24 s. The AMR e2e runs timed out at 20 s that way.

- The wait is counted from the start of the remote refresh, so one run, or
  several concurrent runs, share a single wait.
- When the last refresh failed, the preset is used at once; the next
  refresh still starts in the background.
- e2e fake vela: answer `model list --all --format json`, the form the
  daemon actually sends. It only matched the flag-less form and hung.

* test(e2e): let the fake vela answer the daemon's `model list --all` probe

The catalog probe spawns `vela model list --all --format json`. The matcher
stripped `--all` with its preceding space only, so `' --format json'` never
equalled `'--format json'`: the probe fell through to the login check, the
cache recorded a failed refresh, and default runs settled on the preset. Match
the subcommand and the `--format json` flags in any order, as fake-vela.mjs and
turn.test.ts already do, and cover the exact daemon argv for both the catalog
and the 401 path.
2026-10-15 03:57:51 +00:00
open-design-crew[bot]GitHubbone3deep1962-collabWilliamopen-design-crew[bot] <4197780+open-design-crew[bot]@users.noreply.github.com>NJUHuaAmy
14fee234e6 feat: add motion design workflow and curated motion skills (#8619)
* feat: add Motion Design skill and OD Next task route

* fix(web): rename motion design entry and place it second

* fix(web): reconcile motion design catalog consumers

* feat(web): add motion design templates to Home and Community

Five motion design example templates (3D procedural island, explainer,
product launch, showreel, data story), chosen by community reach, under the
Home motion-design chip and a new Community "Motion design" type.

Each template follows the bundled example layout: an OD-generated
example.html with its runtime libraries under assets/, an HTML preview baked
by the existing preview pipeline, and a SKILL.md that carries example.html
as the reference when the card is picked on the OD Next motion-design route.
Home cards ship curated copy for every UI locale. Motion templates stay off
the Video and HyperFrames chips.

* fix(skills): keep motion-design procedural layers visible in video export

The MP4 exporter seeks timelines with callbacks suppressed
(renderSeek(t, { suppressEvents: true })), so content drawn only from a GSAP
onUpdate callback is missing from exported video. Recommend a per-frame draw
loop that reads the timeline clock, and state that visible content must not
depend on timeline callbacks. The OD Next task asset is re-synced with
scripts/sync-motion-design-skill.ts.

* fix(motion): preserve reference assets and exported animation frames

* feat(skills): integrate curated motion helpers with complete runtime files

* feat(skills): add Huashu, Oil Motion and Motion.Lab adapters

* test: classify animate design guidance in narration guard

* feat(motion): refine five community templates and portable previews

* fix(motion): refine launch transitions and center gallery previews

* fix: allow free-form briefs on automatic motion task route

* feat(motion): add template soundtracks and audio export

* fix(motion): require rendered MP4 alongside editable video source

* test(motion): align strategy activation expectation with package version

* fix: scope motion delivery and make editable sources playable

* fix(motion): bundle source dependencies and valid closing protocol

* feat(motion): rebuild the five templates on the most-viewed community posts

Re-select topics by single-post views in the latest awesome-opus-5.5-video
snapshot and anchor each template to the top eligible post of its genre:
camera-focus explainer, showreel, product launch, procedural island and a
new wordless animated short that replaces the data story.

All five example.html files are hand-authored canvas/Three.js films drawn by
one render(t) from the GSAP master timeline, so preview, scrubbing and MP4
export produce identical frames. Each ships an original procedural
soundtrack, updated SKILL.md and 19-locale copy; Home order follows reach.

* fix(plugins): load bundled fonts in plugin previews

Plugin previews blocked every bundled font: the preview CSP had no font-src,
and relative url() references inside inline <style> blocks kept pointing at
the preview URL instead of the plugin folder. Allow same-origin fonts, map
inline-style url() references through the existing asset route (escapes,
absolute and data: URLs stay untouched), and serve font files with font
MIME types.

* feat(community): make motion template Use match the Home example pick

Community 「做同款」 on a motion design template now binds it as that type's
own example card, carrying the type's project metadata, so the run takes the
same OD Next motion-design route as a pick from Home's motion design list and
delivers the MP4 together with the editable source. Other task types keep
the existing plugin-pinning hand-off.

Community use clicks now record use_source (card | detail_modal) and
use_action (use | use_with_query); the details modal Use is tracked for the
first time. The Home hand-off no longer records a second community_gallery
click for uses Community already tracked.

* fix(plugins): count the five motion templates in the official registry metadata

* fix(media): keep HyperFrames audio filters compatible with FFmpeg 4.1

CI's bundled Linux FFmpeg 4.1 rejects adelay all=1 and amix normalize=0.
Make each track stereo and delay both channels explicitly, skip amix for a
single track, and undo amix averaging with a gain for several tracks.

* fix(motion): keep template previews bakeable on slow CI renderers

CI's software-GL baker skipped the 3D island (preview readiness timeout):
under slow frames GSAP lag smoothing slowed the timeline, so the 8 s
poster frame never arrived within the baker's 15 s wait. Play every
template on the wall clock and move the island poster to 6 s. With
simulated 300 ms frames all five now report ready within 10 s.

* feat(motion): add the kinetic typography template

Template selection now follows the motion design spec's four content types
(brand and product films, kinetic typography, explainer animation, procedural
art). Kinetic typography takes the fifth slot, replacing the animated short.
The new template is a 15-second, 120 BPM type film with an original
soundtrack and 19-locale copy.

* fix(motion): let the project motion player fit template stages

Inside a project the motion source player wraps the composition, fits it and
adds its own controls. The templates also scaled their stage, so editable
sources from Remix and Community use rendered at a fraction of the preview.
Templates now keep their own fit and controls only outside that player.

* feat(motion): restage the 3D island as a midday lagoon

The island moves from golden hour to a bright tropical midday closer to its
anchor post: a shader lagoon coloured by a baked depth map with ripples,
shallow-water shimmer and shore foam, a wide white-sand beach, palms and
instanced bushes, a village with a pier, soft sun shadows and a lower
camera path. The CPU wave mesh is gone, so frames cost no more than before.
Copy is updated in all 19 locales.

* fix(motion): keep each soundtrack inside the composition root

A Community use regenerated the island source tail and dropped the root
<audio> element, so its MP4 had no sound. Templates now place the element
inside the composition root next to the stage.

* docs(motion): state the template selection rule as complete works

* fix(motion): enforce video clocks and bound content verification

* feat(motion): replace the motion templates with remakes of viral posts

The five Motion design templates are now frame-faithful remakes of viral
motion posts, so each preview shows the look users came for: the 15-second
motion designer showreel, a high-energy motion reel (copy set in English), a
one-shape UI motion piece, a pixel-art wizard and a 20-second electric-blue
tech reel. Each ships open-licensed fonts, an original soundtrack, the
creator's published prompt where one exists, and credits its source post.

The explainer, product launch, 3D island and kinetic type templates are
removed. Tests follow the new set; a backward-seek check now covers hidden
WebGL layers.

* feat(motion): feature The Future Is Already Here first and start preview sound with the film

* chore: ensure PR CI

* fix(motion): match The Future Is Already Here controls and reorder the motion templates

* fix(motion): make the one-shape UI preview controls legible

* fix(motion): hide The Future Is Already Here controls inside the project player

* fix(motion): plan suitable sound and synchronize source audio playback

* feat(motion): keep remake soundtracks by default and fade exported audio where it stops

* test(motion): cover audible source controls in Chromium

* fix(test): use explicit ESM imports in audio player regression

* fix(motion): align preview track discovery with video export

* feat(motion): autoplay looping HTML without a player bar

* fix(test): consume the built motion playback contract

* docs(motion): state explicit soundtrack rules for make-same and the music line in replies

* chore(motion): version the audible looping delivery profile

* docs(motion): let template sound rules lead the general policy and freeze the audio contract

* fix(motion): scope autoplay to declared video motion sources

* fix(motion): reject audible MP4s under an explicit silent contract

* docs(motion): drop the routine music note from make-same replies

* test(motion): align delivery regressions with looping source playback

* fix(motion): isolate preview and audio export from legacy HyperFrames

* test(motion): retain the existing desktop legacy audio limitation

* fix(motion): suspend audio when previews leave the active workspace

* feat(motion): replace two motion templates with a product promo and a visual lesson; sign the showreel as Open Design

* feat(motion): give the showreel the Open Design palette and a full-size stacked wordmark

* feat(motion): give the product promo a livelier mascot girl

* refactor(motion): rebuild The Future Is Already Here as readable, editable scene code

* fix(motion): pick gallery cover frames that survive the baker's capture delay

* feat(motion): sharpen the showreel opener, depth, truchet and end card

* feat(motion): make the product promo mascot talk, add a speaking score and the flow pop

* feat(motion): give the visual lesson the original's paper-collage texture

* fix(motion): bundle gallery covers for fresh branch checkouts

* feat(motion): feature and refine Bring Ideas to Life

Adapt the paper story around OpenDesign capabilities, with short rounded hands, clearer timing, continuous paper actions, and a larger audience invitation. Feature it first in Motion and synchronize localized names, metadata, cover, guidance, and regressions.

Keep product promo audio music-only with sparse percussion.

* fix(motion): stabilize artifact cards and capture declared covers

* fix(web): share creation type order with community

* test(motion): exercise audio controls through project UI lifecycle

* fix(motion): scope live cover behavior to actual video sources

* test(motion): use real HEAD responses in cover regressions

---------

Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com>
Co-authored-by: William <zhouhaoran@refly.ai>
Co-authored-by: open-design-crew[bot] <4197780+open-design-crew[bot]@users.noreply.github.com>
Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
Co-authored-by: Amy <1184569493@qq.com>
2026-10-14 15:55:52 +00:00
CaprikaandGitHub 3faaab0f20 fix(e2e): align packaged Codex fixture with recipe identity (#8727) 2026-10-14 09:11:23 +00:00
e0b250663d fix(release): allow re-cutting an unchanged packaged version (#8725)
Co-authored-by: lefarcen <935902669@qq.com>
2026-10-14 07:53:13 +00:00
014bffbf77 fix(collab): synchronize owner devices with overwrite consent (#8683)
* fix(collab): synchronize owner devices with overwrite consent

* docs(collab): add owner device synchronization QA handoff

* chore(collab): move delivery reports and screenshots to Plane

* fix(collab): preserve owner pull fallback and ghost heal

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

* fix(collab): probe null owner heads for retractions

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

* fix(collab): preserve manual checks across coalescing

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

* feat(collab): hide update check behind a dismissed-version badge

Show the header entry only when the owner skipped a cloud version, as a
"Cloud update available" badge that re-opens the overwrite dialog.
Rewrite the dialog description in plain product language.

* fix(collab): clarify device sync copy and place entry before present

* fix(collab): silence update reminders without automatic overwrite

---------

Co-authored-by: Looper <looper@noreply.github.com>
Co-authored-by: elifive555555 <296440099+elifive555555@users.noreply.github.com>
2026-10-13 11:14:14 +00:00
424f5c68cc fix(od-next): remove output-contract gates and unblock continuation (#8356)
* fix(od-next): continue plans with keyed markers and honor explicit deliverables

* fix(od-next): retire output contracts and hand off continued tasks

* fix(od-next): record round settlement and recover production cold

* fix(od-next): resume marker sessions with context deltas

* fix(od-next): separate completion facts and honor plan-only intent

* fix(od-next): preserve physical failures and legacy chat compatibility

* test(web): align run recovery fixtures and await campaign mount

* fix(od-next): tolerate terminal production marker formatting

* fix(od-next): unblock follow-ups after a stop or unreadable history (#8423)

Treat a previous task this build cannot read as absent so the follow-up starts a new task, and stop counting a Run with a pending cancel as holding its conversation. Add end-to-end coverage for the marker continuation flow and restore the remote Workspace directory gate cases.

* docs: clarify focused local validation

Keep local daemon and web validation scoped to affected files and integration boundaries. Reserve full suites for PR CI unless the user explicitly requests them.

* fix(web): scope folded task completion to its final run

Keep the final physical Run key and conclusion together when OD Next history is folded or accumulated live. Reuse the existing predecessor offsets while retaining the full display history and remaining Todo snapshot.

Add regression coverage for completed and unfinished production, live continuation, multiple Runs, legacy history, wrong and quoted markers, question handoff, and failed or canceled Runs.

Validated the parent regression before the fix, 165 focused Web tests, workspace typecheck, and guard.

* fix(od-next): compact historical context without restricting clarification

Reuse confirmed artifact summaries for old assistant history, preserve cross-agent plans and original requests, and represent earlier questionnaires as neutral historical information without inferring answers.

Keep user replies, skips, changed answers, unpersisted bodies, examples, and unfamiliar content intact. Do not add question repetition checks, output gates, repair rounds, or limits on clarification.

Validated red regressions, shared context and Web provider tests, focused handoff/resume/cold-production coverage, real server and fake CLI input, workspace typecheck, and guard. The repeated-question server fixture remains successful.

---------

Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com>
Co-authored-by: Cheems <hihicheems@gmail.com>
Co-authored-by: Cheems <94773058+itscheems@users.noreply.github.com>
2026-10-13 10:32:45 +00:00
netteeandGitHub 9041ca60bc chore(release): bump main to 0.25.0 ahead of stable 0.24.1 (#8700) 2026-10-13 03:28:22 +00:00
af48a420eb fix(web): keep empty Home content reachable in short windows (#8649)
* fix(web): keep empty Home content reachable in short windows

Use safe centering when the empty Home hero exceeds the scroll viewport, and let wheel input continue from the examples list to Home at its boundaries.

Add CLI and BYOK browser regression coverage for short windows, responsive boundaries, scrolling, and centering when content fits. Validated with the focused Playwright cases, pnpm guard, and pnpm typecheck.

* test(web): align Home acceptance with safe centering

Update the existing empty-Home style acceptance to expect safe center while preserving its padding checks. The accepted layout change keeps content reachable when the hero exceeds the viewport.

Verified the CI assertion fails before the test update and all 8 cases in acceptance-visual-fixes.test.ts pass afterward. Also passed pnpm guard, pnpm typecheck, focused TypeScript diagnostics, and git diff --check.

* test(web): cover safe Home scroll boundaries

---------

Co-authored-by: PerishCode <perishcode@gmail.com>
2026-10-12 09:32:52 +00:00
lefarcenandGitHub 39e8301764 fix(daemon): drive Antigravity through agy's stream-json stdin channel (Windows ENAMETOOLONG) (#8594)
* fix(daemon): deliver Antigravity prompt on stdin to avoid Windows ENAMETOOLONG

agy received the full composed OD prompt as the -p argument. On Windows
that routinely exceeds CreateProcess's 32,767-char command line, so the
spawn failed with ENAMETOOLONG before agy started and users saw a generic
"This task failed to run" (OPEND-3495).

Pass a short fixed pointer as the -p value and deliver the prompt on stdin,
which agy print mode reads (verified on agy 1.3.1).

* fix(daemon): drive Antigravity through agy's stream-json stdin channel

The previous attempt passed `-p "Follow the instructions provided on
stdin."` and wrote the prompt to stdin, but agy ignores stdin whenever a
prompt is given with `-p` (agy 1.1.1), so the model never received the
OpenDesign prompt. Earlier "successes" came from the model reading files
in its working directory on its own.

agy's documented headless stdin channel is
`--input-format stream-json --output-format stream-json`, which reads
one NDJSON `{"event":"user","message":{"content":...}}` message per
turn. The prompt now travels only through that frame, handed over as a
complete file-backed stdin at spawn, so argv no longer grows with the
prompt (fixes Windows `spawn ENAMETOOLONG`, OPEND-3495).

- add an `encodeStdinPrompt` runtime hook used by the chat-run spawn and
  the connection test
- parse agy stream-json events (text deltas, tool steps, terminal
  result, usage) in json-event-stream, falling back to the Gemini JSONL
  branch for frames without `event`
- drop the antigravity-only plain-stdout buffering, Gemini re-parse and
  log-file empty-output classification
- recognise agy's headless signed-out output as AGENT_AUTH_REQUIRED and
  keep the per-model quota guidance for `Individual quota reached`
- fixtures recorded from agy 1.3.1 plus the samples in agy's headless docs

* fix(web): show Antigravity quota guidance instead of the generic run-failure copy

The Antigravity RATE_LIMITED card had no message key, so it rendered
chat.runError.fallbackMessage ("This task failed to run. Please retry")
-- the exact sentence in the OPEND-3495 report -- with no hint that the
per-model quota was the cause. Give it its own copy (switch model in the
model menu or via agy /model) and the quotaExhausted title, in all 19
locales.

* Revert "fix(web): show Antigravity quota guidance instead of the generic run-failure copy"

This reverts commit 68a84c3ff3.

The Antigravity rate-limit card intentionally uses the generic approved
copy (#8140, product copy supplement rev 96): blank product rows get no
invented copy, and the P0 e2e 'antigravity rate limits keep
classification and use only the Cloud switch' pins that behavior.
2026-10-12 03:57:38 +00:00
802708f6c9 feat(web): land sign-in on Hosted and pitch free credits across entry points (#8567)
* feat(web): land sign-in on Hosted and pitch free credits across entry points

- Onboarding: drop the "Choose your model source" step. Signing in from the
  welcome screen finishes onboarding on OpenDesign Hosted; Local AI and API Key
  stay reachable from the welcome screen. Hosted select_runtime now reports
  step `connect` instead of `model_source`.
- Welcome screen: the pending sign-in shows one quiet "Sign-in page didn't
  open? Reopen" line (after 5s, or at once when the browser failed to open)
  instead of a nested card with two cancels, and the primary button no longer
  moves between idle and pending states.
- Home rail card: "Get free credits" pitch with a sparkle mark; the pending
  state turns the call to action into "Signing in…" with a single cancel and
  the same delayed reopen line. Dark mode keeps the button visible.
- Settings → Local CLI: callout reuses the free-credits copy; selecting a
  signed-out OpenDesign row selects it in place and offers Sign up / Sign in
  (no bounce to onboarding), committing the CLI once a session exists. Both
  buttons share the solid pill and show "Signing in… | Cancel".
- Fix the selected CLI card flashing on hover, and make the Home @ picker
  tabs clickable where they overlap the desktop window's drag strip.

* fix(web): drop pending OpenDesign pick when DeepSeek Harness setup commits

Installing DeepSeek Harness from its setup dialog committed agentId without
clearing amrPendingSelect, so the OpenDesign card stayed highlighted and a
later sign-in overwrote the DeepSeek choice with 'amr'. Clear the pending
intent alongside that commit and cover the sequence with a regression test.

---------

Co-authored-by: elifive555555 <296440099+elifive555555@users.noreply.github.com>
2026-10-09 11:45:47 +00:00
d9dd6fefa7 feat(release): add one-dispatch withdrawal for an unshipped cut (#8509)
* feat(release): add one-dispatch withdrawal for an unshipped cut

A release that was cut but will not ship had no undo. cut-release creates a
branch, a backport label, a Feishu card, and — through the prerelease build its
push triggers — moves prerelease/latest onto the new line. Abandoning that
version meant reversing four surfaces by hand, and the one that actually
matters is easy to forget: internal validators auto-update, so they sit on a
package nobody intends to release.

release-withdraw reverses each, in the order that leaves the least mess if a
later step fails: repoint prerelease/latest at an older published prerelease,
delete the label, delete the branch, post the matching withdrawal card. The
branch delete uses the release App token because the release/v* ruleset blocks
deletion and that App is one of its bypass actors — the same token that created
the branch.

It refuses more than it does. A version that reached stable is not an unshipped
cut, and the error names release-rollback instead. A branch carrying any commit
that is not on main and not from the release bots would lose work, so it stops.
Open PRs targeting the branch, or still carrying its label, stop it. The
prerelease pointer is read live rather than trusted from the input, and is only
moved when it actually belongs to the withdrawn version — at which point a
target becomes mandatory rather than silently skipped. dry_run defaults to true:
a withdrawal is never the urgent case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(release): make the withdrawal queue behind the pointer's other writer, and give the dry run teeth

Both findings from review.

Concurrency. `open-design-release-withdraw` was a group of one, so it serialised
this workflow against nothing, and the header comment claimed a guarantee it
never had. `release-prerelease.yml` is the only other writer of
`prerelease/latest` and holds `open-design-release-prerelease`; the withdrawal
now joins it.

The publish this races is the ordinary cut timeline, not a manual re-run: the cut
push and the preview-manifest push that follows each start
`notify-release-feishu` -> `release-prerelease`. Three failures came from the
unique group. Reading the pointer before an in-flight publish finishes resolves
`belongs=false`, so the repoint is skipped and the publish then installs the
withdrawn version after a green run. Interleaved writes mix `latest`, because
the publisher writes metadata first and feeds second while `applyLatestRollback`
writes feeds first and metadata last, and every PUT is unconditional. And a
publish landing *after* a repoint restores the abandoned pointer, because the
publisher's CAS refuses only backward moves.

The group is workflow-level and must stay that way, which is the part worth
keeping in mind: it is held through the branch delete, so a queued trailing
publish cannot enter the publisher until `release/vX.Y.Z` is gone and then fails
closed on a checkout of a deleted ref. A job-level group would release the lock
first and lose that. A P0 assertion pins the shared string against
release-prerelease — renaming the publisher's group now breaks a test rather
than the invariant — and pins the single workflow-level block.

`cut-release.yml` stays out of the group: it writes no R2 object of its own, and
what needed serialising was the publisher it triggers.

The branch also gets a compare-and-delete, re-reading the tip and refusing if it
has moved off the SHA that "nothing but cut commits" and "no open PRs" were
established against. Not a substitute for the lock, which is what fixes the
publish race — this covers the likelier window the lock does not see, a backport
landing while a human reads the dry run. GitHub's ref delete takes no
expected-SHA precondition, so the compare is explicit.

Dry run. `Setup pnpm`, `Install dependencies` and `Repoint prerelease latest`
were all gated on `!inputs.dry_run`, which removed the credentialed half of the
validation from the mode that exists to validate. `prerelease_to_version` only
had to be syntactically plausible: an absent, incompletely published or
feed-less target, or one below the prerelease launcher floor, passed the plan and
failed for the first time during the real run. It still fails before the label
and branch deletes, so nothing was destroyed by it — but the dry run is the path
this workflow tells the operator to trust, and `[P0] plans before it destroys`
required `!inputs.dry_run` on the repoint step, locking the skip in.

The three steps now run whenever the pointer needs moving and the planner takes
`RELEASE_DRY_RUN: ${{ inputs.dry_run }}`, matching how release-rollback already
wires it. "The dry run passed" now means the real run has nothing left to
discover, and the header and the step summary say so. The two deletions and the
Feishu card stay gated on the input.

Each of the five behaviours was mutation-checked: reverted at exactly one site
(three for the `if:` gate), exactly one test went red. Workflows re-linted with
the CI-pinned pair, actionlint 1.7.12 with shellcheck 0.11.0 on PATH, proven
wired by a probe workflow that reports SC2086.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-09 07:11:02 +00:00
PerishFireandGitHub 92fe7e87b1 feat(release): decouple stable Docker reconciliation (#8517) 2026-10-08 07:52:45 +00:00
1bf9bf52f0 fix(projects): settle empty catalogs and expose list failures (#8443)
Co-authored-by: lefarcen <935902669@qq.com>
2026-10-08 05:28:22 +00:00
5b19dfa435 fix(release): resolve the rollback tag from published metadata (#8508)
The first live dry run failed at the badge preflight: I had written the tag
as v<version>, but prepare-stable.ts publishes open-design-v<version>. A
hand-built prefix reads plausibly and is wrong, so take the tag from
.versionTag in the restored release's own immutable metadata — the value the
publisher recorded — probing the same prefix candidates rollback-latest.ts
probes, and hand it to the badge step as a step output.

The summary checklist had the same wrong shape; it now names the version
rather than constructing a tag. The regression test pins both: the tag must
come from .versionTag, and no step may rebuild one from the version input.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-29 03:41:33 +00:00
54139504d4 feat(release): add one-dispatch stable rollback (#8507)
* feat(release): add one-dispatch stable rollback

A stable release publishes its artifacts to an immutable
stable/versions/<version> prefix and then copies the pointer objects into
stable/latest. latest is therefore derived state, and retracting a release is
copying an older version prefix over it again — but until now nothing in the
repo could do that, so a bad stable release had no stop button.

Add `tools-release rollback-latest` plus a release-rollback workflow that
dispatches it. The CLI refuses unless the live pointer still serves the version
the operator typed as from_version, the target published completely (not
partial, not a dry run), every ready platform's manifest and updater feed exist
in the target prefix, and the current installer floor is satisfiable by the
target. It re-resolves control.launcher.version from live channel policy rather
than restoring the snapshot's, records rollback provenance, writes metadata.json
last so latest never advertises a version whose feeds it does not yet serve, and
verifies every object through both the origin and the public URL.

The workflow shares release-stable's publish concurrency group so a rollback
cannot overlap a publish, moves only the GitHub Release "Latest" badge (never a
release body), and ends with a checklist of what a rollback does not reach: the
download page's version-pinned links, the What's New card, the group
announcement, and above all the installs already on the retracted version —
the updater never offers a version that is not strictly newer than the running
one, so this stops a rollout and cannot recall one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(release): group the rollback summary fallback redirects

shellcheck SC2129 — CI runs actionlint with shellcheck wired in, which my
local actionlint could not see without it installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(release): prove the restored tag has a release before writing

The badge move runs after the R2 write, so a missing GitHub Release for the
restored version would have failed the run with stable/latest already moved.
Check it up front instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(release): pass the stable installer-floor policy into rollback

resolveLauncherVersionFloor() reads process env, and repository variables are
not process env. Without the handoff a rollback resolved no floor at all: it
would strip an active control.launcher.version from the restored metadata and
stop refusing targets below the current minimum — the safeguard the workflow
documents as enforced. Latent today only because no stable floor is set.

release-stable.yml passes the same pair to metadata publish and verify; mirror
it, with a topology assertion so a later edit cannot drop it silently. Also
stamp RELEASE_BRANCH/RELEASE_COMMIT so the rollback provenance is not blank.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(release): require the restored release to be badge-eligible

gh release view succeeds for a draft or a prerelease, but GitHub will not put
the Latest badge on either — so the preflight passed and the edit failed with
the R2 rollback already done, which is the half-complete state the preflight
exists to prevent. Check isDraft and isPrerelease too, and cover the
eligibility guard in the workflow test alongside its ordering.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-29 03:21:12 +00:00
PerishFireandGitHub b52fafd474 feat(ci): enforce reusable workload plans (#8393)
* feat(ci): enforce reusable workload plans

* fix(ci): skip incompatible convergence upgrades
2026-09-28 08:29:12 +00:00
eb27acd322 feat(billing): support Coding Plan usage and wallet fallback (#8339)
* feat(billing): support Coding Plan usage and wallet fallback

* fix(web): keep AMR send off billing preflight

Workspace send no longer waits on advisory vela billing preflight; recovery still requests it. Realign zero-wallet P0 oracles and the credits-card wallet label.

Generated-By: looper 0.15.0 (runner=fixer, agent=omp)

* fix(billing): serialize recovery preflight and bound hung vela

Skip overlapping AmrBalanceDialog recovery ticks and stop the watch after
ten minutes even if a preflight is still pending. Give vela billing
preflight a 60s runVelaCommand timeout so a hung CLI cannot pin recovery.

Generated-By: looper 0.15.0 (runner=fixer, agent=omp)

* fix(web): restore coding plan text contrast in billing card

* feat(web): render Coding Plan windows and Go tier in the credits panel

- CodingPlanUsage renders one row per preflight window (name, used %,
  remaining USD, reset countdown + absolute time) with loading/unavailable
  states; refreshes once on mount and once at resetsAt (no 30s polling,
  setTimeout delay clamped to the 32-bit limit).
- Pure model in coding-plan-usage-model.ts; creditsPerUsd comes from
  `vela billing summary` through WorkspaceBillingSummary and falls back to
  10,000 only when the backend omits it.
- PlanWordmark/EntryNavRail accept the `go` tier (placeholder wordmark,
  design asset still pending).
- i18n: 7 new billing keys + entry.billingTierGo across all 19 locales;
  real translations for the #8339 keys; drop unused codingPlanNone /
  codingPlanRemaining.
- CLI wording: unstarted window reads "not started yet".

* build(pack): pin vela-cli 0.1.4-test.0 and gate on billing preflight

The packaged client needs `vela billing preflight` for the Coding Plan
window rows. Bump the bundled CLI to the npm `test` prerelease that ships
it and add a third capability gate in tools-pack: a CLI without the
subcommand prints the parent `billing` help and exits 0, so the gate
checks the help markers (preflight, --workspace-id, --model, --format)
instead of the exit code.

TEMPORARY: replace 0.1.4-test.0 with the stable 0.1.4 once it is
released; do not merge with a `test` prerelease pinned.

* fix(web): make Coding Plan rows legible on the inverted credits card

The credits card is a hard-coded #202020/#fafafa inverted surface, but
CodingPlanUsage.module.css read page-level --text-* / --bg-fill-* tokens,
so on the card the window names rendered #202020 on #202020 (1.00:1) and
the stat/reset lines sat below WCAG AA. Derive every colour from
currentColor instead (name 100%, stat 72%, reset/note 60%, separator ~50%,
track 36%, exhausted = --red mixed toward currentColor); measured in Chrome:
name 15.6:1, stat 8.7:1, reset 6.4:1, track 3.2:1, exhausted 6.5:1.

Keep the stat on one line (nowrap) and let the name ellipsize instead of
wrapping "60% / used" onto two lines; drop the block's 12px side padding so
it aligns with the card's own rows.

Also add a minutes tier to the reset countdown: the last hour before a
window resets used to show no countdown at all. New key
billing.codingPlanResetsInMinutes in all 19 locales.

* feat(web): rebuild the plan panel 1:1 from design PR #8364

Replace the improvised Coding Plan block with the design's panel, measured
against docs/ui-previews/plan-panels/index.html in Chrome (computed styles
and a 4x pixel diff of the Plus specimen):

- Header: tier name + 16px wordmark, 升级 pill (管理 on the top tier).
- One row 「7天额度免费用 · 已用 N% ›」 (7-day window only; rounded percent;
  100% when spent, no red state) over a 5px #b1f38b track, then the
  separator and the 「钱包余额 · US$x.xx ›」 row. No headings, window names,
  remaining USD, reset time, note or unavailable line.
- Team workspaces keep the pre-existing card unchanged (all team_* tiers);
  the quota row renders only for personal workspaces.
- Free personal workspace: no quota row, but the header sells 升级 like the
  design (a personal workspace needs no billing permission; an account B
  reports without a plan upgrades as free).
- Top-right pill shows the wordmark only, no balance.
- Wallet always reads US$ regardless of locale (product ruling 2026-09-23).
- zh-CN tier names follow the design: 免费版 / 标准版 / 专业版 / 旗舰版.
- Drop the dead billing.codingPlan* keys and model helpers; add
  billing.codingPlanWeeklyAllowance and entry.creditsManage in 19 locales.

* feat(web): show 管理 on personal Max per design PR #8364

The design's Max card sells 管理 (console auto-recharge settings) where
every other tier sells 升级; product ruled on 2026-09-23 to follow the
design for personal Max too, superseding the earlier "personal tiers are
always upgradeable" ruling. The gate now asks isMaxPlanTier and 管理 wins
over 升级 when both would show.

* feat(web): route the plan card's three entries per product ruling

2026-09-23 ruling on the card's landings: 升级 opens the console's pricing
dialog (billing=plan, unchanged), the allowance row opens the console
dashboard (unchanged), the wallet row asks for the manual top-up dialog
(new billing=recharge intent; B does not honor it yet and degrades to the
dashboard), and 管理 on Max opens the plain dashboard instead of the
auto-recharge dialog.

* fix(web): align personal plan cards with v2 design and scoped loading

* fix(web): center plan wordmarks inside the top-right pill

* fix(web): reuse shared billing cache for plan hover cards

* test(web): match personal billing preflight in avatar fixture

* fix(billing): require usable quota evidence for funding recovery

* test(billing): cover scoped preflight and quota event refresh end to end

* feat(daemon): relay scoped coding plan usage events and health

* fix(billing): refresh quota caches from scoped realtime events

* test(daemon): accept capability query on mock event stream

---------

Co-authored-by: lefarcen <935902669@qq.com>
2026-09-24 03:22:31 +00:00
5885573546 feat(web): localize welcome screen and starter credit ribbon (#8351)
Co-authored-by: elifive555555 <296440099+elifive555555@users.noreply.github.com>
2026-09-24 03:13:16 +00:00
PerishFireandGitHub 00c2d8ae57 feat(plan): establish reusable workload and postinstall contracts (#8383)
* feat(plan): add verified atomic workload product restoration

* perf(plan): probe product availability without downloading payloads

* refactor(ci): formalize workspace initialization plans

* feat(plan): add versioned workload execution contracts

* refactor(plan): colocate postinstall defaults and docs

* fix(convergence): enforce cache result integrity
2026-09-23 07:57:35 +00:00
94f27cb0ab fix(e2e): align smoke fixtures with OD Next execution intent (#8329)
Co-authored-by: lefarcen <935902669@qq.com>
2026-09-21 11:57:41 +00:00
open-design-release-bot[bot]GitHubopen-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
894d55466b chore(release): bump main to 0.23.1 ahead of stable 0.23.0 (#8300)
Co-authored-by: open-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
2026-09-21 03:48:10 +00:00