mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
688544ff7d4e5135e674874935d731fc5213b49f
230
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
886f925cdf | Merge remote-tracking branch 'origin/main' into iodized-nephew | ||
|
|
d3ebed564c |
[codex] Update Open Design X account links (#4611)
* fix: update Open Design X account links * test(web): assert settings X link target Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
d19c53d274 |
Agent-driven brand extraction + two-loop memory overhaul (#4260)
* Implement brand management routes and CLI support - Added `brand-routes.ts` to handle HTTP endpoints for brand operations: listing, extracting, retrieving details, deleting, and serving logos. - Introduced `brands-cli-help.ts` for CLI commands related to brand management, including usage instructions for listing, creating, retrieving, and deleting brands. - Updated `cli.ts` to integrate brand commands into the existing CLI structure, allowing headless management of brands via the command line. - Created supporting files for brand metadata handling, including `design-md.ts` for rendering brand information in markdown format and `index.ts` for the brand engine API. - Implemented `prefetch.ts` to fetch and process brand material from specified URLs, ensuring a streamlined extraction process. - Enhanced server setup in `server.ts` to register brand routes and manage brand-related data effectively. This commit establishes a comprehensive framework for managing brands within the application, facilitating both HTTP and CLI interactions. * Enhance memory management and onboarding experience - Introduced canonical profile labels to ensure consistent handling of user input in profile forms, preventing duplicate entries. - Updated the `parseProfileBody` and `captureProfileFromForm` functions to utilize the new canonical label matching. - Added a memory callout section in the onboarding view to highlight the benefits of memory usage, including personalized responses and reduced setup questions. - Implemented new UI elements in the onboarding view to improve user engagement with memory features. - Expanded i18n support for new onboarding messages related to memory benefits across multiple languages. * Refactor onboarding flow and enhance design system integration - Updated the onboarding process to include a new brand extraction step, replacing the previous newsletter step. - Adjusted the tracking logic to reflect the new onboarding steps, ensuring accurate analytics for user progress. - Improved the UI for the onboarding view, including new input fields for email collection during the brand extraction phase. - Refined the EntryShell component to remove outdated comments and clarify the onboarding renderer's purpose. - Enhanced CSS styles for the onboarding steps to improve layout and user experience. - Updated internationalization strings across multiple languages to reflect changes in the onboarding flow and brand extraction messaging. * Add brand management features and enhance font handling - Introduced new modules for managing brand assets, including `chrome.ts` for headless Chrome operations and `fonts.ts` for self-hosting web fonts. - Implemented `prefetch.ts` to streamline the brand material extraction process, allowing for efficient harvesting of colors, fonts, and logos. - Enhanced the brand system with new schema definitions in `schema.ts` to support brand color and font management. - Developed the `engine` module to integrate brand building and rendering processes, including token derivation and artifact generation. - Improved the overall structure and organization of brand-related files for better maintainability and scalability. * Enhance brand extraction and project management features - Updated `brand-routes.ts` to include new dependencies for project management, allowing for the registration of brand-related projects. - Modified the `extractBrand` function to support project ID and system files, improving the brand extraction process. - Enhanced the CLI commands in `cli.ts` to handle project IDs during brand creation, enabling better tracking of brand projects. - Updated the server setup in `server.ts` to register new project-related routes. - Improved the UI components to display project information associated with brands, including buttons for opening projects in the `BrandDetailView` and `BrandsTab`. - Added new metadata fields in the contracts to support project tracking and management for brands. This commit establishes a more robust framework for managing brand projects, enhancing both backend and frontend functionalities. * Enhance onboarding profile management and memory persistence - Added new canonical profile labels for 'Organization size', 'Use cases', and 'Discovery source' to improve user input consistency. - Introduced `OnboardingProfileState` type to manage onboarding profile data more effectively. - Implemented functions to build and persist the onboarding profile body to memory, ensuring user selections are saved accurately. - Updated the `OnboardingView` component to handle profile persistence during navigation and submission steps. - Enhanced tests to verify that user selections are correctly persisted to the memory profile. This commit improves the onboarding experience by ensuring that user inputs are consistently captured and stored, enhancing overall user engagement with the application. * Reflow brand extraction into an agent-driven, live flow Replace the deterministic SSE prefetch/preview/system pipeline with an agent-driven extraction: POST /api/brands now reserves the brand and stands up a backing project with the target site open in an in-app browser tab plus a seeded prompt, so the agent measures, synthesizes brand.json incrementally, and the user can clear anti-bot walls by hand. New /preview and /finalize routes let the agent render the kit page live and register the resulting user:<id> design system, so extracted brand facts persist as a structured, reusable brand kit instead of a one-shot deterministic guess. Adds the brand-extract skill (SKILL.md + brand-kit.html template), kit-render engine, brand-extraction-engine tests, brand project covers in the Designs tab, onboarding extract handoff, and the matching od brand extract/preview/ finalize CLI subcommands and contract updates. Co-authored-by: Cursor <cursoragent@cursor.com> * Sediment finalized brands into structured memory Reflow a finalized brand into the memory store (brandToMemoryEntries + reflowBrandToMemory) so future chats can ground vague requests in the brand's palette, type, voice and rules. finalizeBrand now wires through the runtime dataDir and best-effort persists the brand, MemoryChangeEvent gains a 'brand' source, and the brand kit render hardens its inline JSON escaping. Adds brand.previewEmpty / brand.viewDetails across all locales. Co-authored-by: Cursor <cursoragent@cursor.com> * Implement logo fallback and imagery support in brand extraction - Introduced a deterministic logo fallback mechanism to ensure that brand extraction processes can retrieve and save site logos, even when the agent fails to do so. - Enhanced the `startBrandExtraction` and `finalizeBrand` functions to utilize the new logo fallback, allowing for better handling of logo assets. - Added support for imagery samples in brand validation, enabling the inclusion of representative images in the brand kit. - Updated the brand kit rendering to include self-hosted fonts and imagery, improving the overall presentation of brand assets. This commit strengthens the brand extraction workflow by ensuring that logos and imagery are reliably captured and displayed, enhancing the user experience in brand management. * Enhance memory management with rule proposal and verification features - Introduced new functionality for distilling annotations into rule proposals, allowing users to suggest rules based on in-canvas annotations through the `od memory rule suggest` command. - Implemented a verification system that programmatically enforces compliance with active rules during artifact generation, ensuring that all active rules are covered in the self-verify scorecard. - Added endpoints for managing verification outcomes, including listing, removing, and clearing verification records, enhancing the transparency of the verification process. - Updated the memory management system to support the retrieval of active rule entries, ensuring that only linked rules are considered during verification. - Enhanced tests for both rule proposal generation and verification processes to ensure reliability and correctness. This commit strengthens the memory management capabilities by integrating rule proposals and verification, improving the overall user experience in managing design rules and ensuring compliance. * Distill review annotations into memory and enforce self-verify scorecard Add distillAnnotationsToMemory to mine inline preview comments/highlights/ marks into durable feedback + rule memory via a dedicated distiller prompt, threaded through the existing extract pipeline with an 'annotation' change source. Tighten the self-verify prompt (daemon + contracts) to state the daemon programmatically checks the scorecard, so a missing or uncovered scorecard on an artifact turn is an enforcement failure. Cover the rule suggest and verification-history routes with tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Apply brand design system through web config on "Use in new chat" Thread onApplyDesignSystem from the entry shell into BrandsTab so the brand's registered design system is applied via the web config channel instead of a bare daemon PATCH that left the Home composer stale. Add a transient home-intent latch + event so the Brands tab can request the Prototype chip on the already-mounted HomeView, which consumes it once the plugin catalog loads. Co-authored-by: Cursor <cursoragent@cursor.com> * Wire annotation distillation into background memory extraction Add a background distill pass that mines inline review annotations (comments / highlights / drawn marks) from a turn into durable memory alongside the general LLM extraction, surface an `annotation` memory toast source in the web UI, and cover the flow with a unit test. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix brand design system not applying to composer on "Use in new chat" Selecting a brand's "Use in new chat" applies the brand's design system as the default and fires the Prototype chip intent in the same synchronous click handler. HomeView consumed that intent inside the event listener, so `pickChip` ran before React committed the config change and seeded the composer's design-system field from the stale (empty) default — the composer showed "No design system" instead of the brand until a reload. Split the intent handling: the listener now only bumps a tick, and a separate effect consumes the chip after the re-render lands, so the seeded design system reflects the freshly-applied brand. Add the previously-untracked home-intent latch test coverage. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(web): rework Brands into Brand Kit and add Home create entry Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): harvest real cover/hero images for the Images module The brand kit's Images gallery only populated when the extraction agent remembered to save imagery — so a forgetful or bot-blocked agent (and the pre-imagery "Open Design" brand) left it empty. Add a deterministic, server-side imagery fallback (imagery-fallback.ts), mirroring the logo fallback: it parses og:image/twitter:image, large <img> (highest-res srcset/<picture>), <link rel=preload as=image>, and CSS background-image hero blocks, fetches candidates with browser-shaped headers, decodes PNG/GIF/JPEG/WebP dimensions to keep only big representative images (dropping icons/sprites/logos/tracking pixels), dedupes by content hash, and saves up to 8 of the largest into imagery/ with labeled samples. finalizeBrand runs it as a timeout-bounded, failure-tolerant safety net (injectable so tests stay offline) when the agent captured too few samples, first adopting any on-disk images. The extraction prompt and brand-extract SKILL now explicitly direct the agent to harvest the site's large/cover/hero images, filtered by rendered size. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(qa): implement deck layout validation and safety checks Add a new QA module for validating the layout of generated brand decks to ensure robustness against clipping and truncation issues. The `analyseDeckLayout` function checks for critical layout invariants, including the presence of `.slide` sections, correct container types, and necessary runtime layers. Introduce `assertDeckLayoutSafe` to enforce these checks during brand system rebuilds, preventing the deployment of decks that fail validation. Additionally, create comprehensive tests to verify the functionality of the new layout validation features. * fix(brands): apply deck shrink-to-fit synchronously so slides never clip The no-clip runtime scheduled its fit pass through requestAnimationFrame, whose callbacks are throttled while the deck is offscreen or occluded. A slide could therefore stay unscaled — and clip its content — until first paint. Fit synchronously on resize/load/fonts-ready with a trailing setTimeout settle pass for late reflow, removing the rAF dependency. Verified at the previously-broken 1024x620 viewport: container-type:size, zero truncations, runtime auto-applies scale (Problem 0.71, ASK 0.87, Product 0.97, Competition 0.97) and frame clip count drops to 0. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(web): let New Brand modal embed scrollable brand reference picker Add a fillHeight mode to BrandReferencePicker so the heading, quick-pick row and controls stay pinned while only the gallery scrolls inside a bounded-height parent. Wire it into NewBrandModal with a stable, spacious dialog and refresh the related newBrand/brandPicker copy across all 18 locales. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): enhance brand extraction with deterministic seed harvesting Introduce a new `seed-fallback` module to provide a server-side deterministic palette and typography seed during brand extraction. This ensures that the brand kit's initial display includes a harvested logo, an approximate color palette, and font families, improving the user experience by reducing the all-skeleton appearance during the first paint. Update the `startBrandExtraction` function to utilize this new module, allowing for a more seamless and visually appealing brand extraction process. Additionally, enhance the `BrandReferencePicker` component to reflect loading states and errors during brand extraction, ensuring users receive immediate feedback on their actions. Update related tests to verify the idempotency of the `finalizeBrand` function, ensuring that re-finalizing a brand correctly reuses the existing design system without duplication. * feat(brand-extract): enhance BrandReferencePicker and localization updates Updated the BrandReferencePicker component to reflect loading states and errors during brand extraction, improving user feedback. Added a new localization key for the brand extraction process and updated existing translations in English, Simplified Chinese, and Traditional Chinese to enhance clarity and user experience. Additionally, introduced new styles for better interaction with brand assets in the brand kit template. * feat(brands): wire in-page lightbox/masonry/asset preview + refine seed Brand-kit preview improvements for the live extraction kit: - brand-kit.html: add in-page overlay system (sandboxed iframe has no top-nav) — clickable image lightbox with prev/next, a "view all" masonry modal, and a full-page asset preview modal that loads system/artifacts/<kind>.html in an iframe. Defer auto-reload while an overlay is open so it never yanks the modal out mid-interaction. - seed-fallback.ts: prefer vivid mid-luminance hues for the seeded accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.) from the typography seed so specimens never render glyph soup. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(brands): wire in-page lightbox/masonry/asset preview + refine seed Brand-kit preview improvements for the live extraction kit: - brand-kit.html: add in-page overlay system (sandboxed iframe has no top-nav) — clickable image lightbox with prev/next, a "view all" masonry modal, and a full-page asset preview modal that loads system/artifacts/<kind>.html in an iframe. Defer auto-reload while an overlay is open so it never yanks the modal out mid-interaction. - seed-fallback.ts: prefer vivid mid-luminance hues for the seeded accent/accent-secondary, and drop icon/symbol faces (Remix Icon etc.) from the typography seed so specimens never render glyph soup. Co-authored-by: Cursor <cursoragent@cursor.com> * i18n(web): add brandPicker.opening across remaining locales + picker test Completes the brand-reference picker i18n key that was committed only for en/zh-CN/zh-TW, so every locale satisfies the typed Dict, and lands the BrandReferencePicker extraction-feedback test left untracked by the concurrent worker. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(EntryShell): enhance AMR cloud card visibility post-detection Updated the EntryShell component to ensure the AMR cloud card remains visible after detection settles, even when the AMR runtime is unavailable. This change prevents the card from disappearing and allows it to degrade gracefully to fallback content and sign-in flow. Additionally, added tests to verify the new behavior, ensuring a better user experience during onboarding. * feat(brands): programmatic-first design system extraction + rename Make brand extraction two-phase so a usable design system is ready the moment the user enters a URL — the instant "aha" — instead of waiting on the AI agent: 1. PROGRAMMATIC-FIRST (synchronous): startBrandExtraction now harvests the site deterministically (logo, palette, typography, one-line description, cover imagery, source URL) via prefetchBrand, synthesizes a valid design system with brandFromMaterial (no LLM), and finalizes + registers it before returning. finalizeBrand is refactored into a reusable finalizeBrandCore shared by both the programmatic path and the agent path. 2. ASYNC AI ENRICHMENT: the seeded agent prompt is reframed to enrich the already-usable design system and re-finalize in place (same user:<id>), updating every artifact/template. Bounded + best-effort: a blocked/unreachable origin skips phase 1 and stays `extracting` for the agent to drive. Gated on userDesignSystemsRoot so the legacy agent-only path stays intact for tests. Also rename the user-facing "Brand Kit" surface to "Design System" across en + zh-CN strings, project names, and the enrichment prompt. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(brands): restore design-systems nav entry + reconcile BrandsTab on re-activation Address review feedback on PR #4260: 1. EntryNavRail dropped the only control that reached view==='design-systems' when Brands replaced it in the rail, leaving the still-rendered/routed design-system manager deep-link only (the entry-nav-design-systems e2e specs assert this). Restore a reachable rail entry (blocks icon, existing navDesignSystems key) alongside Brands. 2. BrandsTab only fetched once on mount, but EntryShell keeps sub-views mounted and toggles visibility, so a brand finishing extraction in its backing project never reconciled until a full reload. Refresh whenever the Brands view becomes active again, and poll while any brand is extracting (torn down once settled / when hidden). Red spec: tests/components/BrandsTab.refresh.test.tsx (fails pre-fix: fetchBrands called once, not twice). * fix(web): surface missing backing projects * fix(web): re-enable brand actions after use * fix(daemon): serve brand logos from data roots * fix(brands): reconcile failed extractions * fix(brands): non-blocking extraction start + lifecycle-accurate status (#4470) Acceptance fixes for the Brand Kit surface (PR #4260, even-ferry), addressing five reported issues: - Perf: `startBrandExtraction` no longer blocks the POST /api/brands response on the synchronous programmatic harvest+finalize. It now waits only a short budget (~1.2s) so fast origins still land on a ready, applyable design system (the instant "aha"), while slow/blocked origins return immediately on the "Extracting…" skeleton and finalize in the background. Measured: example.com POST dropped from a ~19s block to ~1.2s, then finalized to `ready` in the background. - Brand Kit stays stuck on "Extracting…" after a manual stop: the backing run's canceled/failed status now reconciles the brand to `failed` with a reason (this extends the existing reconcile; adds a regression spec). - Brand Kit ignores a backing run that is awaiting user input (anti-bot wall / question form): new reversible `needs_input` brand status, derived on read (never persisted) so it flips back once the user answers. Surfaced as a "Needs input" badge + hint in the card and a distinct status dot in the list; the list keeps polling while paused. - Home → Recent projects showed brand-extraction projects as "Not started": /api/projects now falls back to the brand lifecycle for brand projects whose run-derived status is `not_started` (extracting→running, needs_input→awaiting_input, ready→succeeded, failed→failed), so a live extraction is never shown as not started. - "Use in new chat" produced no visible result: it now carries a confirmation notice through the Home intent channel so Home shows a "Using <brand>" toast, making the navigate+apply verifiable (the composer already preselects the brand's design system). Tests: daemon brand-routes (canceled→failed, needs_input transient) and brand-extraction-engine (fast return + background finalize) specs; web BrandPreviewCard specs (needs_input badge/hint, Use-in-new-chat notice). #4 validated end-to-end against a real daemon. guard + typecheck green. * [codex] Fix brand extraction incomplete states (#4486) * fix brand extraction incomplete states * fix web memory tests for advanced modal Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix onboarding P0 brand-step navigation Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix daemon brand extraction test timeout Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix brand extraction fallback prompt state Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> * [codex] Fix brand extraction terminal status reconciliation (#4532) * Fix brand extraction terminal status reconciliation * Keep prefetched brand pages previewable * fix(brands): preserve ready extraction status Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(brands): persist terminal extraction signal Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(brands): clear stale terminal retry markers Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> * Fix brand kit modal intent handling (#4528) Co-authored-by: Siri-Ray <2667192167@qq.com> * fix(web): let design system contents scroll in narrow review layout (#4526) Co-authored-by: Siri-Ray <2667192167@qq.com> * [codex] Fix Brand Kit preview lifecycle guards (#4527) * Fix brand kit preview lifecycle guards * fix(brands): keep detail selected on delete failure Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(brands): handle delete HTTP failures Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> * ci: retrigger pull_request checks * test(e2e): stabilize entry settings shard --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: PerishCode <perishcode@gmail.com> Co-authored-by: lefarcen <935902669@qq.com> Co-authored-by: PerishFire <39043006+PerishCode@users.noreply.github.com> Co-authored-by: Siri-Ray <2667192167@qq.com> Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
6cf48c29b5 |
ci: reduce Blacksmith usage and stabilize PR checks (#4603)
* ci: move lightweight workspace checks to hosted runners * ci: split UI P0 project runtime shard Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * Stabilize UI P0 project runtime tests --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
d3896fa51a |
[codex] Clean deprecated launcher payloads on updater startup (#4524)
* fix(packaged): recover stale launcher and sidecar state * fix(packaged): write launcher cleanup from installer sync * perf(tools-pack): reuse windows payload caches * perf(tools-pack): avoid slow windows 7z filters * fix(tools-pack): bound windows payload archive hangs * test(packaged): stabilize sidecar tests on windows * fix(tools-pack): harden launcher runtime sync helper * fix(tools-pack): invalidate nsis cache for installer helpers * fix(tools-pack): hash nsis helper source in bundled cli * fix(packaged): restart when existing desktop has stale sidecars * chore(release): bump beta base to 0.11.1 * fix(e2e): seed windows smoke onboarding in runtime data * ci(release): let beta runs use default queueing * ci(release): restore beta concurrency guard * ci(release): enable beta mac x64 by default * ci(release): disable beta mac x64 by default * fix(updater): clean deprecated launcher payloads on startup * fix(e2e): align stable dry-run fixture version Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
d5d9a761ca |
refactor(daemon): organize source modules (#4454)
* docs(daemon): add agent guidance * refactor(daemon): organize source modules * chore(guard): update daemon design system import * refactor(daemon): shorten domain module filenames * fix(daemon): correct pitch-deck manifest path after test move The pitch-deck manifest test moved one directory deeper into tests/design-systems/ but kept the old '../../..' repoRoot, resolving to apps/ instead of the repo root and failing to find plugins/_official/examples/html-ppt-pitch-deck/open-design.json. * fix(daemon): retarget media model verifier Generated-By: looper 0.9.10 (runner=fixer, agent=codex) * docs(daemon): refresh AGENTS legacy paths after module reorg * test(e2e): allow manual edit P0 CI scaling Generated-By: looper 0.9.10 (runner=fixer, agent=codex) * test(daemon): fix frontmatter import path Generated-By: looper 0.9.10 (runner=fixer, agent=opencode) * fix(web): avoid replaying legacy terminal runs Generated-By: looper 0.9.10 (runner=fixer, agent=opencode) * fix(web): preserve legacy terminal replay recovery Generated-By: looper 0.9.10 (runner=fixer, agent=opencode) * fix(daemon): correct live-artifacts test data root * fix(daemon): cover moved route registrars in context contract Generated-By: looper 0.9.10 (runner=fixer, agent=opencode) * fix(daemon): restore moved runtime artifact imports Generated-By: looper 0.9.10 (runner=fixer, agent=opencode) |
||
|
|
5190db7f00 |
feat(web): redesign onboarding connect step as a cloud sign-in landing (#4513)
* feat(web): redesign onboarding connect step as a cloud sign-in landing
Reworks the onboarding first screen into a centered cloud sign-in
landing: brand glyph, headline, one primary cloud sign-in button, and
two secondary links (local CLI / your own key) that each open a
dedicated setup page. Removes the AMR card + three-way runtime picker.
Also:
- Drop the three-step stepper across onboarding; Back link moved
top-left on every sub-page.
- Top-right language (compact, opens down-left) + theme (one-click
light/dark) controls; theme applies synchronously to avoid lag.
- About-you fields become flat tappable chips instead of dropdowns.
- Replace Marketing role with Marketing agency (pinned first).
- Cloud button is state-aware: shows Continue (signed in) when already
signed in and advances directly; shows a brief loading state while the
login status resolves (fetched in parallel on mount).
- Fix onboarding container height (100vh -> 100%) so the footer is not
clipped below the tab bar.
Adds onboardingCloud{Title,Body,SignIn,Continue,Alternative,Or,Rights}
i18n keys; renames onboardingRoleMarketing -> onboardingRoleAgency
across all locales.
* fix(web): attribute already-signed-in Continue into the AMR funnel
The redesigned onboarding cloud landing shows a Continue (signed in)
button when the user is already signed in, which advanced to the next
step via setStep without recording any AMR entry attribution. Only the
sign-in flow (handleCloudSignIn) recorded onboarding_amr_card /
onboarding_amr_sign_in_continue, so already-signed-in users who clicked
Continue were invisible to the AMR attribution funnel — systematically
under-counting that conversion path.
Record the same card + sign_in_continue entries before advancing so the
two cohorts (fresh sign-in vs. already signed in) are attributed
consistently. Runtime/mode/agent are already set to amr by the existing
amrAgent effect, so this is attribution-only with no behavior change.
* fix(web): pin amr runtime on already-signed-in Continue so it records
The already-signed-in Continue branch advanced without setting runtime,
relying on the amrAgent effect to backfill runtime='amr'. If amrAgent
hadn't resolved yet at click time, the onboarding_complete_result event
could record runtime_type='none' instead of 'amr_cloud'. Set runtime/
mode/agent explicitly here (as handleCloudSignIn already does) so the
completion event records the cloud runtime regardless of effect timing.
* test(web): update onboarding tests for the cloud sign-in landing
The connect-step redesign replaced the AMR runtime card + runtime picker
with a centered cloud sign-in landing, so the onboarding suites still
asserted removed UI (the /Open Design AMR/ card, AMR version text, the
'Sign in to continue' CTA, dropdown About-you fields).
Remap to the new UI while preserving coverage:
- AMR auth flows (pending/polling/cancel/error/timeout/recovery) now
trigger via the landing 'Sign in to Open Design Cloud' button; assert
'Signing in…', the Cancel sign-in button, and role=alert errors.
- 'Continue (signed in)' advances past the signed-in connect step.
- Gate-tooltip coverage retargeted to the still-existing BYOK-unverified
and Local-no-agent gates on the bottom Continue CTA.
- About-you picks go through chip buttons (chooseChipOption) instead of
dropdowns; analytics-payload assertions unchanged.
- The two AMR-card skeleton tests now assert the surviving behavior: the
landing stays usable during agent detection with no card/skeleton.
apps/web suite: 334 files / 3333 tests green.
* test(e2e): capture the new cloud sign-in landing in the visual entry suite
The visual-entry suite waited on the removed runtime-selection surface
(the 'Choose a runtime' heading and the .onboarding-view__amr-cloud-card
model picker), so its precondition assertions failed before the
screenshot — element(s) not found. Retarget the capture to the new
Open Design Cloud sign-in landing (cloud CTA + secondary runtime links).
captureVisual only writes an artifact (no baseline diff), so no baseline
regeneration is needed.
* test(e2e): update amr-onboarding UI test for the cloud sign-in landing
The redesign replaced the AMR runtime card + runtime picker with the
Open Design Cloud sign-in landing, so the shared gotoOnboarding helper
(waiting on the removed 'Choose a runtime' heading) failed all tests.
Remap to the new UI while preserving coverage: AMR sign-in/poll/cancel/
recovery now drive the landing cloud button; About-you picks go through
chips; gates assert against the BYOK/Local panel headers. The three
tests that exercised the removed per-runtime model picker on the connect
card are narrowed to the surviving coverage (signed-in AMR completes
setup / carries agentId 'amr' into the first run). 23 tests green
locally via the Playwright harness.
* test(e2e): update packaged onboarding smoke (mac/win) for the cloud landing
The packaged @electron-smoke onboarding specs probed the removed
runtime-card DOM (.onboarding-view__amr-cloud-card / __alternatives /
__model-picker, aria-pressed selection). Retarget the eval snapshot,
type, validator, and click expression to the new cloud sign-in landing:
the primary cloud CTA (.onboarding-cloud__primary) plus the two
secondary runtime links (.onboarding-cloud__secondary), and add a Back
(.onboarding-view__back-to-cloud) step so the smoke can expand BYOK then
Local without the (landing-only) links. Verified via e2e typecheck;
these env-gated packaged-Electron smokes run in the release pipeline.
* fix(web): close the Search tabs popover when onboarding becomes active
The onboarding redesign hid the Search-tabs trigger button while
onboardingActive is true, but the popover portal below rendered
unconditionally on tabsMenuOpen. A popover left open across a route flip
to /onboarding (e.g. browser back/forward, which bypasses activateTab/
createNewTab) survived as a stray 'Search tabs' dialog floating over the
first-run flow with no visible control to dismiss it.
Close the menu in an effect when onboarding activates, and gate the
portal on !onboardingActive so it cannot render even for the frame
before the effect runs. Adds a red-spec regression test (opens the
popover, rerenders to the onboarding route, expects the dialog gone).
Addresses reviewer feedback on PR #4513.
---------
Co-authored-by: elihahhahahah11 <294718562+elihahhahahah11@users.noreply.github.com>
|
||
|
|
358a426b2b | ci: rename atom workflows (#4522) | ||
|
|
e79934b12a |
test(e2e): de-flake manual-edit bridge element selection (#4512)
The P0 'manual edit' UI tests intermittently time out at 30s on `frame.locator(selector).click()` inside selectPreviewElementThroughBridge (seen dequeuing #4497 and #4501 from the merge queue, on unrelated landing-only / docs-only changes). Root cause is a click-vs-resettle race, not a product bug: entering manual-edit mode re-injects the edit bridge and re-emits its targets a tick later (`setTimeout(postTargets, 0)` in edit-mode/bridge.ts) while the preview iframe is still settling, so the first click is occasionally swallowed and then hangs on Playwright's post-click stability check until the test timeout. Wrap the click + selection assertion in expect(...).toPass() with a short per-attempt timeout, so a single dropped click is retried through the settle window instead of failing the run. Final assertions are unchanged. Flaky by nature, so no deterministic red spec; verified e2e typecheck and that the wrapped assertions match the original. CI 'UI P0 (project-runtime)' exercises the live path. |
||
|
|
c1701f709a |
[codex] codify workflow handoff capabilities (#4503)
* codify workflow handoff capabilities * Harden workflow marker jq lookups Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * harden autofix head validation * Preserve Nix hash fallback guidance Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * Gate Nix hash fallback comments Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * Clear stale Nix fallback comments after autofix Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
c782aeb3bb | ci: stop duplicate post-merge validation (#4469) | ||
|
|
b49c9b7932 | Refine CI hot and full validation modes (#4466) | ||
|
|
73d07d8dfb | test(e2e): stabilize AMR onboarding assertions (#4462) | ||
|
|
b02d20e6b9 |
fix: unify Discord invite links (#4452)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local> |
||
|
|
15d3759834 |
[codex] Optimize CI topology and Playwright suites (#4460)
* Consolidate PR validation into ci * Tune absorbed CI runner tiers * Fold visual validation into CI Playwright shards * Run PR shards during manual CI dispatch * Optimize CI topology and scopes * Increase UI P0 Playwright workers * Relax visual Playwright timeout |
||
|
|
fdb1638183 |
[codex] Refresh local CLI auth state after API key switches (#4453)
* Refresh Codex auth status after CLI changes * Probe Claude Code auth status * Stabilize project route during agent refresh * Respect API key auth during CLI probes |
||
|
|
8ff19c6b41 |
[codex] Add main-risk smoke and E2E coverage (#4322)
* test(e2e): cover daemon reload artifact recovery * test(e2e): expand critical flow coverage * test(daemon): add startup and recovery smoke coverage * test(e2e): add visual and desktop chrome smoke coverage * ci: gate packaged onboarding smoke to nightly * fix(web): repair artifact replay type narrowing Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(ci): repair preflight smoke coverage checks Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): tighten artifact recovery polling Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): keep error recovery retries alive Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(e2e): relax brittle UI P0 assertions Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): recover pointer artifact outputs Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(e2e): stabilize manual edit reload smoke Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(e2e): avoid noisy win onboarding cleanup Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): stop failed artifact recovery polling Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(daemon): isolate startup smoke data root Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): recover standalone html artifacts Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(web): guard pointer artifact recovery by run time Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(ci): narrow strict visual gate to critical smoke Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * fix(ci): limit PR visual capture to critical cases * fix(ci): keep PR visual capture complete * fix(web): keep reload artifact recovery retryable * fix(ci): clarify PR visual gate layering * fix(e2e): stabilize visual home P2 capture * fix(e2e): align visual gallery detail clicks * fix(e2e): preserve packaged install during onboarding cleanup * fix(ci): shard PR visual capture * fix(ci): remove duplicate nix validation from ci * fix(ci): keep visual capture screenshots flat * fix(ci): point nix hash autofix at ci-nix * fix(ci): stabilize PR P0 recovery gate * fix(web): ignore stale artifact pointers during recovery * fix(web): reset BYOK model after clearing key * ci: run critical UI P0 subset on PRs * ci: combine PR UI P0 critical shards * ci: combine PR visual capture shards * ci: preserve visual capture shard manifests * fix(web): clear ProjectView delayed timers on unmount * test(e2e): harden onboarding connect gate coverage * test(e2e): align AMR auth recovery and visual catalog timeout |
||
|
|
e1b8d9921e |
Merge pull request #4421 from nexu-io/release/v0.11.0
release: Open Design 0.11.0 — The Bazaar |
||
|
|
d0d1df8e60 |
fix(web): portal New Project design-system dropdown so it isn't clipped (#4346)
* test(e2e): red-spec reproducing #4303 design-system dropdown clipping The New Project design-system popover (local DesignSystemPicker in NewProjectPanel.tsx) opens with plain position:absolute and is clipped by its .newproj-body { overflow-y: auto } ancestor, so lower options are truncated. This P1 UI spec opens the picker on a short window and asserts the popover does not spill past the .newproj-body / viewport bottom. https://claude.ai/code/session_01EqWRnbYoxmugj4R1yj2LJ6 * fix(web): portal New Project design-system dropdown so it isn't clipped (#4303) The New Project modal's design-system picker opened its popover with plain position:absolute, anchored inside .ds-picker. Its clipping ancestor is .newproj-body { overflow-y: auto } (the modal scroll container), so when the trigger sat low in the body or the window was short, the popover was truncated and the sections below bled through — the reported misaligned/truncated UI. This is platform-independent (shared web CSS rendered by the same Chromium in macOS and Windows desktop), not a macOS-only regression. Mirror the shared DesignSystemPicker: render the open popover through a portal to document.body, positioned from the trigger's viewport rect with viewport-aware up/down placement and a clamped max-height, so it escapes the clip box. A scoped .ds-picker-popover-portal variant flips the popover to position:fixed (z-index above the modal backdrop) and lets the list flex and scroll inside the bounded height. The sibling PlatformPicker shares the same absolute-popover pattern and is left for a follow-up. https://claude.ai/code/session_01EqWRnbYoxmugj4R1yj2LJ6 * fix(web): clamp design-system popover height to available viewport space Review follow-up (#4346, thanks @mrcfps): the anchor used Math.max(200, Math.min(440, space)), so when both sides of the trigger were under the 200px preferred minimum (a very short window) the fixed popover was still sized to 200px and overflowed the viewport instead of staying scrollable. Size the popover to the chosen side's actual available space, honoring the 200px preferred minimum only when the side can fit it. The list already flexes and scrolls inside the bounded height, so a smaller box just scrolls rather than spilling past the viewport edge. Extend e2e/ui/new-project-ds-picker-clipping.test.ts with a tight-viewport case (1280x360) that asserts both sides fall under 200px and the popover stays within the viewport. https://claude.ai/code/session_01EqWRnbYoxmugj4R1yj2LJ6 --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
1e2f47fb8d |
fix(amr): surface vela login URL/code so sign-in survives a failed browser handoff (#4402)
* fix(amr): surface vela login URL/code so sign-in survives a failed browser handoff AMR (vela) sign-in is a device-authorization flow: `vela login` prints the activation URL + user code to stdout, then best-effort opens the browser and keeps polling until the server-issued expiry (>5min). The daemon spawned it headless, only read the first 250ms of output, and the UI showed nothing but a "Signing in…" spinner — so when the browser failed to open (stripped PATH in a packaged build, blocked network) the user had no URL to fall back to and stared at a dead spinner for the full AMR_LOGIN_TIMEOUT_MS (5 minutes). - daemon: parseVelaLoginActivation + lifetime stdout/stderr capture surface activationUrl / userCode / browserOpenFailed on VelaLoginStatus. - web: the AMR account pill's signing-in state now shows an activation block (open sign-in page + copy code) as soon as the URL is known, instead of only a spinner; it adapts to the active theme. - web: an AMR run that fails with AMR_AUTH_REQUIRED now offers inline sign-in in the chat error card (the login pill) and auto-retries once on success, rather than bouncing the user out to Settings. Tests: red->green parser spec (validated against real vela login output), AmrAccountControl activation-block specs, ChatPane inline-auth specs. * test(amr): real-vela E2E for the login activation capture seam Spawns an actual `vela login` child through the daemon's spawnVelaLogin and asserts readVelaLoginStatus surfaces the real activation URL + code while the login is in flight, then cancels (never approves, so no config is written and any existing session is untouched). Covers the daemon capture wiring (beginLoginActivationCapture -> readVelaLoginStatus) that the pure parser spec can't reach. Auto-skips where the vela CLI isn't installed, so CI is unaffected. * fix(amr): polish inline auth retry layout * fix(daemon): try AMR login direct first, fall back to IPv4 proxy loopback AMR API proxy (forced IPv4) to dodge broken `amr-api.open-design.ai` edge paths for some hosts (#3726). But behind a corporate transparent proxy that hijacks `amr-api.open-design.ai` onto an internal gateway (e.g. 飞连/CorpLink → 30.x), the extra proxy hop makes the upstream lose the client IP and reject device authorization with `502: Invalid IP address: undefined` — even though the direct path resolves fine. Result: AMR "Authorize" fails in every packaged build that ships this change (beta/main), while release builds without it still work. Only `vela login` was rerouted; the model catalog and chat inference already go direct (to amr-link / VELA_LINK_URL), so this restores login to the same direct-first default. The IPv4 proxy is kept strictly as a fallback: the route now starts login over a direct connection and only retries through the proxy when the direct attempt fails to start — never when a login is already in flight. Both cohorts win: transparent-proxy users succeed directly, broken-edge users (#3726) still get the proxy. Tests: fake-vela gains FAKE_VELA_LOGIN_FAIL_WITHOUT_API_URL to model a broken direct path; the login suite now asserts direct-first (no VELA_API_URL on a healthy path) and proxy-fallback (VELA_API_URL set only after a direct failure, incl. OD_PUBLIC_BASE_URL derivation). * fix(amr): clear stale login activation details * fix(amr): refresh login status immediately after auth starts * fix(amr): sync inline auth card with login status * fix(amr): tighten inline auth retry state * fix(amr): wait for direct login activation before fallback * fix(amr): show activation details only in chat auth card * fix(amr): guard clipboard copy explicitly in the activation block navigator.clipboard?.writeText(...).then(...) already short-circuits the whole chain when the clipboard API is absent, but make the guard explicit so the copy handler reads as a clean no-op rather than relying on optional-chain reach. * fix(amr): don't kill a slow-but-healthy direct login; only fall back on real failure The login activation watchdog turned a merely slow direct CreateDeviceAuthorization into a hard failure: after the grace it killed the direct child and let the route retry through the IPv4 proxy — the exact proxy hop that 502s on the transparent-proxy networks this fix targets. Now the grace only stops blocking the request; a still- running direct attempt is left alive (the UI polls /status), and the proxy fallback fires only on an explicit pre-activation exit/error. The grace is overridable via OD_AMR_LOGIN_ACTIVATION_GRACE_MS so the new route test can exercise the slow-direct path quickly (fake-vela gains FAKE_VELA_LOGIN_ACTIVATION_DELAY_MS). Addresses review feedback on #4402. * test(e2e): AMR auth failure now signs in inline, not via Settings The chat AMR_AUTH_REQUIRED card replaced its 'open Settings to authorize' bounce with an inline sign-in pill (POSTs vela login in place, auto-retries on success). Update the [P0] runtime-recovery spec to assert the inline flow: clicking Authorize & retry issues the login request and opens no Settings dialog. The non-AMR 'Switch to AMR' recommendation flow (AmrGuidance) is unchanged. * fix(amr): only auto-retry inline auth on a real sign-in transition The inline AMR auth card auto-retried the failed run whenever /status reported signed-in — via both the 500ms shared-status poll and the pill's onStatusChange. Because the per-assistant-id guard resets on each retry (new run = new id), a run that keeps failing AMR_AUTH_REQUIRED while /status reads signed-in retried forever (caught by the runtime-recovery UI P0 spec). Now we retry only on an explicit signed-out -> signed-in transition; a null/unknown status never fabricates one, and once signed-in we don't retry again until an explicit signed-out is seen. - Unit specs updated to drive the transition (and a loop-guard spec for the already-signed-in case). - e2e: the AMR auth spec asserts the inline sign-in flow (no Settings bounce); the switch-to-Codex spec mocks /status signed-out, the realistic state for an AMR_AUTH_REQUIRED failure, so the Authorize & retry action is offered. * fix(amr): fall back to the proxy on a post-grace direct login failure The direct-first login route only fell back to the IPv4 proxy when the direct child crashed inside the 250ms startup grace. A direct vela login that survives the grace and then errors out before printing its activation URL (the common broken-edge shape, #3726) returned 202 and stranded the user on a dead direct login. Re-introduce waitForActivation: the route now blocks until the direct attempt reaches device-auth steady state (prints its activation URL) or exits/errors before it; only a pre-activation exit/error triggers the proxy retry, and a slow-but-healthy direct login is left running (never killed). fake-vela now prints the activation block (so the daemon can detect steady state) and gains FAKE_VELA_LOGIN_FAIL_WITHOUT_API_URL_DELAY_MS; the route suite gains a regression where the direct attempt fails past LOGIN_STARTUP_GRACE_MS and must still reach the proxy. Addresses review feedback on #4402. |
||
|
|
4b9a15734d |
[codex] Consolidate PR validation into CI (#4451)
* Consolidate PR validation into ci * Tune absorbed CI runner tiers * Fold visual validation into CI Playwright shards * Run PR shards during manual CI dispatch |
||
|
|
891981d460 |
[codex] Optimize CI runtime topology (#4450)
* Optimize e2e tools-dev runtime parallelism * Remove visual networkidle wait * Optimize e2e vitest parallelism * Optimize Nix flake caching * Test CI on Blacksmith runners * Allow parallel manual CI runs * Tier CI runner sizes * Temporarily narrow CI debug scope * Instrument watcher CI timeouts * Instrument watcher event diagnostics * Avoid default polling in watcher tests * Skip runtime trace during watcher debug * Probe ARM runner tiers for CI * Focus CI runner probe on x64 browser * Probe browser workers by runner size * Probe Playwright file parallelism * Probe Playwright worker scaling on 8v * Reshape CI topology * Fix split E2E Vitest CI lane * Simplify daemon CI topology * Optimize Windows payload CI setup * Revert "Optimize Windows payload CI setup" This reverts commit |
||
|
|
67ade60bce |
fix(e2e): seed win smoke onboarding into the live daemon data dir (#4444)
The packaged Windows smoke's onboarding seed derived its target path from the installed app's baked config, which falls back to AppData and never matches the data dir the running daemon actually reads. `tools-pack win start` rewrites `namespaceBaseRoot` to the tools-pack runtime root and hands it to the runtime via OD_PACKAGED_CONFIG_PATH, so the live daemon's RUNTIME_DATA_DIR is always under `runtimeNamespaceRoot`. The seed landed in the AppData fallback instead, so the daemon never read `onboardingCompleted`. This stayed invisible until #4389 removed the step-0 "Skip" affordance from the now-required Connect onboarding step: `ensureMainAppShell` used to click Skip to reach home, so an ineffective seed didn't matter. With Skip gone and the seed missing its target, the app sat on onboarding and the smoke failed with "packaged windows runtime did not reach main app shell". Write the seed to `<runtimeNamespaceRoot>/data/app-config.json` — the exact dir the running daemon reads (already asserted for logs at line ~400) and the same approach the macOS smoke uses. Drop the now-dead manifest-derivation helper chain. |
||
|
|
39cad2b8a5 | chore(release): bump version to 0.11.0 for release/v0.11.0 | ||
|
|
f6cceb303d |
fix(plugins): unwrap cosmetic hard wraps in bundled manifest descriptions (#4406)
Picking a Home example-prompt card (or "Replicate this content" in the plugin detail modal) seeds the composer with the plugin manifest's `description`. Many descriptions were authored with cosmetic hard wraps (a single newline mid-paragraph, ~75 cols, as if formatted for a terminal/markdown source). The composer renders the seed with `white-space: pre-wrap`, so those newlines survived as short ragged lines that never filled the editor width — leaving a large blank gutter on the right of the input box (e.g. the Trading Analysis Dashboard template: 4 hard breaks, ~200px / 29% of the editor blank). Reflow the offending `description` / `description_i18n` strings in the 56 affected bundled manifests into flowing text (wrapped lines joined, real blank-line paragraph breaks preserved; CJK joins carry no space). Surgical string edits only — manifest formatting/key order untouched (146 lines changed across 56 files). The full build spec still reaches the agent as plugin context (SKILL.md + example.html); only the human-facing seed copy changed. Add an e2e guard (plugin-description-hardwrap.test.ts) that fails if any bundled manifest description carries an intra-paragraph hard wrap, so the cleanup can't silently regress when new examples are added. |
||
|
|
a4abae3804 |
fix(release): build the daily beta from main, not the latest release branch (#4393)
* fix(release): build the daily beta from main, not the latest release branch
notify-daily-feishu picked the highest-semver release/vX.Y.Z branch and
built beta off it. Once that branch ships stable, its base version equals
the latest stable, so release-beta's strictly-greater-than-stable guard
rejects every scheduled run until someone hand-bumps the retired branch —
which is exactly how the daily beta + Feishu card silently stalled for
days after 0.10.1 shipped.
Beta is the daily R&D channel, so track the development tip (main), which
always leads stable. Keep the workflow_dispatch `ref` input for one-off
builds from a specific branch.
* test(release): scope daily-beta resolve check and assert ref override
Strengthen the regression test per review: scope the assertions to the
resolve job and prove both control-flow branches — the empty-input
default writes ref=main, and the workflow_dispatch override still
forwards ${{ inputs.ref }} verbatim — so a refactor can't keep the test
green while breaking the preserved override path.
|
||
|
|
0bd8cb13b1 | Merge remote-tracking branch 'origin/main' into iodized-nephew | ||
|
|
0284577472 |
feat(asset-management): enhance asset dropzone and introduce chat-to-design feature
- Updated the DesignSystemAssetDropzone component to improve file preview handling with new functions for creating and revoking object URLs. - Adjusted CSS for better layout and spacing in the asset dropzone. - Added a new "Chat to design" button in the LibrarySection component, allowing users to send selected assets to the Home chat composer for project creation. - Updated localization strings across multiple languages to reflect changes in asset import terminology. - Enhanced the HomeView component to handle asset staging from the chat composer. |
||
|
|
f81439bdae |
feat(onboarding): gate Connect step, sequential stepper, restyle progress bar (#4389)
* feat(onboarding): gate Connect step, sequential stepper, restyle progress bar - Remove "Skip for now" — Connect is now a required step, not skippable. - Gate Continue until the selected runtime is usable: AMR signed in, an available local CLI selected, or a BYOK connection test that passed. - Make the stepper a strictly-sequential wizard: only already-reached steps are clickable, no forward jumps. Keys off a maxStepReached counter instead of the async AMR login probe, so the indicator no longer flickers disabled->enabled while that status resolves. - Disable the "+" new-tab affordance (button + Cmd/Ctrl+T) while on the onboarding route, so opening a tab can't bypass the Connect gate. - Restyle the stepper as a thin segmented progress bar with centered labels; drop the oversized "Welcome" hero title. - Deprecate the now-unreachable onboarding `skip` / `skipped` analytics enums (kept for historical data; no longer emitted). * test(onboarding): update specs for the new Connect gate behavior CI flagged onboarding tests still asserting the removed/changed UI. Vitest (apps/web): - e2e helper: wait for Continue to be enabled before clicking — AMR detection lags, so the Connect gate keeps it disabled until vela/status confirms signed-in; clicking a disabled button was a no-op and stalled at step 0. - "switches runtime" test: assert Continue is now disabled after switching to a not-yet-ready Local runtime (gate behavior). - about_you_submit-once test: advance via Continue instead of a stepper forward-jump, which is no longer allowed. - replace the Skip-exits test with one asserting the Connect step has no Skip affordance and emits no skip/skipped telemetry. Playwright (e2e/ui): - gotoOnboarding: key off the "Choose a runtime" heading instead of the removed "Welcome" hero title. - replace the skip-exits P0 with a no-Skip-affordance assertion. - visual-home: same Welcome -> Choose a runtime marker update. --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> |
||
|
|
2a150e0286 |
feat(library): enhance asset import and management features
- Updated the `import` command to allow multiple local files and remote URLs, with restrictions on supported formats. - Added new commands: `apply` for copying assets into project design files, `edit-as-page` for converting HTML assets into editable projects, and `figma` for exporting Figma captures. - Introduced sidecar functionality for storing derived data alongside owned assets, including Figma capture IR and element HTML. - Enhanced server configuration to support larger ingest payloads for asset captures. - Improved error handling and user feedback during asset import and application processes. |
||
|
|
30b8eac48c |
chore(release): bump version to 0.10.2 on main (#4387)
main read 0.10.1 (== latest stable 0.10.1), so the daily beta build's strictly-greater-than-stable version guard refused to produce a beta from main. Advance the 0.10.x dev line to 0.10.2 across the same 16 lockstep workspace package.json that #4381 bumped, and align the packaged-smoke stable dry-run fixture to 0.10.2. This continues the existing beta line on R2 (0.10.2-beta.4) so a build from main produces 0.10.2-beta.5. |
||
|
|
66d9cf9fb6 |
fix(release): accept releaseVersion/releaseNumber in beta metadata reader (#4383)
The daily beta build (notify-daily-feishu) reads beta/latest/metadata.json via scripts/release-beta.ts, which only understood the legacy betaVersion/betaNumber fields. The unified release publisher and the in-flight tools-release rewrite stamp the feed with generic releaseVersion/releaseNumber instead, so once a build from that tooling wrote the feed the daily reader died with 'must include betaVersion or baseVersion+betaNumber' and the scheduled beta + Feishu card stopped. Accept either field spelling so the reader survives whichever publisher last wrote the feed. |
||
|
|
a3a5f02d87 |
chore(release): bump version to 0.10.1 on main (#4381)
Back-fill the 0.10.1 version bump that shipped via the release/v0.10.1 branch (tag open-design-v0.10.1, already published) but never merged back to main. The feature/perf content of that release already landed on main via #4198, #4203 and #4202; only the version-number bump and the packaged-smoke stable fixture were left behind, so main still read 0.10.0. This applies the release-specific deltas onto current main: - bump version 0.10.0 -> 0.10.1 across the 16 workspace package.json in the 0.10.x release set (apps/daemon, apps/desktop, apps/landing-page, apps/packaged, apps/web, e2e, root, packages/contracts, packages/download, packages/host, packages/launcher-proto, packages/platform, packages/sidecar-proto, packages/sidecar, tools/dev, tools/pack) - align e2e packaged-smoke stable fixture to 0.10.1 launcher-proto was added to main after the 0.10.1 release branch was cut, so it was not in the original release commit; it is part of the lockstep 0.10.x release set (private workspace package, sibling of sidecar-proto), so it is bumped here to keep main release metadata consistent. Independently-versioned workspace packages (agui-adapter, components, diagnostics, metatool, plugin-runtime, registry-protocol, tools/serve, telemetry-worker) are intentionally left untouched. Supersedes the stale release/v0.10.1 PR (#4205). |
||
|
|
f2fef8d9a5 |
[codex] fix prompt title summaries (#4348)
* fix prompt title summaries * fix ui p0 title expectations * use selected agent for title suggestions * strip generated titles across streams |
||
|
|
95900a615b |
Fix design system preview image asset URLs (#4177)
* fix: rewrite design system preview image assets * fix: reopen design review feedback cards * fix: preserve app urls in design previews * fix: preserve design preview asset suffixes * fix: rewrite inline design preview css assets * fix: refresh design manifest labels * fix: surface invalid design manifests * test: stabilize workspace restoration p0 * fix: validate design manifest card entries |
||
|
|
6c555f93d6 |
chore(ci): stabilize visual regression screenshots (#4290)
* Stabilize visual regression screenshots * Stabilize BYOK visual settings states |
||
|
|
a0afc584bb |
[codex] centralize daemon data directory docs (#4222)
* docs: centralize daemon data directory contract * fix(e2e): allow slower artifact consistency navigation Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * docs: localize daemon data directory pointers Generated-By: looper 0.9.5 (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
f82a4e3828 | fix(web): apply composer BYOK model selection (#4209) | ||
|
|
571b43dce0 |
[codex] Expand UI E2E coverage and P0 CI signal (#4196)
* add PR UI P0 gate * fix(ci): keep critical UI check in required workflow Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * ci: split workspace restoration P0 shard * ci: reduce visual and daemon test wall time * ci: skip duplicate critical UI gate on PRs * ci: increase daemon test sharding * test(e2e): expand critical UI flow coverage * test(e2e): promote critical onboarding and automation flows * test: expand ui e2e coverage * test: repair PR P0 onboarding and media sync checks Generated-By: looper 0.9.7 (runner=fixer, agent=codex) |
||
|
|
21e01f6a25 |
Fix raw asset review cards in design systems (#4093)
* fix: avoid raw asset review cards * fix: resolve web component styles in dev * fix: keep design system component images reviewable * fix: use webpack for local web dev sidecar * fix: improve design system review cards * fix: render design system review previews from srcdoc * fix: keep image ui kit cards generic * fix: rebase inlined preview css urls * test: allow slow send-now navigation --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
2f301902d7 |
fix(web): keep New Project design-system dropdown above form sections (#4026)
The 'Design system' dropdown in New Project rendered behind the form sections below it (Target platforms, Companion surfaces, Fidelity, Create), so the form bled through the open popover. Every .newproj-section carries a residual identity transform from the od-fade-slide-up entrance animation (animation-fill-mode: both), turning each section into its own stacking context. .ds-picker is such a section, so the popover's z-index was trapped inside the picker and could not rise above later sibling sections. Lift the OPEN picker's stacking context above its siblings so the dropdown paints on top. Red->green Playwright spec samples points down the open popover and asserts elementFromPoint resolves into the popover. |
||
|
|
d055737de7 |
[codex] Add PR UI P0 gate (#4142)
* add PR UI P0 gate * fix(ci): keep critical UI check in required workflow Generated-By: looper 0.9.7 (runner=fixer, agent=codex) |
||
|
|
8c3500c807 |
[codex] Cover preview toolbar and conversation history flows (#4134)
* test(e2e): expand home and project detail coverage
* test: cover preview toolbar and conversation history flows
* test: lower priority of supplemental e2e cases
* Revert "test: lower priority of supplemental e2e cases"
This reverts commit
|
||
|
|
4c8914dc71 |
feat(web): split onboarding newsletter into its own third step (#4106)
* feat: move onboarding newsletter signup to its own third step * test(e2e): walk amr-onboarding through the new newsletter step before finishing * fix(web): keep about_you_submit exactly-once on the onboarding completion path The newsletter step is now its own (final) step with a clickable stepper and Back button. Emitting the about_you_submit survey snapshot when the user leaves the About-you step double-fired on Back-then-Continue and fired zero times on a forward stepper jump. Move it onto the completion path, stamp it with fixed About-you coordinates (it describes the About-you submission regardless of which step finishes), and guard it with a per-session ref so it is exactly-once. Adds regression tests for the stepper-jump and Back-then-Continue flows. * test(web): walk amr onboarding e2e through the newsletter step before finishing --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> Co-authored-by: lefarcen <935902669@qq.com> |
||
|
|
70c70ff9a3 |
feat(web): replicate-first Use menu + send-button attention pulse (#4059)
* feat(web): lead the plugin detail Use menu with Replicate this content The split-button menu only exists when the plugin ships an example query, and reproducing the previewed result is what most users open it for — so the replicate option now comes first and structure-only Use drops to second. * feat(web): pulse the send button after a plugin Use or example-prompt pick Choosing Use / Use with query in the plugin detail modal, or clicking an example-prompt card, seeds the composer and returns the user to it — but nothing signals that sending is the next step. Flash the send button twice (house ease-out, 0.25s delay so the scroll-back settles first, none under prefers-reduced-motion) via a new HomeHeroHandle.pulseSend() fired from routePluginUse and useExamplePlugin. * feat(web): replicate-content as the primary detail CTA + sheen-style send pulse - The detail modal's primary Use button now reads (and acts as) 'Replicate this content' when the plugin ships an example query; structure-only Use moves behind the caret menu. Shared via pluginUsePrimaryAction so all four detail variants agree. - The send-button attention effect drops the ring+scale flash for a soft light sweep crossing the button twice — same trigger points, same reduced-motion opt-out. - Plain structure-only Use now pulses only when the composer is actually submittable (draft text or staged files); flashing a disabled send button pointed at a dead end. * feat(web): first-run guidance trail — prototype chip and first preset card sheen Brand-new users (no projects, fresh storage) get a sheen pulse on the Prototype type chip ~1s after Home settles; picking any type chip advances a persisted stage and the first example-prompt card pulses once when the chip's presets render, completing the trail (the existing send-button pulse covers the final beat after a card pick). Users with projects have the stage completed silently so the trail never shows. The send-button sheen generalizes into a shared .home-hero__attention-sheen class (accent-tinted glint on light chip / card surfaces), still skipped under prefers-reduced-motion. * fix(web): gate the first-run guide on project loading completing firstRunGuide was true whenever projects was the initial empty array, so the trail could arm for an existing user whose projects were still loading. Make the prop tri-state (undefined while loading): the guide neither arms the chip pulse nor silently completes the stage until the projects answer is known. * fix(web): close any in-flight guide stage for existing users + gate the card pulse A chip pick during the projects-loading window can advance the guide stage to 'card' before firstRunGuide resolves; if the user then turns out to have projects, the stage lingered and the beat-2 effect (not gated on firstRunGuide) could sheen the first preset card for a non-new user. The firstRunGuide === false branch now completes ANY unfinished stage, and the card-pulse effect requires firstRunGuide === true. * fix(web): pulse Send from the static prompt-example path too The fallback prompt-example cards (rendered when a chip has no example plugins) seed and focus the composer entirely inside HomeHero, so they never reached the HomeView-routed pulseSend(). Extract a local triggerSendAttention() shared by the imperative handle and usePromptExample, with a focused spec clicking a home-hero-prompt-example card. * fix(test): null-guard the first prompt-example card lookup tsc (noUncheckedIndexedAccess) rejects passing exampleCards[0] straight to fireEvent.click; guard explicitly. * fix(web): gate the Send pulse on the composer actually being submittable usePlugin() now resolves a boolean: whether the bound plugin left the composer submittable (inputs valid, apply not failed/superseded). All three pulse call sites (use-with-query, plain Use, example preset pick) consult it, so a plugin with required inputs and no defaults routes the user to the inputs form without a misleading flash on the disabled Send button. Spec: required-input plugin via detail-modal replicate → Send stays disabled and unsheened. * fix(web): carry the guide's beat 2 through the static prompt-example fallback A chip with no plugin presets renders static prompt-example cards, but the beat-2 effect only watched filteredExamplePlugins — a fresh user on that path never got the card pulse and the persisted stage stuck at 'card'. Either card surface now satisfies beat 2, the first static prompt-example button carries the sheen, and a regression spec covers the presetless-chip path. * test(e2e): route freeform Use through the Use-plugin-only menu option The replicate-first menu change makes the detail modal's primary Use button seed the example query for query-bearing starters, so the structure-only freeform path now lives in the caret menu's 'Use plugin only' option. Update the P0 critical 'keeps the prompt freeform' spec to open the caret menu and click that option, matching the shipped behavior. * test(e2e): route the remaining freeform Use cases through the menu option The replicate-first primary CTA also seeds the prompt for query-bearing starters rendered via PluginExampleDetail/PreviewModal, so the neighboring [P1] 'Use plugin from the details modal' case (an html-preview fixture with an example query) that clicked the primary button and asserted an empty composer would fail once it runs outside the @critical gate. Route it through the caret menu's 'Use plugin only' option like the P0 case, and correct the now-stale 'no pre-fill' comments on the chip-only and use-with-query cases. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> Co-authored-by: lefarcen <ontf116@gmail.com> |
||
|
|
a0221deaba |
[codex] Fix onboarding dropdown styling (#4066)
* Fix onboarding dropdown styling * Fix onboarding dropdown placement test Generated-By: looper 0.9.7 (runner=fixer, agent=codex) * Fix searchable onboarding dropdown regressions Generated-By: looper 0.9.7 (runner=fixer, agent=codex) |
||
|
|
844a0c0af1 |
fix(web): scope Use actions to the plugin detail modal and decouple the Community filter from hero chips (#4037)
* fix(web): remove inline Use actions from Community gallery tiles The Home Community gallery tile grew an inline Use / Use with query split button in its title bar, repeating per card. The gallery tile is a pure live preview: opening the detail modal is where Use and Use with query live. Drop the gallery use menu (and its CSS) and route the visual-home use-with-query e2e flow through the detail modal's split Use button. The rich management layout (PluginsView installed tab) keeps its hover-overlay Use menu. * fix(web): decouple the Community category filter from hero type chips Picking an example-prompt type chip (Prototype / Slide deck / ...) — including the default chip on first paint — force-synced the Community grid's category selection through presetSelection, silently rewriting the user's browsing filter. The two surfaces share a taxonomy but are independent controls: the chip drives what the composer generates, the pills only filter the gallery. Remove the presetSelection plumbing (HomeView memo -> PluginsHomeSection prop -> usePluginFacets effect); the Community grid now boots on All and only moves when its own pills are clicked. * fix(e2e): match the Deck Writer detail dialog by plugin name Deck Writer carries a previewEntry, so its detail surface is the PreviewModal whose dialog is labelled 'Deck Writer preview' — the '... details' label only exists on the scenario detail. Match the dialog on the plugin name so the visual use-with-query flow finds it. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
39cf931290 |
Remove project instructions UI and preserve stream errors (#4045)
* Remove project instructions UI and preserve stream errors * Stop injecting hidden project instructions Generated-By: looper 0.9.7 (runner=fixer, agent=codex) |
||
|
|
3f5fe0f96c |
feat(amr): forward AMR_CLIENT_SOURCE to vela + source on wallet links (#4005)
* fix(landing): keep auth redirects on AMR wallet * feat(amr): tag vela CLI launches with AMR_CLIENT_SOURCE + source on wallet links So vela analytics can attribute Open Design's command funnel and model spend back to this host (source=open_design), and the AMR wallet landing carries the source for the web page_view. - runtimes/env: set AMR_CLIENT_SOURCE=open_design for the amr agent spawn (not PII, so no telemetry-consent gate) - integrations/vela: spawnVelaLogin forwards OD_INSTALLATION_ID (consent-gated) - web/daemon: AMR wallet recharge URL gains ?source=open_design Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(web): expect ?source=open_design on AMR console/recharge URLs The AMR console/recharge links the OD app opens into vela web now carry ?source=open_design so vela attributes the visit to Open Design. Update the console/recharge URL assertions accordingly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(daemon): expect ?source=open_design on AMR insufficient-balance recharge URL DEFAULT_AMR_RECHARGE_URL now carries the source param for attribution. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(amr): bump bundled vela CLI to 0.0.15 + fix e2e recharge URL assertion - tools/pack: bundle @powerformer/vela-cli 0.0.15 (the release carrying the source-attribution logic that reads AMR_CLIENT_SOURCE and tags model_request) - e2e: expect the insufficient-balance recharge URL to carry ?source=open_design (addresses review on DEFAULT_AMR_RECHARGE_URL) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(nix): refresh pnpm-deps hashes after vela CLI bump The tools/pack @powerformer/vela-cli bump changed pnpm-lock.yaml, invalidating the daemon/web fetchPnpmDeps fixed-output hashes. Update to the values the Nix flake check computed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: audit <a@b.c> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
6313286232 |
feat(home): plugin detail "Use plugin" split menu + align use-with-query with example-prompt seed (#3997)
* feat(home): plugin detail "Use plugin" split menu + align use-with-query with example-prompt seed
- PreviewModal.primaryAction gains an optional split-button menu. The plugin
detail modal's "Use plugin" now offers two variants — 仅使用插件 (use) and
复刻此内容 (use-with-query) — wired through the existing routePluginUse action,
i18n'd across all 19 locales (new preview.usePlugin / usePluginOnly* /
replicateContent* keys).
- use-with-query now seeds the composer with the SAME human-friendly text the
Home example-prompt cards use. Extracted examplePresetSeedPrompt (+ its
dependencies) from HomeHero into a shared plugins-home/presetSeedPrompt module
so both surfaces share one source of truth, instead of the detail modal
dumping the raw od.useCase.query meta-instruction ("follow the en field
verbatim; start from example.html") into the textarea.
- The example-prompt active plugin chip now shows the same × clear button as the
Community path (activeBadge.isExplicitPlugin distinguishes a user-picked
plugin from a task-chip default).
- Analytics: community_gallery/use_plugin (action=use|use_with_query) lands the
documented row-118 event; chat_composer/plugin_chip_clear mirrors
working_dir_clear for the chip ×.
* feat(prompt): generate artifact copy in the user's UI locale
Chinese (and other non-English) prompts were producing English pages: when a
template / plugin / design-system ships English reference content, the agent
copied that wording verbatim. The UI-locale override only covered chat prose
and generated form controls, not the artifact body.
Extend the locale override so all user-visible copy in the generated
HTML/React/page/deck (headings, body, nav, button/link labels, captions, alt
text, form fields) is written in the run's UI locale by default — and reference
content in another language must be translated/adapted, not shipped verbatim.
Brand names / code / identifiers stay as-is; an explicit user request for a
different output language still wins.
* fix(plugin-details): scenario fallback gets the use/use-with-query split menu
Review follow-up (#3997): PluginScenarioDetail was a single onUse(record,'use')
button, so any plugin routed to the text/scenario fallback lost the new split
action — users couldn't pick "Use plugin only" vs "Replicate this content" even
when od.useCase.query exists. Reuse the shared buildPluginUseMenu in the footer
as an upward-opening split button (caret menu), matching the html/design/media
variants, and keep a plain single button when there is no query.
Also update the home use-with-query visual e2e: use-with-query now seeds the
rendered preset text ("Draft a topic deck.") rather than the raw `{{topic}}`
query, matching the example-prompt card path.
Regression tests: scenario+query renders the split menu caret; scenario without
query keeps a single button.
* fix(home): preserve placeholder write-back when use-with-query seed is the query
Review follow-up (#3997, blocking): use-with-query unconditionally nulled
`queryTemplate`, dropping the only path that writes composer edits back into
`active.inputs`. For presets whose seed IS the rendered (human-friendly) query,
that meant editing a hydrated value before running submitted the plugin with
stale default inputs.
examplePresetSeedPrompt now returns `{ text, fromRenderedQuery }`. routePluginUse
keeps the raw `{{...}}` query template (and `queryTemplateAllowsPrefix`) only when
the seed came from the rendered query; it still nulls the template when we fell
back to a description / meta-instruction seed (no placeholders to extract). The
meta-instruction → description fix is unchanged.
Tests: friendly-query use-with-query now asserts the placeholder edit flows back
into pluginInputs (empty-draft and edited-draft-prefix cases); the
meta-instruction case still seeds the description with no write-back.
* fix(home): persist explicit-pick flag for active plugin chip visibility
Review follow-up (#3997): the active plugin chip's visibility + clear-button
gate inferred "explicit pick" from `record.id !== defaultPluginIdForChip(chipId)`.
An example-prompt preset whose plugin id equals the chip's default plugin — the
prototype rail binds `example-web-prototype`, which is also the prototype chip's
default — was therefore misclassified as a task-default binding, so its chip/×
never appeared even though the user explicitly picked the preset.
ActivePlugin now carries an `explicitPick` flag, set on the example-prompt
preset (useExamplePlugin) and Community / detail-modal (routePluginUse) paths.
Both `activeBadge` (chip label vs plugin title + ×) and
`shouldShowActivePluginChip` (the chip-visibility gate) short-circuit on it
before falling back to the id heuristic — so an explicit pick always surfaces
its own chip, while a type-chip default binding still stands in for the task
chip. Added a HomeView.activePluginChip regression covering the preset-equals-
default case.
* fix(home): keep prefix matching on for use-with-query placeholder extraction
Review follow-up (#3997): `queryTemplateAllowsPrefix` only enabled prefix
matching when the composer already had text BEFORE the user clicked Replicate.
The empty-draft → prepend-intro → edit-placeholder path then fell through:
extraction stayed anchored at `^`, so a placeholder edit after a freshly-added
intro stopped writing back into active.inputs and submit could re-apply stale
defaults.
Enable prefix matching whenever we track the query template (`hasTemplate`).
Suffix matching is equally correct with no prefix, and now tolerates an intro
the user prepends after the seed is inserted. Added the empty-draft → add
prefix → edit placeholder regression.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
|