Commit Graph
2568 Commits
Author SHA1 Message Date
7840acb23d [codex] Pick PR #4952 to main (#4983)
* Fix logo previews and AMR card layout (#4952)

Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local>
(cherry picked from commit bda86f48f0)

* Align Chinese AMR manage labels

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

---------

Co-authored-by: chaoxiaoche <fanzhen@refly.ai>
Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local>
Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-07-01 10:05:42 +00:00
b1d4e59003 feat(landing-page): strengthen the vibe-design pillar + hub-and-spoke internal links (#5003)
* feat(landing-page): strengthen the vibe-design pillar + wire hub-and-spoke links

The 4 vibe-design blog posts were splitting the bare "vibe design" query
across each other (GSC: 3 pages clustered at pos 5-6 in the same locale),
and the pillar (what-is-vibe-design) under-competed the top-ranking guides
(Visily ~2,200 words + FAQ + decision matrix; Cerence ~2,100).

Upgrade what-is-vibe-design into a proper pillar:
- Add a "When vibe design is the right call — and when it isn't" decision
  section and a 7-question FAQ (PAA / featured-snippet surface), taking the
  body from ~1,150 to ~1,860 words.
- Complete the hub-and-spoke: the pillar now links out to all three cluster
  posts (vibe-design-tools, vibe-design-vs-vibe-coding, vibe-design-with-stitch)
  in-context, consolidating topical authority on the pillar and clarifying to
  search engines which page owns the head term.
- Sharpen the differentiator competitors miss — prompt to shipped code,
  open-source, agent-native — since Visily stops at a mockup and Cerence is an
  interview.

Follow-up: re-translate the localized bodyHtml (keep-11 locales) to match.
Locale pages keep their prior full translation until then (not broken, just
one version behind).

* fix(landing-page): keep vibe-design readingTime aligned with translated bodies

readingTime is a shared field the blog template renders for every locale.
Since this PR intentionally leaves the localized bodyHtml on the shorter
prior copy until the translation follow-up, keep readingTime at 6 so the
10 localized pages stay accurate; it moves to 9 in the localization PR when
every body grows to match the expanded English article.

* feat(landing-page): per-locale blog readingTime override

A shared readingTime can't be right for both the expanded English body and
the localized bodyHtml still on the shorter prior translation (reviewer:
9 overstates the localized pages, 6 understates English). Add an optional
per-locale readingTime to the blog i18n schema, render it in [slug].astro
when present, set the English body to 9, and pin the ten rendered locales
to 6 until the localization follow-up grows their bodies. Verified: EN shows
9 min, ja/de/es show 6.

* fix(landing-page): use per-locale readingTime on the blog index too

The detail page honored the per-locale readingTime override, but the blog
index (and its /[locale]/ wrapper) still rendered the shared English value
on both the featured and regular cards. Apply the same locale-aware lookup
there so non-English index cards match their article. Verified: EN index
card shows 9 min, JA shows 6.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-07-01 09:59:03 +00:00
Abhijit SinghandGitHub d270b401f2 fix(daemon): fail OpenCode tool-only empty responses (#4835)
* fix opencode tool-only empty responses

* fix reasoning-only empty responses
2026-07-01 09:36:34 +00:00
CaprikaandGitHub 8d83d24907 [codex] Keep AMR settings card actions inline (#4993)
* Keep AMR settings card actions inline

* Keep AMR plan badge outside clipped benefits

* Move AMR plan badge to account row

* Prevent AMR benefit badges from clipping

* Remove lower cost AMR badge

* Rename AMR console action to manage

* Carry over logo preview and AMR manage fixes
2026-07-01 09:08:43 +00:00
rebel-nexu-zero[bot]GitHubrebel-nexu-zero[bot] <rebel-nexu-zero[bot]@users.noreply.github.com>
3370d70144 fix(landing): remove AMR nav branding (#5001)
Co-authored-by: rebel-nexu-zero[bot] <rebel-nexu-zero[bot]@users.noreply.github.com>
2026-07-01 08:55:36 +00:00
Chanhyo JungandGitHub 6fb5c37108 Fix home submit handoff state (#4886) 2026-07-01 08:52:00 +00:00
lefarcenandGitHub 8b179ab996 fix(landing): reserve about-panel image aspect-ratio so the lazy-swap can't collapse (#4995)
PR #4987 tightened the homepage lazy-load margin (1500px -> 600px), so the
below-the-fold about-section paintings now swap in as the user scrolls to
them instead of being pre-loaded a full screen early. That exposed a latent
bug: `.about-panel-img img` was `width:100%; height:auto` with no reserved
ratio, so between the 1×1 placeholder and the decoded webp the box rendered
as a full-width 1:1 SQUARE (~320px too tall, showing the browser's
broken-image/alt glyph and overlapping the caption) before snapping to the
real ratio.

Reserve `aspect-ratio: 1768 / 1144` (the paintings' real dimensions) plus a
faint skeleton fill. The box is correct from first paint: a clean skeleton
while the webp streams, then zero layout shift when it lands.

Verified on a throttled connection: loading box is 900×582 (was 900×900),
CLS shift 0px, and the painting fills the box exactly on decode.
2026-07-01 08:41:30 +00:00
jzhishuandGitHub e61b86b48d fix(web): show seven recent projects on wide home layouts (#4628)
* fix(web): show seven recent projects on wide home layouts

* fix(web): remeasure recent projects row after load
2026-07-01 07:58:51 +00:00
jzhishuandGitHub 33f9a49c6b fix(web): keep buttons in one row (#4785) 2026-07-01 07:58:24 +00:00
7fa6ed2fdb feat(landing-page): add screenshot-to-code + AI prototype generator tool pages (#4991)
Batch 3 of the /solutions/ tool-page family (SEMrush-picked), built from
the same template as batches 1-2:

- /solutions/screenshot-to-code/ targets the "screenshot to code" intent
  — drop in an image of any UI and the agent rebuilds it as clean,
  component-based code. Distinct input modality from design-to-code and
  figma-to-code.
- /solutions/ai-prototype-generator/ targets "ai prototype generator"
  (Commercial intent, competitor long-tails vs Figma/Cursor/Penpot).
  Deliberately differentiated from the existing /solutions/prototype/
  use-case page: distinct H1 ("The AI prototype generator that ships
  code" vs "Prototype at the speed of a prompt"), generator/tool framing,
  competitor comparison, and the two pages cross-link so Google reads them
  as complementary rather than duplicate.

Both reuse the .solution-page layout, ship a warm-paper hero
illustration, join the Solution dropdown + hub Tools group (now seven
generators), cross-link the cluster, breadcrumb under the /solutions/
hub, and are localized to all keep-11 locales (en/zh first-party, the
other nine Agent-translated).

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-07-01 07:00:33 +00:00
lefarcenandGitHub 101a42cb0d perf(landing): cut homepage LCP — defer JS + below-fold art, shrink backdrops, early locale redirect (#4987)
* perf(landing): load matter-js + cobe on demand, not inlined

The homepage inlined the full matter-js physics engine (~83KB) and the
cobe globe runtime (~13KB) into every document, even though both are
below-the-fold decorations. That shipped ~96KB of decorative JavaScript
in the critical HTML to every visitor — phones and reduced-motion
readers included — inflating the document the browser must download and
parse before the page settles.

Vendor both runtimes to public/enhancers/*.js (regenerated from
node_modules on every build/dev, so they always match the installed
versions) and inject each one via IntersectionObserver only when its
section nears the viewport. Reduced-motion readers skip the matter-js
download entirely and just get the server-rendered banner.

The site still ships zero Astro-bundled / ES-module JavaScript — these
are hand-vendored classic scripts injected by a runtime-created script
element, so the `Verify zero external JavaScript` gate stays green.

Homepage document: 358KB -> 264KB (brotli wire 94KB -> 51KB); the two
runtimes now load lazily, cached immutably per versioned URL.

* perf(landing): defer below-the-fold homepage art off the LCP path

The Cloudflare RUM network trace showed homepage LCP (~2.4s, the hero
webp) was starved of bandwidth: ~1.9MB of images — most of it below the
fold — was fetched in the first ~700ms and competed with the hero for
the connection. Culprits: two full-bleed section backdrops loaded via
CSS `::before` (lab-stage-art 454KB, cta-bg 335KB), the Labs dock
preloading ~500KB of preview stills on init, the contributor orbit
building ~350KB of avatars on init, and a few raw eager <img>.

Defer all of it until its section nears the viewport:

- precise-lazyload gains a `data-precise-bg` mode (adds `.precise-bg-in`,
  which the CSS uses to gate the `::before` background-image — you can't
  set a pseudo-element's background from JS) and a configurable
  `imgRootMargin`. The homepage mounts it at 600px instead of the catalog
  default 1500px so its heavy art doesn't join the initial burst.
- A shared `__whenNear(selector, cb)` helper gates the Labs dock
  (`enhanceLabSwitch`) and contributor orbit (`enhanceContributorOrbit`)
  init behind an IntersectionObserver.
- `cta-window` gets `loading="lazy"`; the near-fold hero product shot gets
  `fetchpriority="low"` so the hero-bg (the LCP element) wins the pipe.

Verified in a headless browser against the built site: initial requests
drop 50 -> 20, the ~1.76MB of below-fold art is withheld until scrolled
to (then loads on cue), CLS stays 0.001, and every enhancer still works
(section backdrops paint, Labs dock switches, falling-text physics runs
23/23, globe renders, 16 contributor avatars build).

* perf(landing): shrink oversized homepage backdrops to display size

The two full-bleed section backdrops shipped far more pixels than they
ever render: cta-bg was 2776×1554 (335KB) and lab-stage-art 2262×1358
(454KB), but both display at roughly 960px CSS — 1920px covers even a 2×
retina panel. Re-encoded at 1920px wide, q82 webp:

  cta-bg.webp        335KB → 174KB  (-48%)
  lab-stage-art.webp 454KB → 276KB  (-39%)

~340KB saved with no visible quality loss (verified at 2× device scale —
the painterly murals stay crisp). Only the pixel dimensions dropped; the
quality factor is high. The homepage's gated `background-image` URLs bump
their `?v=` so the immutable edge cache serves the new files immediately.

* perf(landing): redirect locale from <head> so the wrong-locale first load aborts

A non-English visitor hitting the English root ran the locale
auto-redirect from a <script> late in <body>, so the browser had already
streamed most of the document (and kicked off its head resources) before
bouncing to /zh/ etc. — a wasted near-full first load.

Move the auto-redirect decision to the top of <head> (first thing after
the viewport/theme-color meta) so it fires as the document starts
streaming and aborts the rest of the wrong-locale load. The switcher UI
wiring, which needs the DOM, now defers itself to DOMContentLoaded, so it
works whether the script runs in <head> (homepage) or late in <body>
(other layouts). All existing guards are untouched — canonical-only pages,
autoredirect-off pages, and already-localized roots still no-op, so
English and crawler traffic pays only a tiny inline read.

Verified: root / still redirects to /zh/ for a zh browser with no loop,
and all 11 language-switcher links bind correctly post-DOMContentLoaded.
2026-07-01 06:49:03 +00:00
b5adcc2d76 [codex] Add AMR sign-in to landing header (#4934)
* feat(landing): add AMR sign-in header

* feat(landing): center sign-in popup, scrim the page, return home after login

Improve the AMR sign-in popup flow on the landing header:
- Center the vela login popup over the current window (multi-monitor aware)
  instead of letting the browser place it arbitrarily.
- Dim the page with a focus scrim while the popup is open so it reads as a
  modal step; remove it on success, cancel, or timeout.
- After a successful login, close the popup and return the main window to the
  localized Open Design homepage (in place when already there).
- Fall back to a same-tab navigation when the popup is blocked.

Applied to both the sub-page enhancer (header-enhancer.astro) and the
homepage's inlined copy (index.astro).

* fix(landing): normalize AMR home redirect

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
2026-07-01 06:35:07 +00:00
572b87cfc4 Classify opaque runtime failure details (#4966)
Co-authored-by: Siri-Ray <2667192167@qq.com>
2026-07-01 05:14:23 +00:00
CaprikaandGitHub da3704a331 Polish AMR settings card (#4984) 2026-07-01 04:43:08 +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
9923c13d9e feat(landing-page): add AI landing page generator + Figma-to-code tool pages (#4985)
Batch 2 of the /solutions/ai-<x>-generator/ tool-page family, built from
the same template as batch 1 (breadcrumb under the /solutions/ hub,
single-sourced dropdown labels, related-tools matrix):

- /solutions/ai-landing-page-generator/ targets the "ai landing page
  generator" intent — prompt to a real, responsive landing page, then
  shipped code.
- /solutions/figma-to-code/ targets "figma to code" with a Claude-native
  angle: pull frames through the Figma MCP so Claude Code / Codex read the
  design directly and generate component-based code, no locked-in export.

Both reuse the .solution-page layout, ship a warm-paper hero
illustration, join the Solution dropdown + /solutions hub Tools group,
cross-link the generator cluster, and are localized to all keep-11
locales (en/zh first-party, ja/ko/de/fr/ru/es/pt-br/it/tr
Agent-translated).

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-07-01 04:26:45 +00:00
d379650dc1 add Instagram, LinkedIn, and Xiaohongshu to the settings social links (#4977)
The settings popover already linked X, Threads, and YouTube; add the three
remaining official Open Design accounts (Instagram, LinkedIn, Xiaohongshu)
as follow rows, and add matching rotating "useful info" tips in the design
files panel so each account is surfaced there too.

New i18n keys are fully localized across all 19 locales, and the
settings_popover analytics `element` union gains follow_instagram /
follow_linkedin / follow_xiaohongshu.

Co-authored-by: Tuolalala <xinglige0205@gmail.com>
2026-07-01 03:59:27 +00:00
b2512e9a7e ci: block direct PRs into release branches except release automation (#4982)
Colleagues have been opening PRs straight into release/vX.Y.Z (e.g. into
release/v0.13.0), bypassing main + the backport flow. Add a guard workflow:
on a PR opened/reopened/edited with a release/** base, if the author is not a
release-automation bot (open-design-release-bot, github-actions), post a comment
explaining the backport flow (merge to main, add `backport release/vX.Y.Z`) and
close the PR.

Closing (not a failing check) is the only real gate here: release/* branches
have no required status checks and no merge queue, so a red check would not
block a merge.

Co-authored-by: lefarcen <ontf116@gmail.com>
2026-07-01 03:45:48 +00:00
Tom HuangandGitHub be701787d6 fix(web): clarify plugin remix actions (#4969) 2026-07-01 03:29:12 +00:00
2dfaae3d3b feat(landing-page): batch 6 long-form tutorials + keep-11 localization (#4976)
* feat(landing-page): upgrade 5 tutorials to long-form guides with distinct real screenshots (batch 6)

Batch 6, five angles:
- dylan-michael: Open Design for agencies (Apache-2.0 commercial safety + cost-managed model switching)
- ai-fire-academy: restyle without rebuilding (iterate visual identity on the same content)
- ai-fusion: the four content libraries (skills, systems, templates, and the auto-enforced craft layer)
- nyndra: a developer's under-the-hood look (deterministic loop + architecture + BYOK proxy)
- tony-xhepa: which coding agent to run it with (13+ supported, how to pick)

Each tutorial gets three distinct real in-app screenshots (no two share the same set).

* feat(landing-page): localize batch 6 long-form tutorials to the keep-11 locales

Agent-translated long-form bodies for the 5 batch-6 tutorials into the keep-11 non-English locales. Tag + image-src parity validated per locale. Per-article shards; index now 31 articles.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-07-01 03:05:25 +00:00
af562dee19 feat(landing-page): AI UI generator + design-to-code tool pages, nav/hub wiring, keep-11 localization (#4961)
* feat(landing-page): add AI wireframe generator tool page

First of the /solutions/ai-X-generator tool-page family (SEO action plan
P0-3; Pixelcut/Figma tool-SEO model adapted to OD). Targets the
'ai wireframe generator' cluster (480/KD38 + best ai wireframe generator
2026 590/KD8). Reuses the .solution-page layout + the real prototype-category
plugin grid; hero is a public-path od-site-illustration (prompt -> wireframe
-> shipped UI). New 'aiWireframeGenerator' SolutionPageKey with en + zh copy
(SolutionLocaleCopy is Partial, so other locales fall back to English).
Honest positioning: OD takes the wireframe to shipped code you own, not a
throwaway image. astro check 0 errors.

Nav dropdown entry deferred (positional label-tuple coupling) — page is
reachable via sitemap + internal/related-tools links for now.

* fix(landing-page): replace misleading plugin grid with text feature cards on wireframe tool page

* feat(landing-page): localize related-tools matrix on wireframe tool page

Move the cross-link matrix from a hardcoded English list into
solution-pages-i18n (en + zh, optional related/relatedTitle fields) so
the labels localize like the rest of the page and sibling generator
pages can extend the list as they ship.

* feat(landing-page): add AI UI generator + design-to-code tool pages

Extend the /solutions/ai-<x>-generator/ tool-page family with two more
SEO tool pages built from the wireframe-generator template:

- /solutions/ai-ui-generator/ targets the "ai ui generator" intent —
  prompt to a real, component-based UI, then shipped code.
- /solutions/design-to-code/ targets the "design to code" / "ai design
  to code" intent, keyword-mapped against the /blog/design-to-code-tools
  listicle (blog owns "best ... tools", the tool page owns the tool
  intent).

Each reuses the .solution-page layout, ships en + zh first-party copy
(other locales fall back to English), a warm-paper hero illustration, and
a localized related-tools matrix that cross-links the three generators so
they form an interlinked cluster. Follow-up: surface the Tools group in
the /solutions hub and the header dropdown (all-locale CommonCopy keys).

* feat(landing-page): surface AI generator tool pages in solutions nav + hub

Add a Tools group to the Solution dropdown and the /solutions hub so the
three generator pages (AI wireframe / AI UI / design-to-code) have real
inbound links from sitewide navigation, not just sitemap + cross-links.

- HeaderProductMenuCopy gains a tools label + a toolItems tuple,
  translated across all 18 landing locales (fixed-length tuple keeps
  missing translations visible at typecheck time).
- Header dropdown renders Tools as the first group, ahead of Use cases
  and Roles.
- The /solutions hub renders a matching Tools section, sourcing its
  heading from the product-menu copy and feeding the cards into the
  CollectionPage ItemList JSON-LD.

* feat(landing-page): localize the three tool pages to the keep-11 locales

The AI wireframe / AI UI / design-to-code tool pages shipped with en + zh
body copy and fell back to English for the other rendered locales, which
read as half-translated next to the fully-localized site chrome. Add
full, Agent-translated body copy for the remaining keep-11 locales (ja,
ko, de, fr, ru, es, pt-br, it, tr), matching each locale's existing
solution-page terminology and tone. hrefs/thumbs and proper nouns are
preserved verbatim.

* fix(landing-page): single-source tool dropdown labels from solution-page copy

The Solution dropdown read tool names from HeaderProductMenuCopy.toolItems
while the hub cards read them from the solution-page breadcrumb, and the
two had already drifted in Japanese (per review). Drop toolItems entirely
and derive the dropdown labels from getSolutionPageCopy(locale, key).breadcrumb
so the nav and the hub share one translation source and cannot diverge.

* fix(landing-page): breadcrumb the tool pages under the /solutions/ hub

This PR wires /solutions/ into the header dropdown and hub cards as a real
parent for the three generator pages, but the leaf breadcrumbs and their
BreadcrumbList schema still flattened to Open Design -> <page>. Insert a
localized /solutions/ middle item in both the rendered <nav> and the
JSON-LD on all three tool pages so the trail matches the navigable
hierarchy. Label comes from header.nav.solution (already localized).

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-07-01 02:17:57 +00:00
AmyandGitHub 56c410e9ef [codex] strengthen daemon diagnostics coverage (#4948)
* test: expand automation coverage gaps

* test: cover additional automation gaps

* test: strengthen daemon diagnostics coverage

* fix(e2e): align media provider project modal helper
2026-06-30 16:25:17 +00:00
rebel-nexu-zero[bot]GitHubMasonrebel-nexu-zero[bot] <rebel-nexu-zero[bot]@users.noreply.github.com>
7d74775340 fix(web): restore Settings updater status controls (#4946)
* fix: improve settings update checks

* fix: remove update state preview

* fix(web): enable settings updater downloads

* fix(web): install downloaded payload updates

* fix(web): retry updater quit from settings

---------

Co-authored-by: Mason <jinmeihong0201@gmail.com>
Co-authored-by: rebel-nexu-zero[bot] <rebel-nexu-zero[bot]@users.noreply.github.com>
2026-06-30 15:21:57 +00:00
faa0ed23b7 feat(landing-page): batch 5 long-form tutorials + keep-11 localization (#4967)
* feat(landing-page): upgrade 5 tutorials to long-form guides with distinct real screenshots (batch 5)

Batch 5, five distinct non-cannibalizing angles:
- ai-teaches-better: the 6-layer anti-slop quality engine
- compile-future: turn a reference image (Dribbble shot) into a real page, free via Gemini
- justyn: same-prompt head-to-head vs Claude Design + multi-variation
- eli-rigobeli: make slide decks from a video/article, on free credits (title rewritten from Portuguese)
- better-stack: why even a budget model designs well (design systems + skills carry it)

Each tutorial gets three distinct, angle-relevant real in-app screenshots (no two share the same set).

* feat(landing-page): localize batch 5 long-form tutorials to the keep-11 locales

Agent-translated long-form bodies for the 5 batch-5 tutorials into the keep-11 non-English locales (zh, ja, ko, de, fr, ru, es, pt-br, it, tr). Tag + image-src parity validated per locale. Per-article shards; index now 26 articles.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 14:28:59 +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
lefarcenandGitHub 6c424f4ad5 fix(release): populate github.commit in prerelease metadata so the changelog has a baseline (#4960)
The Feishu release card (notify-release-feishu.yml) builds its changelog as
`git log <previous>..<current>`, reading <previous> from the published
prerelease/latest/metadata.json `.github.commit`. That field is written by
githubInfo(), which reads the RELEASE_COMMIT env. release-beta sets
RELEASE_COMMIT on every build + publish job; release-prerelease set it on none,
so every prerelease published an empty github.commit. Each prerelease then
found no baseline and the card always rendered "首个 Prerelease 包,无上个版本可
对比" — the changelog was permanently empty, not just for a fresh release line.

Add RELEASE_COMMIT to the four prerelease build jobs and the publish job,
mirroring release-beta. Both are required: publish-metadata rejects a
per-platform manifest whose github.commit disagrees with the metadata commit,
so the build jobs (which write per-platform manifests) and the publish job
(which writes the final metadata.json) must stamp the same built commit.

Red spec in packaged-smoke-workflow.test.ts asserts each prerelease build +
publish job carries RELEASE_COMMIT (red on main, green here).
2026-06-30 13:08:39 +00:00
lefarcenandGitHub 41c3b8fe0c fix(daemon): normalize additive cache usage so cache-hit ratio never exceeds 1 (#4903)
The first-call and aggregate cache-hit ratios assumed every `openai` usage
source folds the cache-read subset into `input_tokens` (cached ⊆ input). That
holds for OpenAI chat-completions and codex's rollout, but the Responses-API /
ACP usage the AMR/vela and pi streams emit reports `input_tokens` as the
UNCACHED remainder with cache-read tokens reported separately on top, so
cache_read > input. Dividing cache_read by that too-small denominator pushed
cache_hit_ratio and first_call_cache_hit_ratio far above 1.0 (~78% of AMR and
~57% of pi follow-up run_finished events) and collapsed uncached_input_tokens
to 0.

Resolve effective-input through one shared helper that detects the additive
shape from a hard arithmetic invariant — a cache-read subset can never exceed
the total it is a subset of, so cache_read > input proves the payload is
additive — and folds cache-read/creation into the denominator (anthropic
semantics). Every cache_read <= input payload stays byte-identical; only the
previously-corrupt additive case is repaired.

Red spec asserts the AMR-shaped additive event yields ratio <= 1 (was 4.7) and
uncached == input (was 0), plus an inclusive-OpenAI guard so codex/openai do
not regress.
2026-06-30 12:12:52 +00:00
6083517588 feat(landing-page): batch 4 long-form tutorials + keep-11 localization (#4941)
* feat(landing-page): upgrade 5 tutorials to long-form guides with distinct real screenshots (batch 4)

Batch 4 converts five thin tutorial entries into original long-form guides,
each from a distinct, non-cannibalizing angle:

- iishny: an honest first look (bugs, fixes, wiring any model via OpenRouter)
- 01coder: from prompt to live URL — edit, inspect, one-click deploy (Vercel/Cloudflare)
- panda: five end-to-end workflows that chain skills into real pipelines
- chase: Open Design's open-source lineage and where it fits in the OSS toolbox
- where-do-i-click: the absolute-beginner guide — install on your PC, build your first page

Each tutorial gets three distinct, angle-relevant real in-app screenshots (no
two tutorials share the same set), reusing the captured Open Design app shots.

* feat(landing-page): localize batch 4 long-form tutorials to the keep-11 locales

Agent-translated long-form bodies for the 5 batch-4 tutorials into the keep-11
non-English locales (zh, ja, ko, de, fr, ru, es, pt-br, it, tr). Each preserves
the English HTML structure exactly (validate-i18n.py: tag + image-src parity).
One per-article shard each under app/_data/tutorials-longform/; index now 21 articles.

* fix(landing-page): strip trailing whitespace in where-do-i-click tutorial

* fix(landing-page): make localized intros language-neutral (drop 'rewritten in English')

For the two non-English-source tutorials (first-look-community, 01coder), the
localized long-form intros translated the English-source clause 'rewritten in
English', so non-English readers saw a page in their language claiming it was
rewritten in English. Replace the localized intro paragraph with a
language-neutral phrasing in each of the keep-11 non-English locales; the English
Markdown source is unchanged. Addresses Looper's non-blocking review note on #4941.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 12:09:33 +00:00
2d194b24a6 feat(landing-page): localized /pricing/ page synced with the cloud subscription modal (#4933)
* feat(landing-page): add localized /pricing/ page synced with the cloud subscription modal

Adds a Pricing entry to the top nav and a new /pricing/ page that mirrors the
Open Design Cloud (vela) subscription modal: three-tier plan cards (Plus/Pro/Max)
with the plan wordmark logos, monthly/yearly toggle, first-month / yearly-discount
pricing, model-credit and design-task metrics, the customer story, the FAQ, and the
Team/enterprise banner.

- Plan numbers come from a baked snapshot and are reconciled at runtime from the
  cloud's published plans.json, so a price change in the cloud reflects here with
  no landing-page rebuild.
- All visible copy is localized for en/zh/zh-tw/ja/ko/de/fr/ru/es/pt-br (mirrored
  from the cloud), with English fallback for other locales; the nav label is
  translated across all landing locales.
- Subscribe CTAs deep-link into the cloud console with the selected tier+interval
  and checkout=auto, so checkout starts in the cloud (auth-gated) and returns to
  the console on success.

* fix(landing-page): address pricing review feedback

---------

Co-authored-by: NJUHua <113895241+NJUHua@users.noreply.github.com>
2026-06-30 11:40:24 +00:00
e75cb416fc [codex] Add BYOK provider presets (#4902)
* Add BYOK provider presets

* Fix BYOK preset picker accessibility names

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

* Hide unsupported Bedrock BYOK preset

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

* Restore BYOK preset test coverage

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

* Restore BYOK protocol fallback coverage

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

* Hide Bedrock from BYOK protocol tabs

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

* Downgrade unsupported Bedrock chat configs

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

* Clear Bedrock secrets during config downgrade

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

* Scrub nested Bedrock config on downgrade

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

* Persist Bedrock config downgrade migration

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

* Disable MiMo model discovery fetch

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

* Tighten Bedrock runtime URL detection

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

* Scope BYOK key drafts to provider presets

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

* Preserve BYOK provider form drafts

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

* Filter BYOK media models from chat discovery

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

* Fix BYOK provider draft persistence

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

* Fix BYOK account model load status

* Fix BYOK provider status coverage

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-06-30 11:22:05 +00:00
365553fc5d [codex] Fix deck keyboard double-step navigation (#4897)
* fix deck keyboard double navigation

* fix deck slide handler detection

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

* Defer deck bridge slide fallback

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

* Fix self-handling deck navigation fixture

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

* Keep deck bridge fallback synchronous

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

* Preserve synchronous deck bridge fallback

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

* fix deck bridge constant slide handlers

* fix deck bridge stopped-handler state sync

* Fix focused deck keyboard double navigation

---------

Co-authored-by: Siri-Ray <2667192167@qq.com>
Co-authored-by: Looper <looper@noreply.github.com>
2026-06-30 11:21:23 +00:00
3a8461f25b Fix onboarding language menu placement (#4939)
Co-authored-by: Siri-Ray <2667192167@qq.com>
2026-06-30 09:08:05 +00:00
bf14f80d70 feat(landing-page): how to use Claude Code for frontend design (how-to, i18n) (#4938)
* feat(landing-page): add 'how to use Claude Code for frontend design' how-to with full i18n

SEO content engine (action plan P0-1 follow-on). Targets the high-volume
on-brand term 'how to use claude code for frontend design' (~1900/KD20). A
genuine how-to: install the official frontend-design plugin, prompt with
aesthetic direction not pixels, guide design dimensions, iterate, then move
from a one-off screen to an ownable design system (where OD fits, disclosed).

Cites the official anthropics/claude-code frontend-design plugin (external
authority link). Full 10-locale i18n (zh/ja/ko/de/fr/ru/es/pt-br/it/tr),
structurally audited (h3/internal+external link/href parity). astro check
0 errors. Warm editorial cover.

* fix(landing-page): fully localize Turkish install step (drop leaked English 'Type')

nettee review: the tr bodyHtml rendered 'Type <code>/plugin</code> yazın.'
mixing English and Turkish. Removed the English 'Type' so it reads natively
as '<code>/plugin</code> yazın.'

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 09:05:05 +00:00
3fb3e3ca4a ci(release): finalize-release — bump main + drop backport label after a stable ships (#4936)
* ci(release): finalize-release — bump main + drop backport label after a stable ships

* ci(release): arm merge queue + request core-maintainer review on the bump PR

main enforces require_code_owner_review and the bump touches CODEOWNERS-owned
release manifests, so a bot approval can't merge it hands-free (unlike
backport-automerge / bake-plugin-previews-automerge, whose targets/diffs avoid
code-owner review). Open the PR, arm the squash merge queue (gh pr merge --auto,
proven on main by bake-plugin-previews-automerge), and request the
@nexu-io/core-maintainers review that the code-owner rule needs.

* ci(release): trigger finalize via workflow_run, not release:published

release-stable.yml promotes its own draft to published with gh release edit
using GITHUB_TOKEN, and a release event minted by GITHUB_TOKEN does not trigger
other workflows — so a release:published trigger would never fire. React to
release-stable completing instead (the backport-automerge / bake pattern), and
gate on the open-design-vX.Y.Z release actually being published (draft=false)
so dry-runs (metadata/prepublish) correctly no-op.

* ci(release): resolve version from latest published release, not head_branch

PerishCode review (blocking): release-stable supports building one ref while
dispatched from another via its `ref` input, so workflow_run.head_branch can be
the dispatch ref, not the built release branch — parsing it would miss-fire or
read the wrong version. Read the version from the latest published release
instead (release-stable marks it --latest), which is branch-independent. Drop
the head_branch job-if guard; the draft/prerelease/X.Y.Z guards + bump
idempotency keep dry-runs a clean no-op.

* test(release): pin finalize-release workflow topology

PerishCode review (blocking): .github/AGENTS.md asks cross-workflow behavior
changes to update the topology tests, not rely on YAML review alone. Add a
focused [P2] test in packaged-smoke-workflow.test.ts (alongside the backport /
bake automerge coverage) that pins finalize-release's trusted-consumer contract:
workflows: [release-stable] + success/dispatch gating, App-token use, version
resolved via gh release view (latest/tag) with NO workflow_run.head_branch
dependency, draft/prerelease/X.Y.Z + skip handling, forward-only synchronized
bump, core-maintainer review request, and SHA-pinned merge-queue arming.

---------

Co-authored-by: lefarcen <ontf116@gmail.com>
2026-06-30 09:04:49 +00:00
1d83115fd4 chore(plugin-previews): refresh baked preview manifest (#4905)
Co-authored-by: open-design-bot <bot@open-design.ai>
2026-06-30 08:31:57 +00:00
faa990c253 feat(landing-page): AI design agents + AI prototyping tools listicles (i18n) (#4935)
* feat(landing-page): add AI design agents + AI prototyping tools listicles with full i18n

Listicle engine batch 4 (SEO action plan P0-1/B1), reaching the 8-piece
target low end:
- ai-design-agents — targets the 'ai design agents' cluster (110/KD18); OD's
  own category. Honest three-way split (creative production / task agents /
  agent-native design-to-code), scoping out 'design agencies' and image/video
  gen noise; OD leads the agent-native category.
- ai-prototyping-tools — targets 'best ai prototyping tools' (action-plan
  target topic); grouped by throwaway-vs-becomes-the-product, OD as the
  agent-native prototype-to-shipped pipeline.

Each: scorecard table, FAQ, internal-link hub, warm editorial cover, full
10-locale i18n (zh/ja/ko/de/fr/ru/es/pt-br/it/tr) structurally audited
(h3/link/href parity). astro check 0 errors. OD positioned as the agent-native
/ ownership option, never a cheap clone.

* fix(landing-page): correct malformed </em> tag in ja prototyping post

nettee review: the ja bodyHtml had a closing tag with a trailing space
(</em >), which ships as raw invalid HTML since bodyHtml is injected
directly. Normalized to </em>.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 08:00:37 +00:00
bb3d826c69 Refine Open Design CLI picker controls (#4928)
Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com>
2026-06-30 07:37:21 +00:00
231cf67fa4 feat(landing-page): batch 3 long-form tutorials with distinct screenshots + keep-11 localization (#4924)
* feat(landing-page): upgrade 5 tutorials to long-form guides with distinct real screenshots (batch 3)

Batch 3 converts five thin tutorial entries into original long-form guides,
each from a distinct, non-cannibalizing angle:

- design-engine (Codedigipt): pick/swap the model behind it
- self-hosted (AI Stack Engineer): architecture, self-host, BYOK layers
- aicodeking: team workflow — versioned skills + brand DESIGN.md + anti-slop
- brendan (O'Connell): design from your existing brand (agent scrapes your site)
- roy-shavit: design without burning tokens (title rewritten from Hebrew)

Screenshots: instead of reusing one shared trio across every tutorial (the
prior batches' pattern), each tutorial gets three distinct, angle-relevant real
in-app screenshots captured from the running Open Design app (workspace, slide
deck, motion gallery, plugins hub, plugin library, a generated prototype), so
adjacent tutorials no longer look identical.

* feat(landing-page): localize batch 3 long-form tutorials to the keep-11 locales

Agent-translated long-form bodies (title + summary + bodyHtml) for the 5
batch-3 tutorials into the keep-11 non-English locales (zh, ja, ko, de, fr, ru,
es, pt-br, it, tr), including the per-tutorial distinct image captions. Each
preserves the English HTML structure exactly (validate-i18n.py: per-locale tag
+ image-src parity). One per-article shard each under app/_data/tutorials-longform/,
merged by the index (now 16 articles).

* fix(landing-page): restore blog posts dropped by stale worktree base

The batch-3 branch was cut from an older worktree state that predated four
blog posts (best-ai-design-tools, bolt-new-alternatives, design-to-code-tools,
lovable-alternatives) and a blog index update now on main. Those files were
unintentionally carried as deletions. Restore them verbatim from main so this
PR only changes tutorials + their i18n.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 07:27:00 +00:00
f63916961d Use JPG social image for meetup blog card (#4920)
Co-authored-by: tuolaji <tuola@tuolajideMacBook-Air.local>
2026-06-30 07:05:10 +00:00
a25f246551 feat(landing-page): add figma + v0 alternatives listicles with full i18n (#4925)
Listicle engine batch 3 (SEO action plan P0-1/B1):
- figma-alternatives — targets 'figma alternatives' cluster (1000/KD21); honest
  two-camp map (open-source canvas / native / AI-native), holds the red line —
  explicitly does NOT claim to replace Figma's multiplayer canvas; keyword-mapped
  vs /alternatives/figma/ + existing figma-alternative-open-design blog
- v0-alternatives — targets 'v0 alternative' cluster (140/KD12); completes the
  bolt/lovable/v0 alternatives trio, grouped by why you leave (pricing/scope/own)

Each: scorecard table, FAQ, internal-link hub, warm editorial cover, full
10-locale i18n (zh/ja/ko/de/fr/ru/es/pt-br/it/tr) structurally audited
(h3/link/href parity). astro check 0 errors. OD positioned as agent-native /
ownership entry, never a cheap clone.

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 06:37:25 +00:00
b0b1bd2cdd feat(landing-page): content listicle engine — first 4 SEO listicles (i18n) (#4921)
* feat(landing-page): add best AI design tools 2026 listicle

First post of the content listicle engine (SEO action plan P0-1/B1). Targets
the commercial 'best ai design tools 2026' cluster (590 vol / KD22) plus
gettable secondaries (ui/ux, product, ux design designer queries, KD13-37),
deliberately scoped to digital UI/UX/web design.

Differentiation vs the ranking-farm competitors: names the agent-native /
open category every other roundup omits (Open Design + Onlook), adds a
ship/ownership decision lens and scorecard table, and an honest 'when not to'
section. Open Design leads the agent-native category honestly without being
demoted to a cheap alternative; the post is an internal-link hub into
/alternatives/* and /solutions/*.

English-first per the content rule for new listicle pages; localization
follows once it proves out. Warm editorial cover matches the recent blog set.

* feat(landing-page): localize best AI design tools listicle to 10 locales

Adds zh/ja/ko/de/fr/ru/es/pt-br/it/tr i18n (title, summary, category,
bodyHtml) matching the current canonical keep-set used by the latest
posts. Each locale verified: 9 H2 + 6 H3 + table + 17 list items + 13
internal links with identical hrefs; astro check 0 errors.

* feat(landing-page): add 3 more listicle posts with full i18n

Listicle engine batch 2 (SEO action plan P0-1/B1):
- bolt-new-alternatives — targets 'bolt.new alternative' cluster (1600/KD8)
- design-to-code-tools — targets 'design to code tools' cluster (260/KD22), most on-brand
- lovable-alternatives — targets 'lovable alternatives' cluster (480/KD17)

Each: honest roundup grouped by intent, OD as the agent-native/ownership
entry (never demoted to a cheap clone), scorecard table, FAQ, internal-link
hub into /alternatives + /solutions, warm editorial cover, and full 10-locale
i18n (zh/ja/ko/de/fr/ru/es/pt-br/it/tr) — structurally audited (h3/link/href
parity per locale). astro check 0 errors. English-first keyword mapping keeps
the plural-roundup listicles distinct from the 1:1 /alternatives/ pages.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 06:00:14 +00:00
3a0ff032f4 feat(landing-page): batch 2 long-form tutorials + localize batch 1+2 to the keep-11 locales (#4915)
* feat(landing-page): upgrade 5 tutorials to long-form guides + real app screenshots (batch 2)

Batch 2 of converting thin thumbnail+one-line tutorial entries into full,
indexable, original long-form guides, each from a distinct angle so they
don't cannibalize:

- vs-figma (Anton Larichev): where an agent-native workspace fits next to Figma
- vibe-coders (Sean Kochel): the vibe-coding build loop across 3 surfaces
- skills-systems (Popular AI Tools): plugin library, discovery form, anti-slop gate
- migrate-jack (Jack Roberts): migrating off Claude Design's limits, model-switching
- feature-tour (硅基麻辣拌): full capability sweep — PPT, image, prototype, motion, video, pet

Content only: overwrites 5 existing tutorial .md bodies (frontmatter preserved,
summaries sharpened, Russian/Chinese titles rewritten to English) and adds the
shared real-app screenshot set per slug. Reuses the long-form .tut-body render
already on main. English-first; non-English locales keep their generic fallback.

* feat(landing-page): localize batch 1 + batch 2 long-form tutorials to the keep-11 locales

Adds real Agent-translated long-form bodies (title + summary + bodyHtml) for
all 10 batch-1 and batch-2 tutorials into the keep-11 non-English locales
(zh, ja, ko, de, fr, ru, es, pt-br, it, tr). Before this, those pages fell back
to the generic English placeholder for non-English visitors; now each renders a
fully localized article with hreflang already emitted by the page.

Each translation preserves the English HTML structure exactly (validated by the
od-video-tutorial validate-i18n.py: tag counts + image src parity per locale)
and keeps brand / CLI / command names and code blocks verbatim.

Because 11 articles x 10 locales would push the single i18n store past the 1 MiB
CI blob guard, the store is split into per-article shards under
app/_data/tutorials-longform/<slug>.ts, merged by the tutorials-longform-i18n.ts
index (keeps getLocalizedTutorial's signature, so the page import is unchanged).
The pilot (open-design-in-20-minutes) is relocated into a shard unchanged.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-30 03:10:45 +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
54de349c47 fix: replace expired Discord invite (#4849)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local>
2026-06-29 15:00:45 +00:00
Ethan GuoandGitHub 6755e938a4 test(platform,sidecar-proto): cover proc-tree, stamp readers, ipc-path validation (#2406)
* test(sidecar-proto): cover normalizeIpcPath validation and Windows pipe detection

* test(platform): cover readFlagValue and stamp readers

* test(platform): cover collectProcessTreePids BFS traversal
2026-06-29 15:00:42 +00:00
f80ad9e2dc fix(plugins): add bundled Perplexity AI design-system plugin manifest (#4828) (#4833)
The Perplexity AI system ships a card on /plugins/systems/ from
design-systems/perplexity/, but had no matching bundled-plugin manifest
under plugins/_official/design-systems/perplexity/. As a result
detailHrefForSystemSlug() found no plugin and the card fell back to the
/plugins/systems/ index instead of opening a dedicated detail page.

Add the bundled plugin for perplexity:
- open-design.json: generated via the migrate-to-plugins design-system
  wrapper, then brought to parity with sibling systems (specVersion,
  full title_i18n/description_i18n, localized useCase query). Structure
  is byte-identical in shape to the other design-system manifests.
- DESIGN.md: embedded copy of design-systems/perplexity/DESIGN.md.
- open-design-marketplace.json: register the bundled plugin in the
  official registry seed (sorted insert + bundledPreinstallCount 413->414),
  matching how prior plugin-add commits regenerate the seed.

The landing page now builds a real /plugins/design-system-perplexity/
detail page and the systems-index card links to it.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 14:55:29 +00:00
lefarcenandGitHub 0fecb15baa chore(release): bump main to 0.12.1 ahead of stable 0.12.0 (#4900)
Stable shipped 0.12.0 (tag open-design-v0.12.0, 2026-06-26) but main's
packaged base version stayed at 0.11.1. release-beta's metadata guard
requires the packaged base version to be strictly greater than the latest
stable, so the daily beta build (notify-daily-feishu, 01:00 UTC) has failed
every morning since 2026-06-27 with:

  packaged base version 0.11.1 must be strictly greater than latest stable 0.12.0

Bump all 18 workspace package.json versions in lockstep to 0.12.1 so main
leads stable again. Verified the real prepare-beta guard now resolves
0.12.1-beta.1 (EXIT 0) against the live stable/beta feeds.
2026-06-29 14:47:46 +00:00
ec3a54f374 fix(daemon): detect codex installed via the standalone Codex.app bundle (#4889)
* fix(daemon): detect codex installed via the standalone Codex.app bundle

The official OpenAI Codex desktop app (bundle id com.openai.codex) ships
the `codex` CLI inside Codex.app/Contents/Resources/codex and does not add
it to PATH unless the user runs the app's "Install command line tool"
action. Agent detection only searched PATH plus the user-toolchain dirs
(npm/nvm/fnm/mise/Homebrew/...), so an app-only install surfaced as
"not installed" in the agent picker even though a healthy native binary
exists on disk.

Add a codex-specific, last-resort resolution fallback that probes the
well-known macOS bundle locations (/Applications and ~/Applications),
ranked below PATH so an explicit CLI install always wins, and scoped to
the OD_AGENT_HOME override so sandboxed detection stays deterministic.

Also cap the codex node-wrapper sniff to the first 64KB via a bounded fd
read: the selected codex path can now be the ~190MB native Codex.app
binary, which readFileSync would otherwise slurp whole just to check a
shebang.

* test(daemon): cover the no-override /Applications codex bundle branch

Export codexAppBundleCandidates and assert that, with no OD_AGENT_HOME
override, the system /Applications path is probed first and a distinct
~/Applications candidate follows. The existing fixtures all set
OD_AGENT_HOME, so the common real-world /Applications install path was
untested and a path-typo or ordering regression could silently miss it.

* test(daemon): isolate codex bundle tests from ambient sandbox env

resolveDetectionHome() consults OD_SANDBOX_MODE / OD_DATA_DIR before
OD_AGENT_HOME, so the new Codex.app fixtures now snapshot and clear those
too. Without this, a dev/CI run with sandbox mode already enabled could
resolve the sandbox agent home instead of the fixture home (or throw on
OD_DATA_DIR) before reaching the branch under test, making the coverage
non-deterministic.

---------

Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
2026-06-29 14:44:27 +00:00
110774e891 fix(ci): merge-queue needs-validation gate skips non-PR refs, not eject clean PRs (#4898)
* fix(ci): merge-queue needs-validation gate skips non-PR refs, not eject clean PRs

The merge_group needs-validation gate enumerates queued PRs from three sources;
source 2 scrapes a trailing `(#N)` from each commit subject. That `(#N)` can be
an ISSUE reference an author put in the PR title, not a queued PR — e.g. #4833,
titled "fix(plugins): ... (#4828)", where 4828 is the fixed issue. The gate then
ran `gh pr view 4828`, which fails with "Could not resolve to a PullRequest";
as a plain assignment under `set -e` that ejected a clean, label-free, approved
PR from the merge queue every time it entered — permanently unmergeable.

Distinguish a definitive "not a PR" (skip — the number was a spurious reference)
from a transient API failure (still fail closed → block), so real needs-validation
PRs are still enforced while issue references no longer block clean merges.

* fix(ci): resolve merge-group needs-validation per commit, not a flat union

Addresses review: skipping a non-PR `(#N)` unconditionally could, in a batched
merge group, drop the only candidate that would have checked a non-tip PR — so a
non-tip PR still carrying `needs-validation` could slip through (#4736 hazard).

Resolve each merge-group commit to at least one real PR from its own signals
(subject `(#N)`, commits/<sha>/pulls, and — for the tip — the queue ref). A `(#N)`
that does not resolve to a PR (e.g. an issue reference like #4833's "(#4828)") is
ignored ONLY when its commit is still covered by another candidate that resolves
to a real PR; a commit that resolves to no PR fails closed. Real needs-validation
PRs are still blocked; clean PRs whose title references an issue are no longer
ejected.

Verified with a mocked gh harness: (A) tip "(#4828) (#4833)" → ignores 4828,
checks 4833, clears; (B) batched non-tip whose only number is an issue ref + carries
needs-validation → fails closed; (C) tip with needs-validation → blocks.

---------

Co-authored-by: lefarcen <ontf116@gmail.com>
2026-06-29 13:36:50 +00:00
lefarcenandGitHub 211ec5df5a ci: make the Nix hash check advisory on PRs, enforce it only at merge time (#4896)
* ci: make the Nix hash check advisory on PRs, enforce it only at merge time

A stale nix/pnpm-deps.nix hash is the routine, self-healing consequence of any
pnpm-lock.yaml change: the nix_validation job already regenerates the hash and
hands it to autofix.atom.yml, which pushes the refresh back to the PR branch.

Failing the job on pull_request turned that transient, auto-fixed drift into a
red check that flipped the PR to BLOCKED and read as a real CI failure to the
review bot — the same deadlock the needs-validation gate already documents. The
contributor then waited on the autofix round-trip every time the lockfile moved.

Now nix_validation stays green on pull_request (the autofix still self-heals the
hash in the background) and the hash is enforced as a hard gate only at merge
time: merge_group and manual full runs fail closed, so a genuinely broken Nix
build can never reach main. The Validate workspace gate ignores a red Nix job on
PRs (both the blanket failure scan and the required-jobs check) and keeps
requiring it everywhere else.

* test(e2e): cover the Nix-advisory-on-PR Validate workspace gate

Extract the two jq programs the `validate` job runs (the blanket failure scan
and the required-jobs scan) straight out of ci.yml and feed representative
`needs` JSON through the real `jq`, so the cross-workflow gate behavior is
asserted rather than reviewed by eye:

- pull_request + failed nix_validation -> gate passes (advisory),
- merge_group / workflow_dispatch full + failed nix_validation -> gate fails
  closed,
- pull_request + another failed required job -> gate still fails (the PR
  exception is scoped to nix_validation only).

A future edit that makes Nix advisory on merge_group, or stops ignoring it on
PRs, now fails this test instead of slipping through YAML review.
2026-06-29 13:33:08 +00:00