mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
codex/design-system-module-only
95 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e654592ba6 |
fix(daemon): point users at the Settings section that actually exists (#6831)
* fix(daemon): point users at the Settings section that actually exists
When image generation failed for a missing credential, the reply told
the user to configure it in "Settings → Media". No such nav item exists —
the section is "Media providers" ("媒体生成提供商" in zh-CN) — so users
following the instruction found nothing.
The cause is that Settings destinations were spelled independently
wherever a producer happened to need one: 29 provider errors in
apps/daemon/src/media/index.ts said a bare unnamed "Settings" (one said
"Settings -> Media Providers"), and the od-media-generation skill said
"Settings → Media". None of them were tied to the Settings dialog, so a
rename could not reach them.
packages/contracts/src/settings-nav.ts is now the single place a Settings
destination is spelled, and every producer reads it: the media provider
errors, the ElevenLabs voice-options prompt (daemon + contracts), and the
external-MCP auth guidance. e2e/tests/settings-nav-copy.test.ts holds the
constants against the labels apps/web actually renders and fails the
build if a producer re-inlines its own guess.
Swept the same drift class while here: both hatch-pet SKILL.md copies
pointed at "Settings → Pets", but #5517 folded the pet picker into
General, so the real path is "Settings → General → Pets".
Verified the gate red on the pre-fix tree (3 failing assertions) and
green after. Adjacent, not fixed: these strings are English and the
agent translates them ad hoc, so a localized client can still render a
section name that does not match its own UI — see the report.
Record: recvre8FrTE2Oa (V0.19.1 acceptance)
* fix(contracts): gate destinations on rendered nav, not the i18n dictionary
Review on #6831 caught that SETTINGS_EXTERNAL_MCP named a place users
cannot navigate to. `mcpClient` kept its Settings render block but lost
its sidebar nav item (SettingsDialog.tsx says so in its own comment), and
reconnecting an external MCP server now lives in the top-level
Integrations view. So the destination is not a Settings section at all.
The stale string predates this branch — it was hardcoded in
prompts/system.ts on main. But promoting it into a named constant made it
worse twice over: the docblock asserted "The Settings nav item where
external MCP servers are added/reconnected" in a canonical location, and
the new gate whitelisted it by construction, so the check built to catch
dead paths became the thing defending one.
The deeper defect was the gate's invariant. Comparing a constant to its
i18n key's value proves only that some dictionary entry matches — not
that anything renders it. `settings.externalMcpTitle` still resolves to
"External MCP" with no nav item behind it, which is exactly how the dead
path passed. The same hole covered SETTINGS_MEDIA_PROVIDERS.
Now the gate parses what the UI actually renders — `settings-nav-item`
buttons and INTEGRATION_TABS — and resolves those keys through the
dictionary, using it as a lookup rather than as the source of truth.
Verified by reintroducing "Settings → External MCP": the old gate passed
it, the new one fails with the rendered destinations listed.
Replaces SETTINGS_EXTERNAL_MCP with INTEGRATIONS_MCP_PATH
(`Integrations → MCP`) and adds a regression test pinning that a
dictionary-only label is rejected.
|
||
|
|
356c8c364f |
feat(workspace-team): team workspaces, shared resources, workspace-scoped billing, and the #5517 redesign (#6142)
* fix(web): scope plugin URL imports to workspace * test(web): cover billing interest remount lifecycle * feat(packaged): enable the workspace-team transport for test-profile builds The vela test backend now serves the workspace-team API, so a packaged build baked with the test AMR profile should drive team projects / collab / resource sharing there instead of leaving them dormant. Replace the single feature-test equality check with a profile -> vela web origin map so adding a backend is one entry, and keep every unlisted profile (prod above all) off. * test(daemon): cover billing catch-up after SSE reconnect * fix(collab): surface and start first materialization when opening a shared project QA P0: a brand-new member on a fresh install joins someone's workspace, opens a project from it, and sees no loading state and no files — content only appears on a SECOND open, much later. Two defects, both on the first `/collab/status` request that opening a shared project makes. 1. No pull is started. The daemon's self-materialization block was gated on `callerIsOwner`, so a non-owner member got the placeholder record registered and nothing else. The web's auto-pull is gated on `publishedVersion` advancing past its cursor, and a fresh daemon's first status response cannot carry a published head: `collab.publishedVersion()` reads an in-process map that has never been written, and the real hub head is fetched fire-and-forget into `headEnrichmentCache` for a LATER poll to consume. Materialization therefore arrived only whenever a proactive lane (hub push / reconnect catch-up / the 30s recovery floor) next fired — the "second open" the report describes. 2. No download state is shown. `useProjectCollab.downloadPending` — which picks DesignFilesPanel's "Syncing files from the team…" over its empty state and create-a-file CTAs — reads only `publishedVersion > cursor`, `contentTransferState`, and an in-flight pull. All three are blank on that first response, so the member was shown an empty project inviting them to start creating over content that was still on its way. The fix makes the placeholder stamp the load-bearing signal on both sides: - `materializePlaceholderOnOpen` (routes/collab-sync.ts) replaces the owner-only block: any viewer opening a shared project whose only local record is an unmaterialized placeholder starts its pull on that same request, through the same coalesced flow. The retracted-share heal in its catch stays owner-only — a member who hits the hub tombstone has merely lost access and must not unshare anyone's project. - `/collab/status` reports `awaitingFirstMaterialization`, a purely local, synchronous fact that needs no hub round-trip and is therefore available on the very first response. `od collab status` prints it too. - `localFilesAreNotTheContentYet` (useProjectCollab.ts) makes it always download-pending, bypassing the member-only `shouldAutoPull` gate: whether the local files are the content is a fact about the record, not about who may pull it, so the owner of an unmaterialized placeholder (the reinstall case, recvqzaDvUU6B3) stops seeing the same empty state too. Red evidence: all six new specs fail on origin/feat/workspace-team @ |
||
|
|
ebcba704ef |
feat(prompts): introduce on-demand discovery in SP v2.0 (#6223)
* feat(prompts): introduce on-demand discovery in SP v2.0 * fix(prompts): prevent nested deck label overlap * fix(plugins): stabilize od-default task routing * fix: address prompt and deck audit regressions * fix(prompts): restore plan mode precedence * fix(daemon): accept all form answer headers --------- Co-authored-by: bone3deep1962-collab <bone3deep1962@gmail.com> |
||
|
|
f9d42f4770 |
Add Clone Audit plugin (#5687)
* Add Clone Audit plugin * Update open-design.json * fix: make clone audit skill reusable * fix: sanitize clone audit provenance path |
||
|
|
1912c3ba97 | Add Atelier Zero — Image Generation Prompt Pack plugin (#5873) | ||
|
|
5435274ab4 |
Add Humanize PPT plugin (#5655)
* feat(plugins): add Humanize PPT community plugin Ports LearnPrompt/humanize-ppt (MIT) into plugins/community/ following the community/hallmark precedent, and registers it in the community marketplace index (0.2.0 -> 0.2.1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(plugins): harden humanize-ppt per review — out-dir guard, PPTX fail-closed, packaging (v1.1.1) - brief mode no longer wipes a non-empty --out unless it carries Humanize run markers or --force is passed; wipe semantics documented in SKILL.md and docs/local-demo.md - read_source fails closed on .ppt/.pptx with guidance (extract text first; rendered decks go to --qa-from); SKILL.md/SPEC.md wording aligned - vendor examples/01-ai-tool-update/source.md, inline-fixture fallback in smoke_check.py, drop repo-only record_demo_gif.py, point dangling doc links at the upstream repo Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(plugins): humanize-ppt review follow-ups — outline-gate markers, shim exit codes (v1.1.2) - HUMANIZE_OUT_MARKERS now includes outline-preview.md and preview-confirmed.json, so the documented --preview-outline -> --confirm-outline -> brief flow on one --out is no longer refused by the out-dir guard; refusal text, --out help, SKILL.md/SPEC.md/ docs/local-demo.md list all four markers - humanize_ppt_v3/v4/v5 shims call sys.exit(main()) like the stable entrypoint, so validation failures propagate exit 2 instead of 0 - smoke_check.py gains an outline-gate check (preview -> confirm -> brief on one --out, plus the unrelated-out refusal negative path) and an exit-code matrix across all five public entrypoints - plugin 1.1.2, community registry 0.2.3 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
6b90486c97 |
docs: reconcile stale documentation with current code (#5829)
* fix(docs): align question guidance with form flow * docs: reconcile stale documentation with current code * fix(docs): remove retired template metadata from guides Generated-By: looper 0.10.6 (runner=fixer, agent=codex) * fix(e2e): stabilize visual workspace helper Generated-By: looper 0.10.6 (runner=fixer, agent=codex) * fix(docs): align localized template guide metadata Generated-By: looper 0.10.6 (runner=fixer, agent=codex) |
||
|
|
4b660237c0 |
feat(prompts): land the slim system-prompt line as the default charter (#5603)
* test(daemon): freeze scenario x section gating matrix for composeSystemPrompt
composeSystemPrompt splices ~30 conditional sections whose gates form an
implicit matrix (session mode x design system x skill surface x memory x
execution profile). Before any prompt-slimming refactor, this golden
snapshot freezes which sections each representative scenario receives,
so a re-gating regression surfaces as a snapshot diff instead of a
silent production behavior change.
Detection is line-anchored heading markers: discovery quotes headings
like "## Active plugin" mid-sentence, so bare substring matching would
false-positive on sections that were never spliced in. A companion
assertion fails when a marker goes stale (no scenario produces it), and
position invariants pin injection-resistance first / role-marker guard
last across every scenario.
* perf(prompts): stop shipping rare-path media/deck payloads on every run
Langfuse telemetry (24h, 2k-trace sample) puts the composed charter at
p50 96KB (~24K tokens) with a 21% stable-cache hit rate — most turns
resend it whole. Two always-on blocks serve paths most runs never take:
- MEDIA_DISPATCH_HINT (2.8KB into every non-media project) embedded a
40-line worked bash polling loop. The loop moves to 'od media help'
(the CLI already prints the exact next wait command on handoff), and
the hint keeps only the dispatch rules agents historically fumbled:
no provider REST calls, no API-key asks, POSIX not PowerShell,
python3 not jq, fal-ai/* passthrough. 2,771 -> 1,547 chars.
- The freeform maybe-deck branch injected the full 20.7KB deck
framework into every kind=other / no-metadata run 'just in case'.
New detectDeckIntentSignal() scans the same request text the agent
will see (transcript included, so a deck mention anywhere in the
conversation stays sticky) for generous EN/CJK deck vocabulary and
skips the framework when nothing matches: 78.5K -> 57.7K chars on
non-deck freeform runs. False positives fall back to today's
behavior; deck-kind projects stay unconditional. An absent signal
(contracts/BYOK composer, tests) preserves legacy always-inject.
Also relieves the POSIX argv budget: DS-active runs sat within 4KB of
the 100KB hard cap that fails argv-bound adapters (aider/deepseek).
Baseline check: tests/media/policy-routes.test.ts (7) and
tests/connection-test.test.ts (1, local Kimi CLI version) fail
identically on the unmodified tree — no new failures from this change.
* test(daemon): refresh golden matrix snapshot for upstream memory prompt hardening
Rebase onto main picked up #4913, which reworded the memory
rule-proposal block (+230 chars in memory-bearing scenarios). Section
gating is unchanged — size-only refresh.
* feat(prompts): rewritten slim core charter behind OD_PROMPT_CORE=slim
The always-on doctrine layer (DISCOVERY_AND_PHILOSOPHY ~28K chars +
designer charter ~14K + three tail overrides that re-assert rules the
layered stack states in softer or contradictory forms) is rewritten as
ONE ~15.5K-char document: core-slim.ts. Same composed inputs drop from
65.7K to 36.0K chars (-45%); freeform non-deck runs from 57.7K to 28.9K.
Design rules of the rewrite:
- Every rule stated exactly once, under an explicit precedence ladder
(user request > active skill > design system > memory > charter).
- Contradictions resolved instead of stacked: one verification budget
(static pass + P0 checklist + craft scan + at most ONE render; the
'two passes is normal' re-score loop is gone), one turn-1 form
decision path (four skip conditions listed in one place, including
the memory task-brief replacement), Tweaks reconciled (iteration
surface on request, never demo controls in product files).
- Protocol markers are frozen API and survive verbatim: question-form
shapes/ids, pick_direction/brand_spec/reference_match branch values,
task-type routing options, data-od-id, EDITMODE markers, pinned
React/Babel/Motion tags, artifact handoff shapes.
- Emphasis quota: no IMPORTANT/CRITICAL inflation; imperatives carry
the weight.
Rollout: ComposeInput.promptCoreVariant ('classic' default | 'slim'),
daemon flips via OD_PROMPT_CORE=slim — zero behavior change until set,
A/B-able per daemon. Ask mode keeps the clarifying-questions tail (it
composes no core charter). Guards in tests/prompts/core-slim.test.ts:
a 16KB byte budget that fails any silent regrowth, frozen-marker
assertions, handoff profile switch, and classic-parity checks; matrix
snapshot gains slim scenarios.
Not yet covered (follow-ups): the packages/contracts BYOK composer
still ships only the classic stack; instruction-following A/B against
classic is the sign-off gate before changing the default.
* feat(prompts): shrink the slim core to an 8KB budget by evicting what a system prompt shouldn't carry
The 15.5K v1 slim charter still carried content that has no claim to an
always-on seat. v2 evicts it by category:
- Already owned elsewhere: the od-default task-type router form ships in
plugins/_official/scenarios/od-default/SKILL.md and reaches the prompt
as '## Active skill'; the charter now just defers to skill-owned
turn-1 forms. An ownership test pins the form to the skill file.
- Conditional-path content: per-platform delivery contracts (breakpoint
matrix, per-target files, native chrome) move to
PLATFORM_CONTRACTS_BLOCK, injected only when the project declares a
platform or multiple targets. Deck rules were already duplicated by
the deck-gated directive - dropped from the charter entirely.
- Model-competence content: PDF extraction how-tos, attached-image
explanations, JSON syntax reminders - deleted.
- Recital: the default discovery form example keeps only the brand
question verbatim (its pick_direction/brand_spec/reference_match
values are the one protocol-matched part); the other six questions
become a one-line recipe. Option labels were always model-localized
per language, so exact English menus were never stable anyway.
- React pins keep versions (the actual bug fix: 18.3.1 pairing +
framer-motion React build) but drop the SRI hashes and script-tag
boilerplate - reviewers should weigh the integrity-attribute loss.
Charter now renders at 8,187 bytes (budget test tightened 16KB -> 8KB).
Composed prompt for the common design path: 65.7K classic -> 29.6K slim
(-55%); freeform non-deck: 57.7K -> 21.5K (-63%).
* perf(prompts): evict the remaining always-on payloads from the slim stack
Follow-up to the 8KB charter: the composed slim prompt still carried
~13K of non-charter payload. Four evictions, all slim-only (classic
stays byte-stable for the A/B):
- Project metadata becomes a fact sheet ('facts' style). The classic
block had grown seven doctrine rules plus a responsive contract and
cross-platform rule - prose owned by the slim charter's Craft section
and PLATFORM_CONTRACTS_BLOCK. facts keeps key-value fields, media
workflow data, and two compact delivery lines (screen files, product
depth). kind=other: 3.6K -> ~1.1K.
- Memory two-loop scaffolding compressed ~5.5K -> ~2.9K: identical
headings and od-card shapes (web parses the card types; the daemon
checks the verify-scorecard), repeated rationale prose cut.
- zh-CN locale override drops the worked quick-brief sample copy under
slim - it mirrored the classic form verbatim, which slim recipes
instead; the form contract already mandates localization. 2K -> 0.85K.
- MEDIA_DISPATCH_HINT gates on detectMediaIntentSignal (same
transcript-sticky pattern as the deck signal): most conversations
never mention media, and the hint returns for the rest of the session
the moment one does.
- Direction library becomes a pull layer: slim composes a ~1.3K
id+label index and the agent fetches the chosen direction's full
palette/posture spec via the new 'od tools directions --id <id>'
CLI (also --label / --json / bare list). One tool call on the
direction-pick path, which runs at most once per project, replaces
6.7K of always-on palette data. Classic keeps the inline library.
Composed slim sizes: freeform non-deck 21.5K -> 12.6K; design full
stack 29.6K -> 22.2K (fixture DS; media hint drops another 1.4K on
non-media conversations). Baseline classic: 57.7K / 65.7K.
* refactor(prompts): restructure the slim prompt as static-first layers for cache and hierarchy
Two structural defects in the slim composition, both flagged against
prompt best-practice guidance:
1. Heading hierarchy was inverted: the document opened with an H2
('## Security: prompt injection resistance') and the H1 charter
appeared six sections later. The security section now lives INSIDE
the charter as an H2 right after Precedence (single source moved to
core-slim.ts; the classic stack imports it for its unchanged
standalone-first position), so the composed document reads
identity-first with a coherent H1 > H2 tree.
2. Ordering was cache-hostile: conditional blocks (mode override,
locale, direction index, platform contracts) preceded the static
charter — the exact 'conditional prefix sections' anti-pattern from
the prompt-caching guidance, where every flag combination becomes a
distinct prefix and nothing is shared. Slim now composes in
variability tiers:
static charter (identical across all runs — shared cacheable
prefix) -> conversation-stable (mode, locale) -> project-stable
(direction index, frames, platform, memory, instructions, DS,
skill, metadata, MCP) -> turn-variable (maybe-deck and media-hint
signal blocks, deferred to after MCP so a mid-conversation signal
flip only invalidates the suffix) -> recency-pinned role guard.
The charter's Precedence section now states that a session-mode
directive appearing after it takes precedence, replacing the
positional 'read first' authority the old ordering relied on.
Classic composition is byte-untouched (A/B baseline); ask mode keeps
the classic head. Charter budget 8KB -> 9.25KB (absorbed the ~1KB
security section; composed totals unchanged: freeform 12.7K,
full-stack 22.4K). New layered-ordering test pins the tier sequence
with line-anchored markers; the matrix position invariant now asserts
the per-variant head.
* fix(prompts): resolve five structure/expression defects from the charter review
Findings from the senior-review pass, each with a concrete failure mode:
1. Turn-ordinal section names misfire mid-session. 'Turn 1/2/3+' made
the model treat 'now is not turn 1' as license to skip the fresh-
brief flow when a NEW artifact is requested at turn 8 — and,
conversely, an event-based fix alone would have re-asked questions
the session already answered. Sections are now event-named ('On a
fresh brief' / 'When the brand answer arrives' / 'Once direction is
locked') AND a session-inheritance rule makes the mid-session case
explicit: a fresh brief inherits the conversation's locked
direction/brand/audience, asks only genuinely new unknowns, and
builds directly when there are none — matching current production
behavior with zero extra rounds or cache cost.
2. The handoff rule — the single highest-cost-if-violated output
protocol (never emit <artifact> in filesystem runs) — was the only
rule block without a heading. Promoted to '## Handoff'.
3. The form example read backwards: it showed the LAST question
(brand) and described the earlier six in reverse ('preceded
in-form by'), the only place in the prompt requiring the model to
assemble structure in reverse. Now forward-order: output question
shown in full, brand question shown in full (its values are the
protocol-matched part), the middle questions listed as
insert-between recipes.
4. Dangling reference: Craft said 'single family only for
tech/utility' — a direction name defined only in the Direction
index, which is absent whenever a design system is active.
Reworded direction-independent.
5. direction-cards was dead vocabulary: listed as a legal control but
every mention forbade it. Its one legitimate path is now named —
only when the user explicitly asks to see direction options.
Charter budget 9.25KB -> 10KB: fix #3 cost ~0.7KB (restoring the full
output-question JSON), accepted deliberately — it also restores
few-shot density for weaker fleet models, and the review's own
conclusion was that the last byte-squeezing round had negative ROI.
* fix(prompts): identity-first head for slim ask mode
The last remaining hierarchy inversion: slim ask still opened with the
H2 security block before the H1 ask override. Ask now matches design
mode's structure — the ask override (the turn's whole charter) opens
the document and the security section reads as its first subsection.
Both blocks are static, so the swap is cache-neutral. Classic remains
byte-untouched.
* fix(prompts): repair five slim-vs-classic regressions from the second audit
Second senior review against the shipping classic stack surfaced two real
bugs and four wrongly-compressed classic behaviors in the slim variant:
- text_artifact/BYOK runs got the direction INDEX plus an instruction to
run the `od tools directions` CLI they do not have; classic inlined the
palettes. Slim now profile-switches: filesystem keeps the 1.3K pull
index, text_artifact gets the full inline library back (+1.35K tokens
on that path only; still ~68% below classic, and now under deepseek's
30KB Windows argv cap, which classic never was).
- API_MODE_OVERRIDE's literal scope ('every LATER instruction … is
overridden') inverted when slim moved the charter ahead of it: the
charter's TodoWrite/render-check instructions escaped the override.
Plain-stream slim runs now compose the override first again. Pure
reorder, zero bytes.
- PLATFORM_CONTRACTS_BLOCK gated only on project metadata, missing
freeform briefs that name a platform in text ('做个 iOS app 原型').
New detectPlatformIntentSignal (same generous EN/CJK shape as the
deck/media signals) ORs into the gate; server wires it.
- media-contract's 'explicit layer overrides' paragraph cross-referenced
the classic-only layer names; reworded layer-agnostic (classic +19B).
- Restored four classic rules the compression pass misfiled as
model-competence filler: never hot-link user-attached images by URL
(product constraint), skill/DS per-domain precedence clause, expressive
form-control guidance, and the modern-CSS encouragement line. Charter
budget 10,240 -> 10,752 with rationale in the test comment.
Classic bytes untouched except the shared media-contract rewording.
Golden matrix: gating unchanged; sizes only (classic +19, slim +537).
Pre-existing failures unrelated to this change and failing on the
unmodified baseline: tests/media/policy-routes.test.ts (7), Kimi
connection test (local CLI version mismatch).
* fix(prompts): defer signal-triggered platform contracts to the turn-variable suffix
Two follow-ups from the third structure audit:
- PLATFORM_CONTRACTS_BLOCK sat in the project-stable zone while its gate
now includes the turn-variable conversation-text signal. A mid-session
'make it an iOS app' would insert the block early and break the cached
prefix for every section after it (DS, skill, memory, metadata, MCP).
The gate is now split by trigger stability: metadata triggers keep the
early slot (fixed at project creation), signal-only triggers defer to
slimTurnVariableParts like the deck/media signal blocks. The
slimTurnVariableParts declaration hoists above the design section so
the gate can reach it; no byte or ordering change for any existing
gating combination.
- Slim ask mode on a plain stream composed CHAT -> injection -> API
override, inverting classic's authority order (API before CHAT, so
'overrides every rule below' covers the chat charter). The ask head
now leads with the API override on plain streams; the later push is
gated on !isSlimCore. Zero-byte reorder; the two overrides do not
conflict in content, this restores parity with the shipping order.
* fix(prompts): restore form-tailoring mandate and first-message form scope
The slim-vs-classic blind A/B eval (2026-07-04, 17 pairs, double-order
opus judging) surfaced two form regressions with converging judge
rationales:
- Form quality lost 12:1:4 to classic. Mechanism: classic's discovery
layer carries extensive per-brief form-tailoring guidance; slim
compressed it to the single word 'tailor'. Models shipped the default
recipe verbatim — app-platform checkboxes on landing-page briefs, the
fundraising ask/traction buried in one textarea placeholder. Restored
as an explicit mandate with concrete per-brief examples, a
plausible-targets-only rule for the platform options, and a
translate-the-labels note on the tone recipe.
- DS + detailed-brief projects skipped the turn-1 form 3/6 vs classic
1/6: the mid-session inheritance clause generalized to first
messages. Added the explicit scope limit: inheritance never applies
to a project's first message.
Charter budget 10,752 -> 11,264 with the eval citation in the test
comment. Golden matrix: sizes only.
* fix(prompts): template tokens in the seed must be replaced before handoff
The 40-task x 5-turn A/B eval (2026-07-05) found slim's remaining T2
quality gap is driven by catastrophic failures, not taste: 3 of 39
pairs shipped the live-artifact skill seed with unrendered {{mustache}}
tokens (classic did this once). Mechanism: slim compressed classic's
seed-handling guidance to 'copy the seed, paste layouts', losing the
explicit fill-with-real-content step.
- Read-before-write bullet now ends with: replace EVERY template token
with real content; a {{placeholder}} or empty section reaching the
user is a failed delivery. (Also covers the eval's 4 thin-content
failures.)
- Self-check static pass adds 'leftover template tokens' to its scan.
Charter 11,155B, within the existing 11,264 budget — no bump needed.
* fix(prompts): first build ships complete, no stub sections
Clean-scope T2 analysis of the 40-task eval (excluding the 10 tasks
confounded by the live-artifact skill protocol) still shows a first
build completeness gap: main 7.34 vs slim 6.10, driven by thin-content
deliveries (empty canvases, placeholder-looking blocks) on 4 of 29
pairs. The charter's 'show something visible early' line, uncushioned,
reads as license to hand off the early skeleton.
- Qualify it: '…but the turn ships the COMPLETE artifact: no stub
sections.'
- Self-check static pass adds 'empty or stub sections' to its scan.
11,215B, within the 11,264 budget.
* refactor(prompts): split the overloaded turn-1 form section by concern
The slim charter's '## On a fresh brief' H2 bundled six distinct
concerns under one heading — trigger, default action, mid-session
inheritance, skip conditions, form-shape tailoring, and the form JSON
contract — so a maintainer could not scan the outline to find any one
rule, and the cross-cutting form contract (valid on ANY turn) was buried
under a heading scoped to fresh briefs.
Behavior-equivalent restructure (every directive's wording preserved;
only headings added and the form contract's 'any turn' note moved from a
parenthetical to the section lead):
- ## Turn 1 — the discovery form (trigger + default action)
- ### When to skip or inherit the form (inheritance + skip conditions)
- ## Writing a `<question-form>` (cross-cutting: shape + tailoring + example + ordering)
- ### Form contract (JSON validity + type enum + localization)
The charter outline now reads as a per-concern document. Frozen protocol
markers (form JSON, brand values, type enum, allowCustom) unchanged.
Charter 11,242 -> 11,322B; budget raised to 12,288 for readability
headroom at the maintainer's direction (budget explicitly deprioritized
for this change). Golden snapshot regenerated; 113 prompt tests green.
* refactor(prompts): readability second pass + multi-turn DS/constraint adherence
Two changes, from a critical re-read plus production feedback.
A) Readability / logic second pass (behavior-equivalent, wording preserved):
- Heading style: the two remaining imperative-tail H2s became event
labels with the directive moved to the body lead ('## When the brand
answer arrives', '## Once direction is locked'), so the outline reads in
one consistent grammar. Dropping '…hand off' also fixes a heading that
promised handoff while the rules live in the next section.
- The self-check bullet's inline (1)(2)(3)(4) run-on became a four-item
sub-list — the least-scannable line is now the most scannable.
- The 70-word 'Read before you write' sentence split into shorter units;
'show early / ship complete' separated into its own bullet so the two
ideas stop reading as contradictory.
- Precedence: skill and DS collapsed into one rank split by domain (was
numbered 2 vs 3, contradicting the 'each highest in its own domain'
clause) — removes the only real logical seam in the ladder.
B) Multi-turn edit adherence (new '## On an edit or tweak' section):
Production feedback reports the design system and explicit user
constraints frequently drift during multi-turn edits. The charter was
turn-1/first-build heavy and had no standing edit-mode invariant. Added,
in the lifecycle between build and handoff:
- an edit touches ONLY what the user named; untouched sections/values
stay as they were; re-read the file and edit in place.
- the design system binds on EVERY turn, not just first build — no
drift, no raw hex, no palette re-pick because this turn was about
something else.
- every hard constraint stated this session persists across later turns
until the user relaxes it; a new request adds to constraints, never
silently resets them.
Charter 11,322 -> 12,029B, within the 12,288 budget (no raise). New
frozen assertion pins the adherence invariants against future
compression. 114 prompt tests + guard + typecheck green; golden snapshot
regenerated.
* refactor(prompts): two-tier charter — lifecycle spine, grouped pillars, precedence precision
From a senior word-by-word re-read. The charter was 13 flat H2s spanning
three conceptual tiers (foundations / lifecycle / reference) with no
visible spine, and the precedence wording could invert authority.
Structure (behavior-equivalent, rule wording preserved):
- 13 flat H2 -> 5 H2: two foundations (Precedence, Security) + three
pillars, each grouping its H3s —
## Discovery — ask before you build (Turn 1, skip/inherit, writing, contract)
## Delivery — brand → build → iterate (brand answer, build, edit, handoff)
## Craft & contracts (craft, technical, conduct)
The delivery lifecycle is now one connected, ordered spine — 'Editing
an existing artifact' reads as a named phase of it, which should help
the multi-turn drift the edit-adherence rules target.
Precision fixes:
- Precedence: 'On conflict, higher wins: 1…2…3…4' was ambiguous (which
number is higher?) — reworded to an explicit list, 'the one higher on
this list wins — the user's request is the highest authority, this
charter the lowest', and the trailing pronoun tightened to 'overrides
it wherever the two conflict'.
- 'no tool calls or file reads first' -> 'before it'; 'Resolve the
source' -> 'Resolve the brand source'; 'restyle the whole thing' ->
'restyle beyond the request'.
- Trimmed one of three localization restatements (kept the authoritative
one in Form contract, now naming labels/options/placeholders) and the
'however complete the brief reads' duplicate.
Handoff/Craft/Technical/Conduct headings demote to H3 under their
pillars (local constants, not shared with classic). Charter 12,029 ->
12,294B; budget 12,288 -> 13,312. Ordering/adherence test anchors and
golden snapshot updated. 114 tests + guard + typecheck green.
* fix(prompts): make edit-adherence forceful — do exactly what was asked, verify it landed
Production feedback and maintainer review: the edit section addressed
only scope (don't over-change) and persistence (DS/constraints), but not
the core instruction-following failure — 'the user asked for A and the
result isn't A'. The whole section was defensive; the positive imperative
that the requested change must actually happen, completely, was missing.
Strengthened '### Editing an existing artifact':
- Leads with the imperative: the delivered file must actually be A — do
exactly what was asked, in full, in every place it applies, with
complete-vs-partial examples ('dark green' = every element, not one).
- Forbids reinterpreting, 'improving on', partially applying, or
substituting own taste for the user's literal words — ties to
Precedence #1 (user's request is highest authority).
- New 'Verify before you hand off' bullet: open the file, confirm the
change is actually present and complete and no in-force constraint
broke; never report a change you did not make (the claim-vs-reality
failure).
- Kept the scope / DS-binding / constraint-persistence bullets.
Charter 12,294 -> 13,122B, within the 13,312 budget. Frozen assertion
updated to pin the positive imperative and the verify bullet.
* fix(prompts): a later explicit request overrides a conflicting earlier constraint
Edge case raised in review: turn 2 'fix the color to blue, don't change
it', turn 4 'change everything to yellow'. Correct behavior is turn 4
wins (the user is changing their own mind; yellow becomes the new
standing constraint), which Precedence #1 + 'persist until the user
relaxes it' already imply — but the old bullet also said 'a new request
ADDS to those constraints', which a literal model could read as
additive-only and stall on the turn-2 'don't touch it'.
Rewrote the constraint-persistence bullet to make the override explicit:
constraints carry forward, only the user can lift or change one, and a
later explicit request overrides a conflicting earlier constraint — with
the blue->yellow turns as the in-prompt example. The anti-silent-drop
guard (model must never drop a standing constraint on its own) is kept.
Charter 13,122 -> 13,412B; budget 13,312 -> 14,336.
* fix(prompts): make the plan step agent-agnostic — TodoWrite is Claude-only
Open Design drives many local code agents; the real session mix is ~65%
non-Claude (codex, opencode, gemini, ACP family, …). The slim charter's
plan step hardcoded 'first tool call is TodoWrite' + in_progress/completed
— a Claude Code tool those agents don't have. For ~2/3 of traffic that
instruction is dead: the agent either skips planning (losing the exact
lever that helps multi-turn adherence) or hallucinates a tool it lacks.
Everything else in the slim charter was already agent-agnostic (render
checks and direction pulls go through the shell OD CLI wrapper; protocol
markup is assistant text), so TodoWrite was the one hardcoding.
- Charter plan step → generic: 'lay out a short, updatable plan; if your
runtime has a structured plan/todo/task tool, use it, else a numbered
list; never call a tool you don't have.'
- Composer injects a concrete note ('Your plan tool is TodoWrite; the
host renders it as a live Todos card; mark in_progress/completed') only
for Claude-family runs (streamFormat claude-stream-json: claude,
codebuddy, amp) — the only agents with TodoWrite and the host's live
Todos card. Agent-specifics live in the composer, portable doctrine in
the charter.
- API_MODE_OVERRIDE reframed from 'TodoWrite/Read/… are unavailable' to
'any tool call — TodoWrite/…/or whatever your runtime exposes — will
not execute'. Keeps the specific names (issue #313 anti-pseudo-tool,
test-pinned) while covering non-Claude runtimes.
Two frozen tests pin: charter has no TodoWrite + generic wording;
Claude-family gets the note, json-event-stream doesn't. 116 tests +
guard + typecheck green. Charter 13412 to 13543B (budget 14336).
* feat(prompts,live-artifacts): render one-level repeats, tighten slim charter craft guards
- live-artifacts/render: implement the documented `data-od-repeat="item in data.path"`
one-level repeat directive (specified in the schema but never rendered), with
loop-scoped `{{item.*}}` bindings, single-pass expansion so data values are never
re-interpolated, and explicit rejection of nested repeats / non-array sources.
- live-artifact SKILL.md: state the html_template_v1 binding contract in the workflow
(flat data.* scalars + data-od-repeat lists; no hand-loops, no bare loop vars) so
templates stay within the renderer's capability.
- core-slim charter: "replace every template token" now yields to a skill's
template-plus-data protocol; add an objective Layout-integrity craft rule (no
overlap, no clipping, oversized display type must fit its column, charts use fills
not outlines) and name those failure modes in the self-check.
* feat(prompts): add agent-agnostic production-value craft rule to slim charter
Visual-first pages regressed on slim: hero images were hand-drawn CSS boxes
instead of generated art (P1), and controls read flat/greyscale (P5). The slim
charter had dropped all of main's imagery + visual-system guidance.
Add one "Production value — feel shipped, not greyscale" craft rule: generate a
real image via the Open Design media tool (referenced through the injected
`"$OD_NODE_BIN" "$OD_BIN"` wrapper, so it is runtime-agnostic — not tied to any
one code agent) when a hero/product shot would carry the page; ship a real
product palette, colored interaction states, and elevated primary controls.
Bump SLIM_CORE_BYTE_BUDGET 14_336 -> 15_360 to seat this load-bearing guidance.
* feat(prompts): generalize the production-value imagery rule beyond hero shots
40-task eval + user review (C3 tea gift-box, P1) showed slim under-generates real
imagery on visual-first work, defaulting to hand-drawn schematic graphics. Reframe
the rule from a narrow "hero/product shot" trigger to a general default: whenever a
real picture would lift the artifact (product, place, food, person, hero, texture),
generate it via the media tool; drop to a diagram/UI mock only when that genuinely
serves the content better. Still agent-agnostic (media tool via the injected
"$OD_NODE_BIN" "$OD_BIN" wrapper).
* fix(prompts): let the production-value rule use the run's own image generation
Hard-pointing imagery at `od media generate` only works when a daemon spawned the
agent (it injects OD_PROJECT_ID); a standalone agent (eval harness, external
runtime) can't reach it, so slim silently fell back to hand-drawn placeholders
while codex-run peers used their native imagegen. Broaden the rule: generate through
whatever image generation the run offers — the Open Design media tool when wired up,
otherwise the runtime's own native image generation. Verified: C3 slim now emits a
real generated product photo instead of a schematic box.
* test(daemon): drop connected-external-mcp from the golden matrix
Upstream moved the connected-external-MCP directive out of
composeSystemPrompt into the per-turn slice (live OAuth token state must
stay out of the cached stable prefix), so it is no longer a compose
input or a gateable section.
* chore(prompts): default to the slim charter on the validation branch
VALIDATION-ONLY commit for feat/system-prompt: packaged beta builds must
exercise the rewritten slim charter, and the packaged sidecar env
allowlist does not forward OD_PROMPT_CORE, so the default flips to slim
here. OD_PROMPT_CORE=classic restores the classic stack. Do not carry
this default into main.
* perf(prompts): batch slim tool work, with quality guards restored (#5555)
* perf(prompts): batch slim tool work
* fix(prompts): restore seed-copy rule and unconditional own-browser ban
The tool-economy pass (
|
||
|
|
da7c4ae051 |
fix(web): rank Community "Newest" by shipped publishedAt, not local install timestamps (#5597)
* fix(web): rank Community "Newest" by shipped publishedAt, not local install timestamps
The Community gallery Newest toggle sorted by the installed-record
updatedAt/installedAt. Those are stamped when a machine seeds its own
database, so a fresh install (or an upgrade that re-stamps the catalog)
writes the whole bundled catalog milliseconds apart in folder-walk
order — Newest showed reverse walk order (roughly reverse-alphabetical),
unrelated to publication recency.
Root-cause fix: bundled templates now ship a real publication date.
- packages/contracts: add optional manifest field publishedAt (ISO 8601).
- apps/web sortByNewest: freshness = publishedAt when parseable, else
updatedAt (right signal for user-installed plugins); tie-breaks and
stability unchanged.
- plugins/_official: backfill publishedAt into all 460 bundled manifests
from each folder's first-appearance commit date in upstream git
history.
- e2e: repository-resource guard requiring every bundled manifest to
declare a parseable publishedAt, so the signal cannot silently erode.
- docs: field reference entries in plugins-spec (en + zh-CN).
Issue: https://plane.powerformer.net/open-design/projects/49832a02-3158-4faf-bf2f-d0e39c40c7e6/issues/ca0778af-97f5-4fc0-bc63-739280904979
Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)
* worker: 模板用最新筛选,筛选出来的不是最新的
Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)
* fix(web): keep shipped appeal order inside same-publishedAt batches
Review follow-up (#5597, nettee): after the freshness tie on an equal
publishedAt, the comparator still consulted local updatedAt/installedAt,
which a fresh install stamps in folder-walk order — so every
same-publication batch (largest: 322 manifests on one catalog date)
re-sorted per machine instead of keeping the shipped visual-appeal
ranking. Same-publishedAt records now preserve their incoming position;
local timestamps break ties only when at least one side has no usable
publishedAt. Adds the requested regression spec pinning
same-publishedAt / different-updatedAt records.
Generated-By: looper 0.0.0-dev (runner=worker, agent=claude-code)
* fix(web): gate publishedAt freshness to bundled records; untrack oversized looper attachment
Review follow-up (#5597, nettee round 2): publishedAt was overriding
updatedAt for every visible plugin, so a user-installed github/local/
marketplace plugin carrying an old manifest publishedAt would be buried
behind bundled templates despite a newer local install. publishedAtMs
now returns null for non-bundled records — "Newest" means install
recency for user installs, catalog publication for bundled ones. Adds
the requested regression (non-bundled, old publishedAt, newer
updatedAt) and clarifies the field docs (en + zh-CN).
CI repair: commit
|
||
|
|
bc6a246c65 |
feat(slides): enhance deck project experience (#5083)
* feat(deck): enhance slide deck functionality with speaker notes and navigation improvements - Added a switch for including speaker notes in slide decks, defaulting to true. - Updated keyboard navigation to include 'R' for resetting to the first slide. - Implemented click navigation for half-slide transitions. - Enhanced the deck framework to support hidden programmatic prev/next controls. - Improved handling of file inputs in question forms to support file submissions. This update aims to improve user experience in creating and presenting slide decks, ensuring better accessibility and functionality. * feat(artifacts): enforce semantic naming for user-facing deliverables - Updated guidelines to require semantic filenames derived from user briefs for new artifacts, moving away from defaulting to `index.html`. - Enhanced documentation to clarify naming conventions for HTML files, emphasizing the use of descriptive names like `investor-pitch-deck.html`. - Adjusted prompts and hints across the system to reflect these changes, ensuring consistency in user-facing outputs. - Improved test coverage to validate the new naming conventions and ensure proper implementation in various contexts. This update aims to enhance clarity and usability in project file management, promoting better organization and user experience. * feat(file-viewer): enhance speaker notes display and improve file workspace functionality - Updated the speaker notes section to include a styled placeholder for empty notes, improving user experience. - Changed the icon in the file workspace from "slides" to "panel-left" for better clarity. - Introduced new sub-category filtering options in the file workspace, enhancing organization and navigation. - Improved styling for the page creator search input and added visual feedback for loading states. These changes aim to enhance usability and visual consistency across the file viewer and workspace components. * test(web): align workspace tests with pages switcher * test(e2e): open design files through pages menu * fix(deck): keep source mode reachable * fix(workspace): restore uploaded file tabs * feat(deck-thumbnail): implement virtualized thumbnail rail for improved performance - Introduced a new `DeckThumbnailRail` component to optimize the rendering of deck thumbnails, reducing memory usage and improving load times. - Enhanced the `FileViewer` to integrate the new thumbnail rail, allowing for lazy loading of thumbnails based on viewport visibility. - Added tests for the `DeckThumbnailRail` to ensure correct functionality and caching behavior. - Updated styles for better visual consistency and performance during thumbnail rendering. These changes aim to enhance user experience by providing a smoother and more efficient way to navigate through deck slides. * feat(deck): enhance deck rendering with thumbnail support and keyboard shortcuts - Integrated `DeckSlideThumbnail` for rendering individual slides in a shadow root, improving performance and reducing main-thread load. - Updated `DeckThumbnailRail` to utilize the new thumbnail component, allowing for efficient slide navigation. - Implemented keyboard shortcuts for deck navigation, enhancing user experience during presentations. - Added tests for `buildDeckRenderInput` to ensure proper functionality of the deck stage fallback. - Improved styling for loading states in the viewer, providing a smoother visual experience. These changes aim to optimize the deck viewing experience by reducing resource consumption and enhancing interactivity. * feat(deck): improve thumbnail loading and speaker notes editing experience - Refactored `DeckSlideThumbnail` to enhance loading states with a new shimmer effect, improving visual feedback during thumbnail rendering. - Updated `DeckThumbnailRail` to manage loading states for thumbnails, ensuring a smoother user experience. - Simplified the speaker notes editing interface by removing the toggle switch, allowing direct editing from the notes body. - Enhanced accessibility by adding roles and focus states to speaker notes elements. - Added tests to verify the new loading states and speaker notes functionality. These changes aim to optimize the user experience in deck navigation and speaker notes management, providing a more intuitive and responsive interface. * feat(file-viewer): enhance version export functionality and speaker notes interaction - Introduced new export options for file versions, including PDF and image formats, improving the ability to download and share content. - Implemented a streamlined process for exporting version content, with progress indicators and error handling for a better user experience. - Enhanced speaker notes editing by refining event handling to prevent unintended focus shifts, ensuring a smoother editing experience. - Updated styles for improved visual consistency in the file version download interface. - Added tests to verify the functionality of version exports and speaker notes interactions. These changes aim to optimize the file viewer's usability and enhance the overall experience when managing and exporting project files. * fix(web): polish export menus and creator filters * fix(file-viewer): fall back to preview exports * test(file-viewer): cover version export fallbacks * test(file-viewer): assert loading skeleton by role * fix(file-viewer): restore html source mode affordance * fix(file-viewer): capture full version fallback snapshots * docs: trim slides handoff eof * test(exports): cover full preview snapshot requests * test(file-viewer): account for snapshot options arg * refactor(file-viewer, file-workspace): streamline export functions and enhance page creator dialog visibility * test(file-workspace): enhance slide template creation and mock plugin responses * feat(export): add support for versioned exports and enhance HTML export functionality * feat(export): implement versioned export support across multiple formats and enhance related tests * feat(file-viewer): enhance manual edit functionality with commit sequence tracking and add test for inline text session saving * style(speaker-notes): update filmstrip and thumb-frame styles for improved responsiveness and add corresponding tests * feat(file-viewer): enhance comment composer functionality with portal metrics and improve draw toolbar layout for mobile views * feat(analytics): track slide deck viewing experience Add analytics for the new deck/slides experience introduced in this PR: the deck viewer surface, in-deck slide navigation, thumbnail rail, and speaker-notes authoring. Presentation entry stays on the existing present_popover click to avoid double-counting. - contracts: DeckViewerSurfaceViewProps (surface_view), DeckViewerClickProps (ui_click), SpeakerNotesSaveResultProps (new speaker_notes_save_result event), wired into the event unions. - web: track* wrappers + fire helpers in FileViewer — deck_viewer surface_view on deck mount, slide_prev/next/reset, thumbnail_select, thumbnail_rail_toggle (expand/collapse), speaker_notes_edit, and speaker_notes_save_result (preview + presenter surfaces). - tests: deck analytics suite asserting the emitted (event, props) pairs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(file-viewer, file-workspace): enhance export toast functionality and improve localization for page creation * feat(home-view, plugins-home-section, agent-skill): update default facet preference, enhance category selection handling, and improve localization support - Set `preferDefaultFacet` to true in HomeView component for better user experience. - Introduced `handlePickCategory` function in PluginsHomeSection to manage category selection based on card layout visibility. - Updated PRIMARY_CATEGORIES to reflect the new order and added localization for titles and descriptions in adaptAgentSkill. - Enhanced tests to verify the correct handling of display copy and tags from SKILL frontmatter. * feat(plugins-home, file-workspace): introduce commercial category labels and enhance deck handling - Added a new module for resolving and localizing commercial category labels for plugins. - Updated the FileWorkspace and PluginCard components to display the commercial category label on deck cards. - Enhanced the PageCreatorPresetFrame to adjust frame classes based on deck presets. - Refactored subcategory handling in facets to align with the new commercial category taxonomy. - Improved localization support for new category labels across multiple languages. * feat(deck-preview): implement deck preview scaling and enhance home hero layout - Introduced `useDeckPreviewScale` hook to manage scaling of deck previews within a fixed 1280×720 logical viewport, ensuring proportional rendering across various templates. - Updated `FileWorkspace`, `HomeHero`, and `PluginCard` components to utilize the new scaling functionality for improved visual consistency. - Enhanced the layout of the home hero section to accommodate new subtype chips and descriptions, including a "More" dropdown for overflow handling. - Improved localization support for new UI elements across multiple languages. * fix(PreviewModal): clarify sidebar prop documentation and update test description - Updated the documentation for the `PreviewSidebar` interface to specify that the sidebar's stage-edge handles are not shown when the sidebar prop is absent. - Modified the test suite description for `PreviewModal` to be more concise and relevant. * test(e2e): select prototype visual card --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
323246a64c |
Website Clone: first-party Home entry, fidelity, real-clone example cards + tracking (#5178)
* Add Website Clone home entry with bundled web-clone skill and root-relative asset preview fix
* Retrigger CI
* Open the site entry after website-clone turns
* Harden web-clone skill asset and color fidelity
Recon now scrolls the full page and captures @font-face rules, real font/image
resource URLs, computed section palette, and resolved root variables. Asset
harvest is rebuilt on the browser network stack so cross-origin CDN images,
fonts, and media (hotlink-protected included) all land locally, with a
self-hosted fonts.css and an originalUrl→localPath manifest. Clone audit gains
--recon --strict fidelity gates (fonts self-hosted, images downloaded, key
section colors exact) that exit 2 on violations, and SKILL.md makes all three
a mandatory delivery gate.
* Default web-clone mode to faithful reproduction when unconfirmed
A real nike.com run showed the agent silently downgrading to visual-homage
mode (placeholder brand, typography blocks instead of photography, approximated
palette) because the user skipped the turn-1 confirmations and the site was a
copyright-heavy commercial SPA. Fidelity is the point of this scenario: default
to faithful reproduction, land real assets first, record trademark/copyright
replacements as a pre-deploy checklist for the user to decide in Step 6, and
never skip script recon just because the target looks bot-sensitive.
* Streamline web-clone runs: skip discovery with URL, exempt brand constraints, actionable playwright setup
Three run-path optimizations for the Website Clone scenario:
1. POST /api/projects derives metadata.skipDiscoveryBrief for web-clone
projects whose pending prompt already carries the target URL — the URL is
the brief, so the turn-1 question form no longer stalls the run (an
explicit client flag still wins). Covered by
project-create-web-clone-discovery.test.ts.
2. Prompt composition skips the design-system authoritative block and craft
rules for intent=web-clone runs: the fidelity target is the original
site, not the project brand; brand application belongs to the skill's
Step 6 replacement phase.
3. The plugin's playwright-loader now also resolves from the process cwd
(so 'npm i -D playwright' in the project root works for scripts staged
under .od-skills/) and fails with exact fix commands; SKILL.md documents
the staged-path resolution and forbids downgrading to eyeballing because
of missing deps.
* Swap the copyright guardrail for faithful reproduction on web-clone runs
The official designer prompt's 'don't recreate copyrighted designs — help
the user build something original instead' bullet made web-clone agents
silently rebrand clones (Nike → placeholder brand, original SVGs instead of
real photography) even after the skill mandated faithful defaults: a system
prompt guardrail outranks skill blocks. For intent=web-clone runs the bullet
is swapped for a faithful-reproduction rule that routes trademark/copyright
caution through a pre-deploy replacement checklist (NOTES.md) the user owns.
Prompt tests guard both directions of the substitution.
Also: recon now captures scroll-feel signals (scroll-behavior, scroll-snap
rule count, sticky/fixed census) and SKILL.md makes matching the original's
scroll behavior (smooth-scroll libs, snap, sticky) a fidelity requirement.
* Extract web-clone into a shared global skill referenced by ref
The Website Clone workflow (SKILL.md + 14 recon/harvest/audit scripts +
references) moves from the example-web-clone plugin into the global skill
registry at skills/web-clone/. example-web-clone now references it via
od.context.skills:[{ref:'web-clone'}] instead of shipping its own copy, so the
upcoming per-site clone example plugins can all share one skill rather than
each duplicating a 16KB SKILL.md and its scripts.
Pinned-plugin skill resolution (server.ts) previously only loaded a plugin's
LOCAL ./SKILL.md; a {ref} skill loaded nothing, so the body never entered the
prompt and the scripts never staged. It now falls back to resolving the ref
against the global registry, loading the body and registering the skill dir for
cwd staging. Verified end-to-end in a live run: skills/web-clone stages to
.od-skills/web-clone-<hash>/ with SKILL.md + all scripts.
guard.ts residual-JS allowlist follows the scripts to their new home; a
structural test locks the manifest<->skill contract.
* Add 7 Website Clone example-prompt cards for the Home clone rail
nexu.io, open-design.ai, anthropic.com, vercel.com, resend.com, linear.app,
raycast.com — each a thin example plugin that references the shared web-clone
global skill (od.context.skills:[{ref:'web-clone'}]) so none duplicate the
workflow. Each seeds the composer with a faithful-clone prompt for its URL and
ships a self-contained example.html preview built from a real recon capture of
the target homepage, so the gallery card shows what the card clones. They
surface under the Website clone chip's example-prompt rail (verified in a live
desktop run) and inherit the chip's intent:'web-clone' metadata, so clicking one
runs through the full fidelity path (skip discovery, brand exemption, faithful
reproduction, script recon/harvest/audit).
* Polish clone example-card previews with a framed hero capture
The first pass inlined a downscaled full-page screenshot cropped mid-content —
it read as a raw screenshot dump. Each preview is now a crisp above-the-fold
hero capture (1440x900 DPR2, 16:10) presented inside a browser-window chrome
(traffic lights + host URL pill) on a brand-tinted gradient, so the gallery
card reads as an intentional site preview. Verified by rendering the previews
headless.
* Cache the plugin list so Home remounts don't grey the create rail
HomeView re-fetched + parsed the large /api/plugins payload on every remount,
leaving the create-rail chips disabled for 1-2s each time. A module-level cache
(listPluginsFresh, 10s TTL) serves warm mounts without the network round trip so
pluginsLoading clears within a frame; the first render stays cheap (empty list)
to keep the click off the critical path. Also hide the base example-web-clone
plugin from the example rail (the per-site clone-* cards are the real examples).
* Ship real self-contained clones as example-card previews + align seed prompt
Each clone-* example.html is now a real, self-contained reproduction of its
target site (inlined CSS/fonts/images via document.styleSheets serialization so
CSS-in-JS/Next.js SPAs like Vercel/Raycast capture correctly, oversized icon
sprites dropped, rasters downscaled to stay under the 5MB preview cap, plus a
scroll-reveal motion layer). Preview renders the real HTML; Remix copies it into
a project as index.html. Manifests reuse the base web-clone useCase.query with a
{{targetUrl}} default per site, so picking a card seeds the same preset prompt
with the URL filled in instead of the marketing description.
* Shrink clone example previews ~33% (dedup + drop EOT + WebP)
Three lossless-to-near-lossless passes on the self-contained clones:
- Dedup repeated data-URIs (same image used in <img> + css url() N times): store
each once as a :root CSS var, point url() at var(), hydrate img[src] from the
var via a tiny script. Resend alone shed 1.8MB.
- Drop leftover EOT/fontobject font data-URIs (IE-only, redundant with woff2).
- Re-encode inlined raster images to WebP (~50% smaller than JPEG at equivalent
quality) via cwebp q72.
Total across the 7 cards: ~23MB → ~15.5MB, every card now under 3MB (was up to
5MB). Image hydration + fidelity verified by headless render.
* Lead create rail with Website clone; seed example cards with just the URL
- Move 'web-clone' to the front of CREATE_RAIL_ORDER so Website clone is the
first create-rail card, ahead of Slides (deck).
- Website-clone example cards (Clone Nexu, Clone Vercel, …) now seed the
composer with the same short 'clone this site: <url>' scaffold the chip uses
(localized webClonePromptSeed prefix + the card's targetUrl), e.g.
'Website URL to clone: https://nexu.io', instead of the multi-paragraph
build spec. Picking the chip with an empty composer already seeds the bare
prefix for the user to paste a URL after.
- Fix a test-only regression from the Home plugin-list cache: the module-level
visible-plugins cache leaked a case's mocked /api/plugins payload into later
cases via listPluginsFresh, greying the rail / stranding scenarios on
'Template None'. Add resetPluginsCache() and clear it in a global afterEach.
* Track web-clone example-card picks (example_prompt / example_open_project)
The Website-clone example cards (Clone Nexu / Vercel / …) had no analytics on
pick or remix, so the site-clone funnel could not be broken down per example.
Wire the two clicks the contracts already type (埋点文档 row 116):
- useExamplePlugin → ui_click area=chat_composer element=example_prompt
- duplicateExamplePlugin (Remix) → element=example_open_project
Both carry chip_id (web-clone) + plugin_id (example-clone-<site>) + plugin_type
for per-site breakdown. The created project's own project_kind=web_clone (already
derived from metadata.intent via projectKindToTracking) still rides
project_create_result / run_created, so 'how many projects are website clones' is
answerable without extra work. No contracts change — the element enum and the
web_clone project_kind already existed. Adds a behavioral test asserting both
events fire with the right triplet + attribution.
* Mirror web-clone copyright-guardrail swap into contracts/BYOK prompt
PR #5178 blocking review (nettee/looper): the daemon prompt special-cases
intent='web-clone' (faithful-reproduction rule) but the contracts prompt stack —
which apps/web uses for API/BYOK runs — imported OFFICIAL_DESIGNER_PROMPT directly
and never routed web-clone, so BYOK website-clone runs kept the original 'build
something original' guardrail. Daemon and BYOK now behave identically:
- contracts/prompts/official-system.ts: add COPYRIGHT_GUARDRAIL_BULLET,
WEB_CLONE_COPYRIGHT_GUARDRAIL_BULLET, renderOfficialDesignerPrompt (mirrors the
daemon renderer; contracts base has no execution placeholders so it only swaps
the bullet).
- contracts/prompts/system.ts: composeSystemPrompt routes the charter through
renderOfficialDesignerPrompt({ webCloneFidelity: metadata.intent==='web-clone' }).
- Add system-prompt-web-clone.test.ts covering both modes + the byte-identical
bullet guard.
* Complete web-clone BYOK prompt parity + rebase relative JS asset refs
Two remaining blocking issues from PR #5178 looper re-review:
1. contracts composeSystemPrompt still appended the active-design-system
'authoritative' block + visual-direction override unconditionally, while the
daemon suppresses both for intent==='web-clone'. A BYOK web-clone run with an
active design system was still told the design system wins, fighting faithful
reproduction. Gate both sections behind !isWebCloneRun; add contracts tests
asserting web-clone BYOK prompts drop the design-system guidance.
2. rewriteInlinedScriptAssetRefs only handled root-relative literals. When
js/app.js is inlined into the HTML entry, a sibling lookup like
fetch('./data.json') / new Worker('./worker.js') / import('./chunk.js')
resolved against the HTML root instead of js/. Take the source script path and
rebase confirmed relative refs against it (mirrors the CSS pass), membership-
confirmed; add unit cases for ./sibling, ../parent, and escaping/missing.
* Website-clone examples: plain text prompt cards, drop embedded HTML + Remix
The 7 site example cards embedded a full self-contained clone of each target site
(anthropic.com, vercel.com, …) as example.html and offered a one-click Remix that
copied that markup into a project. Shipping verbatim copies of other companies'
sites is an IP risk, so replace them with plain text prompt cards:
- Delete plugins/_official/examples/clone-* (7 dirs, incl. the example.html
reproductions and the Remix-enabling preview.entry).
- Add a 'web-clone' entry to HOME_PROMPT_EXAMPLES (en + zh-CN, others fall back to
en): 7 text cards that fill the composer with 'Website URL to clone: <url>'.
With the site plugins gone, the web-clone chip's preset rail is empty so these
static text cards render instead. Clicking one fills the URL prompt and (via
the existing usePromptExample) still fires ui_click element=example_prompt
chip_id=web-clone — no plugin_id / no Remix / no example_open_project.
- Remove the now-dead webCloneCardTargetUrl seed override; refresh stale comments.
- Rewrite HomeView.web-clone-tracking test for the text-card path (asserts text
cards render, no plugin-preset / no remix affordance, and the pick still tracks).
The base example-web-clone skill + web-clone run behavior (intent, fidelity
prompt, discovery skip) are unchanged.
* Give web-clone example cards a site logo + domain, not raw prompt text
The 7 Website-clone examples rendered as near-identical white boxes each showing
'Website URL to clone: https://<site>' — visually flat and hard to scan. Render
them as a logo gallery instead: each card shows the site's own favicon (resolved
at render time via a public favicon service — no third-party brand assets are
bundled) in a rounded tile above the bare domain (nexu.io, vercel.com, …). A
blocked/failed icon fetch falls back to a lettered monogram tile. Click behavior
is unchanged: the full 'Website URL to clone: <url>' prompt is still what fills
the composer and fires ui_click element=example_prompt. Non-URL prompt examples
(other chips) keep the plain text card.
* Web-clone examples: keep only open-design, add kimi
Legal review flagged brand-copy risk in the example rail. Drop the
nexu / anthropic / vercel / resend / linear / raycast site prompts and
keep just open-design.ai plus kimi.com (official Kimi partnership).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
e02a36f51c |
feat(examples): add Open Design homepage — interactive 3D showcase (#5355)
* feat(examples): add Open Design homepage — interactive 3D showcase Adds the live open-design.ai homepage as a first-party, self-contained example: an interactive React Three Fiber / Next.js hero with a real-time 3D "Open Design" wordmark, sticker collage, variable fonts, cursor parallax, and scroll-driven motion. Renders in the sandboxed powered preview. Made repo- and preview-safe without touching the app's runtime: - 3D geometry Draco-compressed (KHR_draco_mesh_compression): hero wordmark 4.4MB -> 300KB, cnt 2.2MB -> 548KB, decoded by the bundled DRACOLoader. Visually identical (verified). - Work/sticker imagery converted to LOSSLESS WebP: pixel-identical to the source PNGs (alpha + visible-pixel diff = 0), 12.2MB -> 7.1MB. - Every file now < 1MB, so the template is fully self-contained in-repo with no external asset host. - Path-portable so it renders from the nested preview subpath, not just the site root: absolute asset paths made relative; font/bgm URLs derived from document.baseURI instead of window.location.origin; App-Router createHrefFromUrl pinned to "/" and history push/replaceState URL neutralized so hydration matches and baseURI stays put (fixes the React #418 + broken relative-asset resolution seen when serving a Next RSC bundle from a subpath). Verified end-to-end from a deep subpath: 3 Draco models + 41 WebP + 3 fonts load, zero 404s, zero console errors, no hydration error, interactive (scroll/cursor). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(examples): list the full asset set in open-design homepage manifest Addresses review: od.context.assets previously listed only the design assets (models, fonts, imagery, bgm) and omitted the Next runtime chunks under assets/_next/. Applying the plugin would stage an incomplete copy of the static export, missing the runtime files example.html needs to render. Now lists every file the entry requires (example.html + all 54 files under assets/, including the _next chunks + css). Also cleaned up the truncated od.useCase.query text into a complete sentence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(examples): complete the open-design homepage asset closure Addresses the review's local-asset-closure blocker (three dangling references the mirror never captured): - Restore the Next polyfills chunk assets/_next/.../a6dad97d9634a72d.js (referenced by the noModule fallback script; modern browsers skip it, so it never 404'd at runtime but left the closure incomplete). - The work grid's passcode-protected /2026 tile pointed at work/tt01|tt02 images that were never in any mirror source (they 404 on the live site too). Add lockscreen placeholder images in the site palette so the reference resolves and — importantly — the client work data still matches the server-rendered HTML (removing the tile instead reintroduced a React #418 text hydration mismatch). - od.context.assets now lists the full closure (58 entries). Also corrected the manifest/SKILL 'zero external dependencies' wording: the Draco decoder is fetched from Google's gstatic CDN on demand (same pattern as the other WebGL examples); everything else is bundled locally. Re-verified from a preview subpath: 3 Draco models + fonts + imagery load, zero local 404s, zero console errors, no #418. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(examples): remove third-party network calls + committed key from homepage bundle Addresses review: the bundled preview shipped two undisclosed external requests, contradicting the manifest/SKILL 'only Draco loads externally'. - useWeather() made a live QWeather request with a hardcoded API key (devapi.qweather.com/...&key=...) to append a live temperature to the clock HUD. Replaced the fetch with static data ({now:{temp:"19"}}) — no network call, key removed from the bundle. The HUD still shows a temperature (static, as befits a mirror showcase). - Removed the Vercel toolbar injection IIFE (vercel.live/_next-live/ feedback/feedback.js + a data-deployment-id). It was cookie-gated to Vercel team members so it never fired in preview, but it left a committed external endpoint in a first-party plugin. Re-verified from a preview subpath: the ONLY external request is now the gstatic Draco decoder (as the manifest states); 3 models + fonts + imagery load, zero local 404s, zero console errors, no #418. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Tuola Ge <gexingli@refly.ai> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
49d64f0e8c |
fix(examples): resize WebGL canvases lazily in the render loop (#5327)
The powered-preview iframe can finish loading while its viewport is still 0x0 (hidden/animating dialog). Every WebGL example sized its canvas once at init plus on window resize, so when no resize event is delivered after the dialog settles, the drawing buffer stays 0x0 and the preview renders black until something (e.g. opening the plugin-info panel) changes the iframe width. Guard each resize handler to no-op when dimensions are unchanged and call it from the render loop, so the canvas self-heals within one frame of the iframe getting its real size — no reliance on resize events. Applies to all 15 webgl-* examples. Reported by QA: preview stays black until fullscreen/plugin-info is toggled. Co-authored-by: Tuola Ge <gexingli@refly.ai> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7d005a17c3 |
feat(examples): add 10 WebGL example templates (#5312)
* feat(examples): add 10 WebGL example templates Adds 10 first-party powered-preview WebGL examples under plugins/_official/examples, each a self-contained dir (SKILL.md + example.html + open-design.json, self-contained i18n): C-tier — faithful Codrops ports (MIT + credit + LICENSE; original imagery): webgl-depth-gallery, webgl-pixel-reveal-gallery, webgl-horizontal-parallax, webgl-distortion-grain D-tier — original self-contained WebGL2 shader heroes (no third-party assets): webgl-caustic-pool, webgl-halftone-drift, webgl-holographic-foil, webgl-voronoi-cells, webgl-aurora-veil, webgl-liquid-iridescence All changed files are <1MB (pass the blob-size gate). The two large mirror showcases (oryzo, opendesign) are deferred: they exceed the 1MB blob guard and need their heavy assets moved to repository-assets R2 (per the gate's guidance). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(examples): stop shader setup after WebGL2 fallback message Wrap each pure-shader example script in an IIFE and return early when getContext('webgl2') is unavailable, so unsupported environments settle on the fallback message instead of throwing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Tuola Ge <gexingli@refly.ai> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
956b6607f5 |
feat(preview): add powered WebGL previews and examples (#5266)
* feat(powered-preview): implement cross-origin isolation for WebGL and Worker artifacts - Introduced a new powered preview feature that allows rendering HTML artifacts in a cross-origin-isolated iframe, enabling the use of Web Workers, WASM, and SharedArrayBuffer. - Added API endpoint `/api/preview/isolation` to report the daemon's directly-reachable HTTP origin for rendering. - Implemented logic in the file viewer to determine if an artifact requires powered preview based on its content. - Updated the file serving routes to support powered preview, ensuring proper headers are set for cross-origin isolation. - Enhanced the user interface to include new scenarios for WebGL and Worker visualizations in the home hero section, with corresponding translations and descriptions. This feature addresses the limitations of the opaque-origin preview sandbox, allowing for more complex GPU and compute applications to function correctly. * feat(preview): add WebGL templates and lazy HTML previews * test(web): stabilize project back routing assertion * fix(preview): address powered preview review blockers * fix(preview): isolate powered preview origin |
||
|
|
390fcf88f3 |
fix(plugin-previews): keep Community gallery previews in sync with shipped plugins (#5262)
* fix(plugin-previews): validate baked preview metadata against shipped plugins The Home Community gallery renders whatever data/plugin-previews/manifest.json names, and nothing kept that metadata in sync with reality: #4815 deleted 19 example plugins but left all 19 manifest entries behind, #4040 shipped a card showing another plugin's imagery, a failed re-bake silently leaves the old clip serving outdated content, and durationMs recorded the intended walk time rather than the encoded file (23 entries carried holdMs > real duration, so the card's idle loop pointed past the end of the clip). - add scripts/check-plugin-preview-manifest.ts to pnpm guard: every manifest entry must name a shipped plugin, own its clip keys (<id>/<hash>/... or the legacy <id>.<hash>....), carry a coherent fingerprint, and never share a clip with another entry; prune the 19 orphaned entries it caught - bake validation (BAKE_VERSION 5): reject blank clips (whole-clip luma range via ffprobe signalstats), record durationMs from the encoded file, clamp holdMs to it, and write a bake-report.json naming skipped/stale/blank plugins instead of swallowing the failure - strict mode (--strict / PREVIEW_STRICT=1) fails the run when a bake left broken metadata behind; the pre-merge validation workflow now runs strict while the post-merge/nightly publishers stay lenient * fix(plugins): make the hyperframes example self-contained The example loaded cdn.tailwindcss.com (a render-blocking head script the page never used — every style is inline) plus Google Fonts. Inside the sandboxed gallery iframe or on a slow network the stalled script showed a long blank instead of the composition, and the CI bake raced the webfonts. Drop both: the page now renders from local system font stacks with zero external requests, so the live preview, the detail iframe, and the baked clip all show the same content. * fix(plugin-previews): address review — fail fast on probe errors, widen strict trigger paths - probeClipMs/clipLumaRange now throw instead of returning null: ffprobe is required validation infrastructure, and a swallowed probe error silently disabled exactly the checks this PR adds. A thrown error becomes an 'error …' skip, is recorded in bake-report.json under 'errors', and fails strict mode — while the routine skips every sweep has (non-html plugins 404ing the preview route) still never trip strict. - bake-plugin-previews-pr.yml now also triggers on plugins/community/**, .github/actions/bake-previews/**, and itself, so community-plugin preview changes and bake-recipe changes cannot merge without the strict pre-merge validation. * fix(plugin-previews): bake static pages as a held still instead of skipping forever The strict pre-merge bake on this PR caught five manifest entries that could NEVER refresh: example-dating-web, example-html-ppt-zhangzara-8-bit-orbit, example-frame-logo-outro, od-new-generation, example-orbit-notion. All five are (near-)static pages — the CDP screencast only delivers frames when something repaints, so they produce 1-4 frames and the old 'frames < 5' guard skipped them on every bake, nightly included, leaving their committed entries permanently stale (their old clips are the 103-210ms degenerate files in the manifest today). Encode <5-frame captures as a still instead: hold the last frame for the idle-loop span (half before the trailing repeated concat entry, half inherited by it, summing to ~HOLD_MS). Only a zero-frame capture is a real failure now. The blank-luma check still rejects stills of nothing. * fix(plugin-previews): never persist a manifest entry without a fingerprint When the preview fingerprint fetch failed, the loop still rendered and — on an otherwise successful bake — persisted an entry with hash: null and un-fingerprinted keys: metadata the content-hash reuse skip can never match again and the new manifest guard rejects. Treat a missing fingerprint as an infrastructure error instead: skip the plugin, record it under errors in bake-report.json (strict mode exits non-zero), and leave any committed entry untouched for the next sweep. --------- Co-authored-by: Tuola Ge <gexingli@refly.ai> |
||
|
|
02c22711c1 | Add Design System Source Context plugin (#4931) | ||
|
|
cb4d4efbd2 |
Add Glass Design System UI Kit plugin (#4395)
* Add G2 design system UI Kit plugin * Fix G2 UI kit packaged references * Trigger workspace validation * Prevent G2 input preview submit |
||
|
|
1799d33e1b | Add Agent Skill: Principal UI/UX Architect & Motion Choreographer (Awwwards-Tier) plugin (#4800) | ||
|
|
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> |
||
|
|
54de349c47 |
fix: replace expired Discord invite (#4849)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local> |
||
|
|
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> |
||
|
|
1319bcef2e |
chore: prune curated official example plugins (#4815)
Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> |
||
|
|
3a92f8a011 |
Add web effect extractor scenario (#4811)
Co-authored-by: tuolaji <tuola@tuolajideMacBook-Air.local> |
||
|
|
29b138f7a3 |
feat(brands): turn any brand into a reusable design system (#4691)
* 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(library): OD Library asset registry + OD Clipper extension Add a global, cross-project asset registry (OD Library) and a Chrome MV3 capture extension (OD Clipper), wiring the full HTTP + CLI + Web UI three-track loop per specs/od-clipper.md. - contracts: LibraryAsset/Source/Kind, ingest, search, pairing, task DTOs - daemon: 6 additive SQLite tables, content-addressed owned storage, the idempotent registerLibraryAsset hook (hash dedup + append-source), programmatic enrichment (mime/size/image dims/domain/tags), pairing tokens with a persisted extension-origin allowlist, /api/library/* routes, and /api/tools/library/{search,apply} for in-task agent reuse - cli: `od library list|get|rm|search|import|pair` - web: Library tab (grid, source badges, filters, search, live SSE updates, extension pairing affordance) - clipper/: standalone MV3 extension (background SW, content toolbar, popup) - skills/library-curator: utility skill for agent-driven asset reuse Origin middleware now honors paired chrome-extension:// origins (seeded from SQLite on boot) and exempts the pairing-confirm handshake. Enrichment AI stages (caption/OCR/embedding) are recorded as skipped pending a configured model. * 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> * 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. * 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. * feat(library): enhance asset application with element markup support - Updated the `applyLibraryAsset` function to include an `includeElement` option, allowing the capture of element markup alongside assets. - Modified related components (e.g., `ChatComposer`, `LibrarySection`, `FileWorkspace`) to handle the new element markup feature, ensuring both asset paths and optional element paths are returned and processed. - Introduced a new function, `fetchLibraryAssetElementHtml`, to retrieve the captured HTML for element-pick assets. - Enhanced the UI to display element markup inline within the chat composer, improving user interaction with captured elements. - Updated API contracts to reflect changes in asset application responses, including optional element markup paths. * feat(library): enhance asset filtering and preview handling - Updated the LibraryPicker and LibrarySection components to implement a badge-aware kind filter, allowing for more precise asset filtering based on badge kind. - Introduced a new `matchesKindFilter` function to streamline the filtering logic across components. - Enhanced the DesignSystemAssetDropzone to ensure proper handling of image previews, addressing issues with broken thumbnails under React StrictMode. - Added CSS styles for kind badges to improve asset representation in the UI. - Implemented tests for the DesignSystemAssetDropzone to ensure correct preview lifecycle management. * feat(library): hydrate single asset on SSE ingest Add fetchLibraryAsset(id) so the Library grid can merge just the one asset an `ingest` SSE event references instead of refetching the whole list on every capture. Returns null on miss/error. * feat(clipper): richer in-page image picker Collect CSS background-image url()s in addition to <img> (so hero/section art painted as backgrounds is no longer silently missed), defer thumbnail decode to visible cells via IntersectionObserver, draw downscaled canvas thumbnails instead of second full-res decodes, and add locate-on-page highlighting so a picked image can be traced back to its DOM source. * feat(library): implement lazy loading for thumbnails and enhance asset filtering - Introduced a `LibraryThumb` component to lazily load heavy content (images, videos, iframes) only when they are near the viewport, improving performance. - Added a debounced search feature to optimize asset filtering, reducing unnecessary network requests during rapid input. - Enhanced the asset filtering logic to track active filters using a ref, ensuring efficient updates during live events. - Updated the `snapshotCardRects` and `cardIdsInBand` functions to support improved hit-testing for drag-and-drop interactions. * feat(library): lazy picker thumbnails + debounced search Extend the Library grid's lazy-thumbnail + 250ms debounced-search pattern to the composer LibraryPicker so opening it no longer fires one full-bytes request per asset, and tidy the clipper content-script image collection. * feat(clipper): compress and budget capture inlining Re-encode large raster images to downscaled WebP and inline smallest-first within a fixed budget, dropping only the secondary Figma IR past a safe body size, so an image-heavy page (e.g. a news front page) always saves as an editable HTML capture instead of 413-failing the ingest. * test(library): LibraryPicker debounce + lazy-thumbnail coverage Cover the composer picker's 250ms debounced search and its lazy <img> mount (deferred until the card is in view), matching the grid's perf test. * feat(design-system): enhance asset handling and UI for design systems - Updated the CLI to support additional asset kinds, including 'design-system'. - Enhanced the DesignSystemProvenance type to include source URLs, improving provenance tracking. - Modified the design system generation jobs to correctly summarize source links and GitHub repositories. - Updated UI components to reflect changes in asset handling, including new source link management in the DesignSystemFlow. - Improved tests to cover new functionality for adding source links and ensuring proper handling of design system assets. * refactor(library): rename 'design-system' to 'brand kit' and enhance thumbnail loading - Updated labels and filters in Library components to replace 'design-system' with 'brand kit'. - Introduced a shimmer skeleton for lazy-loaded thumbnails in the LibraryPicker to improve user experience during asset loading. - Enhanced the PickerCard component for better performance by memoizing individual asset cards. - Updated tests to ensure proper handling of brand kit assets and their visibility in the LibraryPicker. * feat(clipper): implement internationalization for toolbar and popup - Added i18n support to the clipper, enabling localization of UI elements and tooltips. - Introduced a new i18n.js file to manage translations for various languages. - Updated content.js and popup.js to utilize the i18n functions for dynamic text rendering. - Enhanced accessibility by ensuring aria-labels and tooltips are also localized. - Improved user experience by providing localized messages for actions and statuses. * feat(clipper): enhance brand kit extraction and localization support - Updated the brand kit extraction process to include improved handling of assets and localization for various UI elements. - Added internationalization support for the brand kit feature, allowing for dynamic text rendering based on user locale. - Enhanced the user experience by ensuring that all relevant messages and tooltips are localized. - Updated tests to cover new localization features and ensure proper functionality of the brand kit extraction process. * feat(clipper): enhance brand color derivation and update localization - Introduced new functions for color manipulation, including linear interpolation and clamping, to improve brand color derivation. - Updated the deriveBrandColors function to better map observed palettes to semantic roles, ensuring consistent brand representation. - Revised localization strings in i18n.js to reflect changes from 'brand kit' to 'design system', enhancing clarity and user experience. - Improved overall code organization and readability by refactoring existing functions and adding new utility methods. * refactor(clipper): update terminology from 'brand kit' to 'design system' - Replaced all instances of 'brand kit' with 'design system' across various components and localization files for consistency. - Updated UI elements, tooltips, and documentation to reflect the new terminology. - Enhanced user experience by ensuring clarity in the design system extraction process and related functionalities. - Adjusted localization strings in multiple languages to align with the updated terminology. * feat(clipper): enhance image fill handling and normalization - Introduced functions to normalize image fills by converting non-PNG/JPEG formats (SVG, WebP, GIF, AVIF) to PNG before import, ensuring all images are properly rendered in Figma. - Updated the UI to report the number of images converted and dropped during the import process, improving user feedback. - Enhanced the overall image processing workflow to prevent silent failures when unsupported formats are encountered. - Revised documentation to reflect the new image handling capabilities and supported formats. * feat(clipper): enhance UI kit and busy state feedback - Updated the UI kit to include new components such as inputs, selection, and overlays, improving the overall design system representation. - Enhanced the busy state feedback during capture processes with localized messages and a step-by-step progress indicator, providing users with clearer status updates. - Revised localization strings to support new UI elements and improve user experience across multiple languages. - Improved documentation to reflect changes in the UI kit and busy state handling. * 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). * Update clipper/brand-capture.js * fix(clipper): improve busy state handling and UI feedback - Adjusted the spinner CSS to use flex properties for better layout control. - Enhanced the reclampIfMoved function to preserve user position during busy state transitions. - Added loading toast notifications for popup-launched captures to ensure progress visibility even when the on-page bar is hidden. * feat(daemon): add kiwi-schema dependency and enhance Figma API integration - Added kiwi-schema package to the daemon for improved schema handling. - Updated FigmaApiNode interface and related functions to support shared functionality with the offline decoder, ensuring consistency in node processing. - Refactored capture functions in clipper to maintain UI visibility during DOM/IR snapshots, enhancing user experience during capture operations. * 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 * feat(daemon): implement offline Figma import and decoding functionality - Added support for importing `.fig` files directly into the daemon, enabling offline processing without requiring a Figma account. - Introduced a new `fig-decode.ts` module for decoding `.fig` files, handling both ZIP-wrapped and raw formats. - Created `figma-import.ts` to orchestrate the import process, generating a canonical snapshot and associated metadata. - Enhanced the server to handle Figma file uploads and integrate with the new decoding logic. - Updated package dependencies to include `kiwi-schema`, `html2canvas`, and `jspdf` for improved functionality. - Added tests for the new Figma import features to ensure reliability and correctness. * feat(clipper): reload-proof capture progress badge on the extension icon The on-page progress strip dies if a page reloads itself mid-capture (aggressive paywall sites like economist.com do this), leaving no loading signal. Add a per-tab '•••' badge on the extension icon for the lifetime of any capture message — it lives on the action icon, so a page navigation can't take it down. Verified end-to-end via a real loaded extension. * feat(daemon): add export functionality for Figma and enhance PDF export process - Introduced `runFigma` command for importing Figma designs, supporting both local `.fig` files and Figma URLs. - Added detailed usage instructions for the `od figma import` command. - Implemented `runExport` command for programmatic export of HTML/deck artifacts to PDF, PPTX, or image formats. - Enhanced error handling and user feedback during export processes. - Removed obsolete `build-pptx-export-prompt` module and related tests to streamline the codebase. * feat(daemon): enhance library synchronization and export capabilities - Implemented `reconcileLibrary` to mirror design systems and agent-produced project deliverables into the Library as referenced assets. - Added support for programmatic export of artifacts via the `od export` command, including detailed usage instructions. - Introduced new functions for handling Figma imports and exports, improving integration with design workflows. - Enhanced error handling and user feedback during synchronization and export processes. - Added tests for new features to ensure reliability and correctness. * feat(web): PPTX export for any shareable artifact + Library toolbar tooltips * chore(nix): refresh pnpm deps hash * refactor(web): enhance onboarding view and file export progress indicators - Updated the onboarding view layout for improved accessibility and visual hierarchy, including adjustments to spacing, typography, and button styles. - Introduced a loading toast for file export progress, displaying elapsed time and estimated time remaining for slide exports. - Added new translation keys for export progress messages in multiple languages. - Refactored the export progress handling to provide real-time updates during the export process, improving user feedback and experience. * refactor(web): streamline export capture bridge and update connector styles - Removed unused loading logic for html2canvas in the export capture bridge, simplifying the code. - Updated CSS for the onboarding view connector to improve visual clarity and ensure it does not overlap with node numbers. * refactor(web): remove html2canvas dependency and enhance Figma URL handling - Removed the html2canvas package from the project, including its references in the lock file and related components. - Added functionality to manage Figma URLs within the Design System flow, allowing users to add, remove, and validate Figma file links. - Improved drag-and-drop handling to prevent unintended file navigation when dropping files outside designated areas. - Updated UI components to accommodate new Figma URL features, enhancing user experience and accessibility. * refactor(web): unify brand and design system flows - Merged the brand extraction process into the design system creation workflow, allowing users to start from a brand directly within the design system wizard. - Updated routing to redirect legacy brand links to the unified design systems tab. - Enhanced the onboarding experience by removing the separate Brand Kit tab and integrating brand selection into the design system creation process. - Improved UI components to reflect these changes, ensuring a seamless user experience across the application. * feat(web): introduce brand enrichment banner and picker modal - Added a new BrandEnrichmentBanner component to allow users to refine programmatically-extracted design systems with AI by selecting design-system skills. - Implemented a BrandPickerModal for selecting brands from a searchable gallery, enhancing the design system creation flow. - Updated ChatPane to conditionally display the enrichment banner for eligible brand projects, improving user engagement. - Enhanced the design system flow to support the new brand enrichment features, ensuring a seamless experience for users. * feat(web): enhance BrandPickerModal and DesignSystemAssetDropzone - Updated the BrandPickerModal to allow scrolling of the entire picker area, improving user experience by creating a unified scrolling surface. - Added new props to the BrandReferencePicker for action labels and scroll root reference, enhancing flexibility in brand selection. - Introduced a new DesignKitView component for rendering design kits consistently across different surfaces. - Enhanced the DesignSystemAssetDropzone to support a wider variety of file types with appropriate previews, improving asset management during design system creation. - Updated styles for better visual clarity and responsiveness across components. * feat(web): update Design Systems tab actions and enhance localization - Changed the button label in the DesignSystemsTab from "Edit" to "Open" for better clarity in user actions. - Added a new translation key for 'dsManager.openSystem' across multiple languages to support the updated button label. - Enhanced the FileWorkspace component to ensure the Design Files tab aligns correctly with the Design System tab, improving UI consistency. - Implemented a new design system editing feature that allows users to fetch and save design system content from DESIGN.md, enhancing the design workflow. * fix(merge): repair post-merge regressions after origin/main integration Follow-up fixes on top of the origin/main merge ( |
||
|
|
0bf1b6d6b8 |
[codex] converge release workflows and stable dry-runs (#4390)
* fix(tools-pack): use junctions for Windows standalone peer deps * fix(desktop): expose IPC during startup * fix(tools-pack): preserve Windows inspect diagnostics * fix(tools-pack): report Windows inspect status errors * fix(packaged): use Electron net fetch for app protocol * fix(packaged): load Windows renderer from web sidecar * fix(desktop): show Windows packaged window during startup * fix(packaged): disable Windows GPU startup * fix(tools-pack): keep Windows core smoke observable * fix(packaged): remove Windows startup probes * fix(tools-pack): trace Windows desktop IPC status * fix(tools-pack): add Windows IPC diagnose loop * fix(release): default beta-s Windows updater feed * chore: clean merged test eof * refactor(release): unify prerelease channel model * chore(release): close prerelease doc escape hatches * refactor(release): converge release channel workflows * fix(release): install toolchain in metadata jobs * fix(release): build release package before contracts * chore(release): bump development version to 0.10.1 * fix(e2e): seed windows packaged smoke runtime config * fix(release): install toolchain for metadata publish * fix(release): materialize betas metadata checkout * chore(release): bump development version to 0.10.2 * fix(release): allow betas metadata cold start from s3 * fix(e2e): support betas packaged update scenarios * fix(release): pass betas channel into packaged smoke * fix(release): set betas channel during self-hosted builds * fix(release): verify counted channel reservations * fix(release): use pnpm cmd for betas windows publish * fix(release): add betas manifest artifact fallback * fix(release): skip beta-s public metadata fetch * fix(release): read beta-s manifests from storage * fix(release): cache beta windows tools-pack builds * fix(release): inline beta mac tools-pack builds * fix(pack): deep sign unsigned mac bundles * docs(pack): document payload-first beta updater validation * fix(release): align preview tools-pack cache flow * fix(release): align prerelease tools-pack cache flow * fix(release): pass github token to prerelease metadata * fix(release): setup pnpm before feishu notify * fix(release): add stable dry-run prepublish flow * fix(release): accept completed prerelease metadata gate * fix(release): require stable release branches * fix(release): converge r2 access checks * fix(updater): use release channel parser for defaults * fix(updater): harden windows payload relaunch * fix(release): converge updater smoke fixture contract * test(e2e): require silent updater fixture output * fix(release): align stable windows smoke build path * fix(ci): include release workspace in validation * fix(ci): repair release validation lanes Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(ci): restore zero-install Feishu notification Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
b02d20e6b9 |
fix: unify Discord invite links (#4452)
Co-authored-by: koki yanlai xu <koki@kokideMacBook-Air.local> |
||
|
|
915548b4bd |
[codex] Fix social template English metadata (#4427)
* Fix social media template English metadata * Remove social template description hard wraps 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> |
||
|
|
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. |
||
|
|
eb749841b4 |
fix(home): surface community slide decks on Home with letterbox-free 16:9 previews (#4350)
* fix(plugins): surface slides decks on Home instead of marketplace sources The 23 community slides/deck plugins from #4127 were registered as a restricted community marketplace source, so they showed up as installable "available sources" cards (受限 + Install) instead of on Home. Relocate them to plugins/_official/examples so they ship bundled — appearing in the Home Community gallery and the deck example-prompt rail, exactly like the existing zhangzara / swiss / guizang decks — and drop their community-registry entries. - Move 23 plugins/community/<slug> → plugins/_official/examples/<slug> (upstream LICENSE / author / homepage / "Based on" attribution preserved) - Rename manifest name community-<slug> → example-<slug> (bundled convention) - Remove the 23 entries from plugins/registry/community/open-design-marketplace.json (the 3 pre-existing community entries stay) - HomeHero: uncap the deck example-prompt rail (other chips keep the curated 18) so every bundled slide template is reachable straight from "All" - curatedPriority: pin the 23 slides to the front of both the deck example rail and the Community Slides shelf Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): drop provenance tail from deck seeds & fix deck preview letterbox Two polish fixes for the slide/deck plugins now surfaced on Home: 1. Example-prompt seed: strip a trailing source-attribution sentence ("…。移植自 foo/bar 的 baz 模板。" / "Based on …") from the composer seed so the prompt doesn't end on provenance boilerplate. Conservative — only fires when the final sentence opens with an attribution marker and real text precedes it; attribution woven mid-description (followed by a use-case sentence) and the gallery/detail descriptions are left intact. Latin '.' only ends a sentence at whitespace/EOL so "STYLE_PRESETS.md" / "github.com/…" don't mis-split. 2. Deck gallery preview: decks ship a fixed 16:9 stage that scales to its viewport, so the tall scroll-preview frame letterboxed it and showed a dark --stage-bg band above/below the slide. Tag deck cards with data-od-mode and give them a 16:9 frame the iframe fills natively (no transform, no pan), so the stage sits edge-to-edge with no band. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): deck preview frame to 16:9 so no white strip below the slide The deck preview override targeted the inner html-frame while the gallery frame kept its fixed 300px height, leaving a white strip under the 16:9 slide. Make the gallery frame itself 16:9 for deck cards so the stage fills it exactly — title bar + slide, nothing left over. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(decks): hide the page-counter chrome on all 23 community slide decks The five upstream deck families each render a different page-counter ("1 / 10") — a center pill (.deck-controls), an id="counter" badge, a fixed .deck-counter, or a .count span inside a Shadow-DOM rail — so the home gallery thumbnails showed it inconsistently. Per maintainer request, drop it everywhere rather than unify: inject a display:none rule for the light-DOM counters and inline- hide the Shadow-DOM .count span. Keyboard/touch navigation is untouched; only the visual counter is removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): fix deck letterbox band in the example-prompt rail tiles too The earlier 16:9 deck-preview fix only covered the Community gallery cards; the hero example-prompt rail tiles render the deck in a 4:3 (1440×1080) preview and still showed a dark --stage-bg band on top. Tag deck preset tiles with data-od-mode and give them a 16:9 preview the iframe fills natively, matching the gallery treatment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(home): remove the ↗ open-external button from community gallery cards The ↗ only rendered when a tile's preview was an HTML source, so it appeared on some cards (most decks, a few prototypes) and not others (images, srcless tiles) — inconsistent chrome across the shelf. Drop it and the whole onOpenExternal pass-through (PluginCard → PluginsHomeSection → HomeView) plus the now-dead .plugins-home__gallery-open styles. * fix(home): make the community search clear (×) button visible The clear button uses the shared <Button> component, whose CSS-module class set padding 6/12 and crushed the 12px × glyph to zero width inside the 26px button (a blank grey square). The .plugins-home__search-clear reset only out-specified the global `button {}` element rule, not the component class — scope it under .plugins-home__search so the padding:0 / 20x20 sizing actually wins. * fix(home): align deck example-prompt tile title row with other tiles Deck preset tiles used a 16:9 `auto` preview row, so their card was shorter than the fixed-150px sibling tiles; the flex rail stretched them back up and the slack leaked into the title row, making deck titles ~6px taller. Keep deck tiles on the standard 150px preview cell and center the native 16:9 stage inside it (neutral margin, no dark band), so card and title-row heights match prototype/HyperFrames/image tiles. * fix(deck-bridge): mirror the visible class so reveal animations fire on navigation Reveal-animation decks (the frontend-slides family) gate staggered entrances on a separate `.slide.visible` class that the deck's own show() adds alongside `.active`. The host bridge's setActive() flipped only the active class, so bridge-driven page turns showed slide chrome but left every .reveal child at opacity:0 — the body rendered blank. Mirror `.visible` in lock-step with the active slide (only for decks that use it, a no-op elsewhere). Adds a red→green regression test. * fix(home): unpin the bare Frontend Slides template from the slides shelf example-frontend-slides is the family-root template with a generic cover; pinned first it read as filler leading the Slides shelf and deck chip. Drop it from PINNED_SLIDE_PLUGIN_IDS so it falls to the uncurated tail while the styled variants (Creative Voltage, Electric Studio, …) keep the lead. --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
c7e422d7a2 |
feat(plugins): unify all 56 official deck seeds with the Open Design product narrative (#4357)
* feat(plugins): unify all 56 official deck seeds with the Open Design product narrative Apply the same canonical 10-section story used for the community slides batch (sourced from the homepage structure doc + README) to every official deck plugin seed that ships an example.html: cover, why, three claims, numbers board (60K+ stars / 300+ contributors / 217+ plugins / 129 design systems / 21 agents), 5-step workflow, multimodal outputs, capabilities, agent ecosystem, testimonial, and CTA with GitHub/Discord/X links. Scenario decks keep their framing with Open Design as the subject: weekly-report/weekly-update become OD growth reports, course-module a getting-started tutorial, testing-safety-alert the local-data-security story, xhs-* decks OD-themed xiaohongshu notes, ib-pitch-book an investor narrative, presenter-mode-reveal keeps its presenter-mode demo. open-design-landing-deck only gets its numbers aligned to the canonical figures. Skipped (no example.html seed): guizang-ppt, html-ppt, replit-deck. Content-only edits: CSS tokens, layouts, decorations, animations, keyboard nav, hash routing and functional JS untouched. zh 13 decks / en 43 decks per existing typography. All 56 verified: script syntax, cover screenshot, no fictional brand residue. * fix(decks): wire dead Download/closing CTAs to real destinations Review follow-up for #4145: primary Download CTAs now point to https://open-design.ai/ (the canonical download landing), and the remaining href="#" closing links (Star on GitHub / Discord / X / See All Agents) point to the repo, Discord invite, and X profile. Also split the landing-deck primary CTA off the repo-root URL so the primary and secondary actions no longer share a destination. * style(official-decks): anti-slop visual pass across the official deck seeds Restyle/polish sweep over all 55 official example decks (taste-skill + impeccable + gsap-skills guidelines): - A-class seeds (AI-slop look: default Inter, purple-blue gradients, uniform rounded shadow cards) fully restyled with distinct typographic systems, locked single accents, and off-white/off-black grounds. - B-class seeds (clear style family, e.g. the zhangzara-* craft set) kept their family signature and received polish only: spacing rhythm, contrast to WCAG AA, hairline discipline, reduced-motion guards. - Motion limited to transform/opacity with prefers-reduced-motion guards; signature ease cubic-bezier(.16,1,.3,1). - Content is unchanged: all copy, numbers (60K+ stars, 217+ plugins, 129 design systems, 21 agents, -80% cost), links, slide counts and the deck engine scripts are byte-identical to the previous seeds. - html-ppt-zhangzara-pin-and-paper already met every rule (craft fonts, single ink accent, static content) and is intentionally untouched. * i18n(official-decks): translate all Chinese deck seeds to English All official slide seeds are now English-only per template policy. 15 decks translated (~12,000 CJK chars): presenter-mode-reveal, testing-safety-alert, xhs-pastel-card, tech-sharing, obsidian-claude-gradient, knowledge-arch-blueprint, xhs-white-editorial, hermes-cyber-terminal, xhs-post, dir-key-nav-minimal, graphify-dark-graph, ppt-keynote, guizang-editorial, swiss-international, open-slide-canvas. - Layout, engine scripts, slide counts, stats (60K+/300+/217+/129/21/ -80%) and links unchanged; only content language changed. - CJK-specific Google Fonts (Noto Sans/Serif SC, ZCOOL KuaiLe, Songti) replaced with Latin families matching each deck's voice (Inter, IBM Plex Sans, Nunito, Patrick Hand, Georgia, Noto Serif). - The xhs-* social decks keep their Xiaohongshu aesthetic with native English social copy. - Overflow from longer English copy fixed with minor per-element type sizing; every deck screenshot-verified; zero CJK characters remain across all 56 official deck seeds. * fix(xhs-pastel-card): restore absolute positioning of topbar/footer chrome The content-layer rule '.slide > *:not(.xp-blob){position:relative}' (specificity 0,3,0) overrode the absolutely-positioned .xp-topbar and .xp-footer (0,2,0), dropping both into the flex flow: the chip overlapped the headline, left:90px turned into a 90px rightward shift that pushed the page number off-canvas, and bottom:40px lifted the footer into the body copy on every slide. Excluding the two chrome elements from the content-layer rule restores the intended layout; verified per-slide screenshots across all 8 slides. * feat(deck-seeds): expand the three sampler decks to full 10-page examples deck-guizang-editorial, deck-swiss-international, and deck-open-slide-canvas shipped as 1-2 page style samplers while every other official seed carries a full 8-11 page example. Each is now a 10-page deck built from its own SKILL.md layout vocabulary: - guizang-editorial: one page per L01-L10 layout, single Ink/Monocle palette per the 5-pick-1 rule, ink/paper reversal for rhythm. - swiss-international: 10 of the 22 locked layouts (statement, cards, six-cell grid, timeline, duo compare, loop diagram, why-now, closing manifesto), Klein Blue as the single accent; SKILL.md example_desc updated from the stale two-page wording. - open-slide-canvas: ten free-composition 1920x1080 canvases (asymmetric split, oversized numerals, positioned-block flow, editorial quote, comparison spread) with keyboard + hash navigation per its own convention. Content follows the English-only OD narrative with canonical stats and links; every page screenshot-verified; zero CJK; single-file with Google Fonts as the only external resource. * fix(decks): wire the two remaining dead closing-slide CTAs Review follow-up for #4145 (nettee, looper reviewer): - 8-bit-orbit: the closing 'Download Open Design' / 'Star on GitHub' pixel buttons were plain <button> elements with no click handling; converted to anchors targeting https://open-design.ai/ and the GitHub repo, keeping the .pixel-btn skin. - retro-windows: the closing copy promised download/star actions but the action row was the old unwired Restart / Contact / End Session set; replaced with Download Open Design / Star on GitHub / Join Discord anchors in the same .btn-retro skin. * fix(decks): wire remaining button-skinned dead CTAs across deck seeds Review follow-up for #4145 (looper reviewer round 3). Converts every remaining action-copy control that carried button/chip skin but no href into a real anchor with the canonical targets, keeping each deck's skin: - zhangzara-long-table: closing .pill chips (GitHub / Download) and the cover 'Star on GitHub' pill - zhangzara-raw-grid: closing .label arrow Download + the two .s10-rb-block tiles (macOS-Windows / Star on GitHub) - zhangzara-peoples-platform: GET STARTED slide DOWNLOAD block - obsidian-claude-gradient: all four .oc-pill chips on the CTA slide - zhangzara-biennale-yellow / sakura-chroma / cobalt-grid colophon ftag labels, zhangzara-pink-script 'Star on GitHub' tile, and ib-pitch-book 'Download Open Design' stamp (same pattern, found by a repo-wide sweep for the regression class) * fix(decks): wire zhangzara-coral closing-slide social icons to anchors * feat(plugins): unify guizang-ppt (magazine-web-ppt) deck default with the Open Design product narrative in English The deck-mode default seed (magazine-web-ppt, dir guizang-ppt) was the one official deck the narrative+i18n pass missed, because its content lives in assets/example-slides.html + assets/template.html rather than example.html. - Rewrite the 9-slide example deck to the English Open Design product narrative (60K+ stars / 300+ contributors / 217+ plugins / 129 design systems / 21 agents / -80% cost), preserving the magazine editorial layout vocabulary and hitting all 8 layout categories. English titles use the Playfair .h-hero-en family; copy follows anti-slop craft (no decorative em-dashes, real labelled metrics, tight hierarchy). - Translate template.html (title, hint, all CSS/JS comments), SKILL.md, references/*.md, open-design.json, and the design-templates README to English. - Keep magazine-web-ppt name, mode=deck, default_for=deck intact. - Both synced copies (plugins/_official + design-templates) updated identically. --------- Co-authored-by: free666799 <293857035+free666799@users.noreply.github.com> |
||
|
|
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> |
||
|
|
ec524986b5 |
chore(plugins): remove html-ppt-dir-key-nav-minimal and html-ppt-xhs-post (#4212)
* chore(plugins): remove html-ppt-dir-key-nav-minimal and html-ppt-xhs-post
Final cut list from the maintainer review of the slide-template gallery
(narrowed from the originally proposed nine html-ppt studio seeds to
these two; the other seven stay).
Removed across every surface:
- plugins/_official/examples/<slug>/ (2 plugin dirs)
- design-templates/<slug>/ (2 catalogue entries)
- plugins/registry/official/open-design-marketplace.json entries
- apps/web/src/i18n/content{,.ru,.fr}.ts slug keys
Landing-page solution showcases never referenced these two, so no
landing changes are needed. pnpm guard and pnpm typecheck pass;
repo-wide grep for both slugs returns zero hits.
* fix(registry): sync bundledPreinstallCount after removing two plugins
plugins-marketplaces.test.ts asserts metadata.bundledPreinstallCount
equals the registry plugins array length; update 414 -> 412 to match
the two removed entries.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
|
||
|
|
01d8e6baab |
feat(plugins): 23 community slides/deck plugins from top open-source slides skills (#4127)
* feat(plugins): add 30 community slides/deck plugins from top open-source slides skills
Convert the highest-starred MIT-licensed slides skills into community deck
plugins (one template style = one plugin), plus 3 family root plugins:
- frontend-slides (zarazhangrui, 21.1k stars): root + 7 style variants (fs-*)
- huashu-design (alchaincyf, 18k stars): slides cut root + 8 variants (huashu-*)
- html-ppt-skill (lewislulu, 5.8k stars): root + 9 theme variants (hps-*)
- visual-explainer (nicobailon, 8.7k stars): 3 aesthetics (ve-*)
Each plugin ships the standard trio (open-design.json + SKILL.md locked spec +
self-contained example.html seed, zero external JS), validated against
PluginManifestSchema. All 30 registered in the community marketplace registry
(0.1.2 -> 0.2.0). Every variant was deduped against the 59 existing official
deck plugins (zhangzara ports, guizang, html-ppt family) before inclusion.
Upstream attribution preserved: MIT LICENSE files + author/homepage per plugin.
* feat(plugins): unify all 30 community deck seeds with the Open Design product narrative
Replace per-deck placeholder content with one canonical 10-section story
sourced from the homepage structure doc and README: cover, why (Claude
Design proved it, OD opens it), three claims, numbers board (60K+ stars /
300+ contributors / 217+ plugins / 129 design systems / 21 agents), 5-step
workflow, multimodal outputs, capabilities, agent ecosystem, testimonial,
and CTA with GitHub/Discord/X links for organic resharing.
Content-only edits: CSS tokens, layouts, decorations, animations, keyboard
nav and hash routing untouched in every deck. huashu-* decks carry the zh
copy; fs-/hps-/ve- decks carry the en copy (latin display faces). All 29
rewrites + 1 pilot verified: script syntax, cover screenshot, no fictional
brand residue.
* fix(ve-presets): align preview motion and slideCount with example contracts
Review follow-up for #4127 (mrcfps):
- ve-midnight-editorial / ve-terminal-mono / ve-warm-signal set
od.preview.motion to "deck" while their example.html files are
vertical scroll-snap documents; switched to "scroll" so the
marketplace hover clip traverses them correctly.
- ve-terminal-mono / ve-warm-signal advertised slideCount options
(5-10 / 10-20 / 20+) that the locked prompt overrode with a hard
8-11 requirement; the prompt now honors {{slideCount}}, and the
SKILL.md slide-count rule is rephrased as a default that yields to
the user's selection.
* style(community-slides): anti-slop polish across the 30 community deck seeds
Visual polish sweep (taste-skill + impeccable + gsap-skills guidelines)
over every community slides plugin example:
- All theme tokens stay LOCKED to each plugin's od.useCase.query spec;
polish is limited to spacing rhythm, contrast (WCAG AA), hairline
discipline, and prefers-reduced-motion guards.
- Motion only via transform/opacity; engine scripts byte-identical.
- Content unchanged: copy, numbers, links and slide counts match the
previous seeds; SKILL.md craft notes updated where the polish touched
documented details.
* fix(fs-presets): honor requested slideCount in fs-dark-botanical and fs-notebook-tabs
Review follow-up for #4127 (mrcfps, round 2): both plugins offered
medium/long slideCount options in their pickers while the en query and
SKILL.md hard-locked 8-11 slides, so picking 'medium 12-16' or 'long'
still produced an 8-11 deck. Same contract fix as the ve-* presets in
|
||
|
|
08a2bdc959 |
Add /deep-think — Maximum Cognitive Effort Protocol plugin (#4116)
* Add /deep-think — Maximum Cognitive Effort Protocol plugin * feat: make /deep-think plugin portable and add name to frontmatter * fix(manifest): clean up serialized YAML description to a plain sentence * chore: sanitize references in deep-think plugin - Removed internal provenance.json to prevent metadata leakage - Replaced private workspace instructions in source.md with a clean attribution note * chore: remove reference to mallettile.ca in attribution note * fix(plugin): add deep-think agent skill metadata * fix(plugin): remove workspace-specific deep-think prompt --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
2940876409 |
feat(plugins): refresh HyperFrames video templates from html-video (#4063)
* feat(plugins): refresh HyperFrames video templates from html-video
Replace the 11 HeyGen catalog stub entries (no bundled source, duplicate
catalog-block cover images) with 23 fully bundled HyperFrames templates
imported from nexu-io/html-video, so both the in-app Plugins home and the
marketing site's /plugins/templates/hyperframes/ show real, renderable,
visually distinct templates with hover-autoplay motion previews.
Added (plugins/_official/video-templates/<slug>/):
- open-design.json — od.surface "hyperframes" (HyperFrames artifact type),
en + zh-CN title/description, inputs, and jsDelivr-hosted preview assets.
- template.json — client card metadata.
- SKILL.md — how to repaint and render the composition.
- source/ — the HTML+CSS+GSAP (or Remotion) composition, verbatim.
- preview.mp4 — a looping motion preview rendered with the html-video
HyperFrames renderer, trimmed to the full animation length (cards
hover-autoplay from frame 0, detail page plays it); each under the 1 MiB
blob limit. 21 of 23 ship a video; frame-logo-outro (a held logo) and
frame-data-rollup (Remotion, blank native render) ship a still poster.
- preview.png — poster frame extracted from that render.
Landing-page tweaks:
- Hide the two cover-less examples/{hyperframes,video-hyperframes} onboarding
scenarios from the public template library (feature demos, not templates).
- Point the "use this" CTAs (template card + plugin detail) at the desktop
download page instead of the detail page / GitHub releases.
- Hover-autoplay restarts each preview from frame 0 so the full animation
plays on every hover instead of resuming mid-loop.
- SEO: keyword-led <title> ("HyperFrames templates & skills …") and a
rewritten, keyword-rich category description (all 18 locales) to target
"hyperframes template" / "hyperframes skill" search intent.
Removed the 11 source-less hyperframes-* HeyGen catalog stubs. Licensing is
mirrored faithfully per upstream and summarised in HYPERFRAMES-ATTRIBUTIONS.md:
8 Apache-2.0 forks of heygen-com/hyperframes, 1 MIT from
nateherkai/hyperframes-student-kit, 7 original Apache-2.0, and 7 derived from
MIT design skills (frontend-slides, huashu-design) with studio inspiration
recorded as non-affiliated L1 origin.
Registry seed nets +12 entries (402 -> 414); bundledPreinstallCount updated.
* fix(plugins): self-contain hyperframes templates + narrow aspect options
Address review on the HyperFrames import:
- Narrow each fixed-layout (1920×1080) hyperframes manifest's
od.inputs.aspect.options to the single aspect its template.json actually
ships (e.g. frame-vignelli is 9:16, the rest 16:9), so the picker/agent
can't request portrait/square renders the composition can't produce.
frame-data-rollup (responsive Remotion, layout computed off canvas size)
keeps 16:9/9:16/1:1.
- frame-kinetic-type: drop the external 9 MB S3 A-roll video from
source/compositions/main-graphics.html. The timeline sets that layer to
opacity:0 at t=0 and never reveals it, so it was never visible; replacing
it with an empty self-contained layer keeps the render identical (verified)
and removes the only third-party runtime media dependency. Re-rendered its
preview from the vendored source.
* fix(plugins): vendor all runtime assets so hyperframes templates are self-contained
Make every bundled HyperFrames template render with no third-party network
dependency, per review and per each template's own SKILL.md "keep the
composition self-contained under source/" contract:
- GSAP: vendor gsap@3.14.2 into each template's source/ and rewrite the
jsDelivr <script src> to a relative path (9 templates).
- Google Fonts: fetch each family's woff2, ship them under source/fonts/,
inline a local @font-face fonts.css, and drop the googleapis <link>/@import
(20 templates). CJK families (Noto Sans/Serif SC) are intentionally not
vendored — they exceed the 1 MiB blob limit; their placeholder sample text
falls back to the OS CJK font, keeping the source dependency-free.
- Tailwind: replace the cdn.tailwindcss.com JIT script with a static
tailwind.css built from the classes each template actually uses (6).
- Textures/media: vendor the remaining external texture (warm-grain) and copy
the previously-missing local assets/ (screenshots, audio, swiss-grid.svg)
into frame-product-promo, frame-product-promo-30s, frame-swiss-grid.
- od.context.assets now stages ./template.json + ./source so the renderer
materializes the full bundle.
All vendored files are under the 1 MiB blob limit. Re-rendered the six
templates whose output could shift (Tailwind static build + CJK fallback);
verified renders are visually intact. Final audit: zero external CDN/http
asset references across all 23 template sources.
* fix(plugins): inline vendored GSAP + enrich plugin detail SEO
- Inline the vendored GSAP runtime directly into each template's index.html
instead of shipping gsap.min.js, so no new committed `.js` files trip the
repository-layout guard (`scripts/guard.ts` residual-JS policy). Compositions
use the global `gsap` the inlined runtime defines. Templates stay fully
self-contained; re-rendered frame-kinetic-type / frame-swiss-grid to confirm
motion is intact.
- Plugin detail pages now lead their <title> and meta description with the
artifact type + brand keywords — "<HyperFrames video template> · Open Design"
and "... for Open Design — the open-source Claude Design alternative" — so
each detail page ranks for "hyperframes template", "Open Design", and
"open source Claude Design alternative".
* fix(plugins): replace placeholder screenshots in frame-product-promo-30s
The product-surfaces scene referenced source/assets/screenshot-{1,2,3}.png,
which were 67-byte 1×1 placeholder PNGs carried over from the upstream
template, so a render of that scene showed blank laptop screens. Replace them
with three self-contained 1440×900 dashboard mockups (distinct Plan/Build/
Monitor accents) so the bundled source renders usable product surfaces, and
re-render the preview. All three are well under the 1 MiB blob limit.
* fix(plugins): give frame-logo-outro a motion preview like the rest
frame-logo-outro shipped as an image-only preview, so it was the one new
HyperFrames template without hover-autoplay / detail playback. Re-render it
from its (now self-contained) source as a short looping logo-reveal MP4 and
switch its manifest to previewType "video", matching the other 22. 72 KB,
under the 1 MiB blob limit. (frame-data-rollup remains a still poster — its
Remotion native render comes out blank; tracked as a follow-up.)
* fix(landing): keep plugin detail lead localized, SEO suffix meta-only
The keyword-rich English SEO suffix was appended to `description`, which is
both the <meta description> and the visible <p class="lead">, so non-English
plugin detail pages rendered mixed-language body copy. Split it: `description`
stays the fully-localized lead, and a separate `seoDescription` carries the
English brand/keyword suffix for <Layout description> + JSON-LD only.
---------
Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
|
||
|
|
b034609cde |
chore(plugins): remove the shamoni example plugin (duplicate preview imagery) (#4040)
* chore(plugins): remove the shamoni example plugin The Shamoni scroll-driven gallery example ships a baked preview that duplicates luxury-botanical's hero imagery, so the Community shelf shows the same perfume tile twice. Curator call: drop the example entirely — plugin folder, baked-preview manifest entry, and its slot in the pinned curated ordering. * fix(daemon): prune persisted bundled rows when their folder leaves the image The bundled boot walker only upserted folders that still exist, so a plugin removed from the daemon image (like the Shamoni example this PR deletes) survived in upgraded installs' installed_plugins table — and /api/plugins kept serving a record whose backing files were gone. Make bundled rows mirror the bundled tree: after a successful walk, delete source_kind='bundled' rows whose folder was not seen this boot. Folders that still ship but fail to parse stay registered (warned, not pruned), the ENOENT early-return never prunes (a missing bundledRoot is a packaging bug, not a removal), and user-installed rows are untouched. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
ec47346e94 |
feat(web): composer 插件菜单 & 设计百宝箱 hover 预览 (#4000)
* feat(web): hover-preview column in the composer plugins menu
Hovering (or arrow-defaulting to) a plugin in the composer "+" → Plugins
flyout now opens a second-level preview column: a live preview hero
(reusing the plugins-home PreviewSurface — media poster or sandboxed
example iframe) plus the localized title, trust badge, description, and
tags. The previewed row stays highlighted so the panel's subject is
clear before the cursor lands.
The Plugins flyout widens to fit the side column and reserves that width
in the placement math; on narrow (contained) surfaces the preview drops
below the list instead. Other submenus are unchanged.
* feat(web): design-toolbox hover preview + styled detail panel
Extends the plugin hover-preview to the project composer's design
toolbox. Hovering a plugin entry now renders the same rich preview
(ComposerPluginPreview — poster / sandboxed example iframe + title,
trust badge, description, tags); every other kind (skill, MCP,
connector, file, follow-up action) keeps a compact text card.
The shared hover-detail panel (.plus-menu__detail) previously shipped
with no CSS at all — it had no position/background/border, so the
inline left/top never applied. This adds the panel styling (fixed,
panelled, shadowed, viewport-clamped) plus the section-label and
detail text styles, and clamps the panel's top so the taller plugin
preview stays on screen. ComposerPluginPreview's column divider was
de-scoped to the plugins-flyout context so it renders cleanly inside
the toolbox panel too.
* fix(web): drop redundant divider above design-toolbox search
The toolbox head carried a border-bottom while the search box below it
has its own full border, so with the flyout gap the two hairlines read
as a doubled line. Drop the head border; the search box already bounds
the section.
* fix(web): localize plugin titles in the composer plugins list
The list rendered the raw `plugin.title` (often English) while the
hover preview used the localized `title_i18n`, so the same plugin showed
two different-language names side by side. Render the localized title in
the list too, and fold it into the search haystack so a localized-name
query still matches.
* feat(web): show plugin kind tag in the hover preview
Adds a localized kind pill (Prototype / Slides / Image / Video / Audio /
HyperFrames / Live artifact) to the plugin preview title row, reusing
extractCategories — the same taxonomy that powers the home Community
filter chips — so the preview names the plugin's type at a glance. Shows
in both the composer plugins menu and the design-toolbox preview.
* fix(web): localize the applied-plugin chip title
The composer's applied-plugin chip showed the raw `record.title` (English,
e.g. "Audio Jingle") while the same plugin's preset card / hover preview
used the localized `title_i18n` (e.g. "音频铃声"), so the two read in
different languages. Localize the chip in both surfaces:
- HomeView: activeBadgeTitle now uses localizePluginTitle(locale, record).
- PluginsSection: the ContextItem label (project ChatComposer chip) too.
Mirrors the already-correct PluginPromptPresetCard pattern.
* fix(web): localize trust badge, drop raw tag chips from preview
- TrustBadge now resolves its label via i18n (pluginsView.trust.*) so
Official / Trusted / Restricted follow the active locale everywhere it
renders; an explicit `label` prop still overrides.
- Drop the raw manifest tag chips from the plugin hover preview. Tags are
author-defined English slugs with no controlled vocabulary, so they
can't be reliably localized; the localized kind pill already conveys
the category, so the card stays single-language.
* feat(web): tag design-system plugins in the hover preview
Design-system plugins aren't one of the home Community facets, so
extractCategories returns nothing and they had no kind pill. Detect them
by mode/tag (same heuristic as the preview classifier) and show the
localized 'Design systems' label (entry.navDesignSystems).
* i18n(plugins): backfill title/description translations for 22 example plugins
These 22 official example manifests shipped title_i18n / description_i18n
with only zh-CN + en, so in every other UI language (Korean, Japanese,
…) the plugin name and description fell back to English — visible now
that the composer surfaces them in the hover preview.
Fill all to the full 18-locale set (zh-CN, zh-TW, ja, ko, de, fr, ru,
es, pt-BR, it, vi, pl, id, nl, ar, tr, uk, en), matching the locale set
used by the already-complete manifests. Brand/product/proper names and
technical terms are kept verbatim; useCase.query stays English-authoritative.
* fix(web): clamp design-toolbox detail panel into the viewport
The left-side fallback (when the right side overflows) used
rect.left - gap - detailWidth without clamping, so a row near the left
edge or a pane narrower than detailWidth + gap*2 produced a negative
left and pushed the position:fixed panel off-screen. Clamp the chosen
left into [8, innerWidth - 8 - detailWidth] so it always degrades
gracefully. (review: nettee/looper)
* test(web): extract + unit-test toolbox detail panel positioning
Pull the detail-panel placement out of showToolboxDetail into a pure
computeToolboxDetailPosition helper and pin the narrow-pane clamp with a
focused vitest regression (row near left edge / viewport narrower than
the panel never yields a negative left; top clamps too). Addresses the
nettee/looper review ask for a regression check.
* fix(web): match plugins-flyout placement reserve to rendered width
PLUS_MENU_PLUGIN_FLYOUT_WIDTH was 560 while .plus-menu__flyout--plugins
renders at 466px, so getFlyoutPlacement over-reserved and medium-width
panes (~664-757px side room) wrongly fell back to the contained layout,
silently dropping the side-by-side preview column. Set it to 466 (with a
cross-reference comment to the CSS), extract the boundary arithmetic into
a pure resolveFlyoutSide helper, and pin the 466-vs-560 boundary with a
vitest regression. (review: nettee/looper)
* fix(web): localize trust badge tooltip + aria text
title and aria-label still came from the hard-coded English
meta.description, so on non-English locales the badge read as
mixed-language to tooltips and screen readers. Resolve all of label,
title, and aria-label from the localized tier key. (review: nettee/looper)
* fix(web): update TrustBadge test for localized a11y text
The existing TrustBadge spec asserted the old hard-coded English
descriptions ("Open Design official", aria "…: Action plugin"), which the
localization change replaced — that's why Web workspace tests went red.
Keep a localized tier prefix in the accessible text when a contextual
label is passed ("Official: Action plugin") and update the spec to pin
the localized behavior.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
|
||
|
|
28f5516697 |
feat(prompt-templates): add desk hologram AR realdesk Seedance 2.0 video template (#3967)
* feat(prompt-templates): add desk hologram AR realdesk Seedance 2.0 video template Ship the two-phase keyframe + i2v workflow behind blue-warrior-realdesk-t2v-15s as a first-party video prompt template with preview MP4/poster and plugin bundle. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(prompt-templates): host desk-hologram previews on repo-assets CDN Drop the 8.9 MB tracked MP4 to satisfy the 1 MiB blob guard and point previewImageUrl/previewVideoUrl at repo-assets.open-design.ai, matching the Three Kingdoms Seedance templates. Bump bundledPreinstallCount to 402. Co-authored-by: Cursor <cursoragent@cursor.com> * ci: add workflow to publish prompt-template previews to repo-assets R2 Maintainer workflow_dispatch helper for template PRs that drop large MP4s from git and point preview URLs at repo-assets.open-design.ai. Co-authored-by: Cursor <cursoragent@cursor.com> * ci: auto-publish desk-hologram template previews on workflow push Run the repository-assets upload when this workflow lands on the template branch so PR #3967 preview URLs go live without waiting for main. Co-authored-by: Cursor <cursoragent@cursor.com> * ci: keep repository-template asset publish as workflow_dispatch only Assets for PR #3967 are live on repo-assets; drop the one-shot branch push trigger now that the upload succeeded. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(plugins): add specVersion to desk-hologram video template manifest Align open-design.json with the official video-template plugin schema. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Tuola Ge <gexingli@refly.ai> Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
b8489c9874 |
fix(plugins): pin the Motion React UMD loader in motionsites plugins (follow-up to #3973) (#3992)
* fix(plugins): pin Motion React UMD loader in plugins, generalize the system-prompt rule PR #3973 patched the blank-screen crash (Motion React hooks loaded from the vanilla motion.js DOM bundle) at the runtime/write boundary and added a Framer Motion note to the official system prompt. This closes the remaining gaps: - Root cause was in the plugins, not just the runtime: the 25-plugin motionsites batch (#3873) prescribes Framer Motion hooks in the React port but never locks how to load them, exactly as it locks fonts/colors/asset URLs. Add a "Motion loading (locked)" note to the 8 plugins that genuinely prescribe Framer Motion (3d-creator-portfolio, acreage-farming, evergreen-finance, liquid-glass-agency, luxury-botanical, mindloop-landing, portfolio-cosmic, shamoni). Plugins that map useScroll *down* to a passive listener, or use GSAP only (cinematic-landing-page), are intentionally left untouched. - Generalize the system-prompt note to lead with the principle (two UMD builds: vanilla DOM vs React, hooks live only on the React build's window.Motion) while keeping one pinned example version. - Add port-path regression coverage for the reported luxury-botanical plugin: full Motion hook set (useScroll/useTransform/useAnimationFrame/useMotionValue), the minified vanilla bundle, and the wrong-bundle + FramerMotion-global combo. Validation: pnpm guard, contracts + daemon typecheck, daemon artifact-runtime-compat.test.ts (8/8). * fix(daemon): widen Motion UMD normalizer to jsdelivr + wrong-file shape The runtime normalizer only matched the exact unpkg `motion@VER/dist/motion.js` script shape, so two real agent outputs still slipped through to a blank screen: a vanilla bundle served from jsdelivr, and the right package name pointing at the wrong file (`framer-motion@VER/dist/motion.js`). Widen the matcher to both hosts and both package spellings, preserve the original CDN host on rewrite, and document the `<script src>`-only boundary (ESM imports / importmaps / esm.sh are steered by the prompt + plugin notes, not rewritten). The React-hook usage gate still keeps animate-only vanilla DOM artifacts untouched, and a new test pins that the correct framer-motion.js bundle is never falsely rewritten. --------- Co-authored-by: audit <a@b.c> |
||
|
|
25b98195b4 |
Refine Share to Open Design next step action (#3965)
* Refine Share to Open Design next step action * fix(web): keep share to OD busy state anchored |
||
|
|
b144df3fba |
fix: restore default scenario craft rails (#3878)
* fix: restore default scenario craft rails * fix: freeze plugin craft on snapshots Generated-By: looper 0.9.7 (runner=fixer, agent=opencode) --------- Co-authored-by: audit <a@b.c> |
||
|
|
75f1472d53 |
feat(web): align Home composer facet rails with Community + drop 6 low-quality example templates (#3939)
* feat(web): align Home composer facet rails with Community + drop 6 low-quality example templates Home composer sub-category rails now mirror the Community plugin grid exactly — same sub-category set, order, and per-facet plugin slice: - Prototype order: Landing/marketing, Brand/design, Dashboards, Apps, Developer tools, Docs/reports - Slides order: Creative decks, Engineering talks, then Pitch/business, Course/training, Reports/briefings, Product/sales - Sub-chips are derived from the full install set (not the curated example subset), so the rail shows every type Community shows - Selecting a sub-category now lists the same plugins Community lists for it via applyFacetSelection (primary-category + sub-category match), so the example-prompt count matches the Community count badge Also removes six example templates with broken/poor visuals (Art Landing, Prisma Creative Studio, Urban Jungle, Modern Agency, AI Automation, FlowMate) and their pinned-order entries in curatedPriority. * fix(web): separate facet display order from matching precedence Addresses review: reordering SUBCATEGORIES re-bucketed overlapping-tag plugins because extractSubcategories() resolves via SUBCATEGORIES.find() (first match wins). Dashboards/app/launch-deck plugins with secondary design/marketing tags wrongly moved into Brand / design or Creative decks in both Home and Community. - Restore SUBCATEGORIES to its original matching precedence (stable buckets) - Add SUBCATEGORY_DISPLAY_ORDER, applied in buildSubcategoryCatalog, so the rails/catalog render Landing/Brand/... and Creative/Engineering/... first without changing which bucket a plugin lands in - Add regression coverage in plugins-home-facets.test.ts for overlapping-tag fixtures (dashboard+design, mobile+design, landing+brand, launch+marketing, pitch+marketing) and update the display-order expectations --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
bad35b45c9 |
fix(daemon): stabilize HyperFrames render handoff (#3882)
* fix(daemon): stabilize hyperframes render handoff * fix: align hyperframes skill handoff guidance --------- Co-authored-by: audit <a@b.c> |
||
|
|
a93869ee09 |
feat(plugins): 25 motionsites example plugins + daemon asset cache (#3873)
* feat(plugins): add 25 motionsites example plugins + daemon asset cache Add 25 first-party example scenario plugins under plugins/_official/examples/ (packaged from motionsites.ai templates via the motionsites-to-open-design-plugin skill): each ships open-design.json, SKILL.md, and a self-contained rendered example.html fidelity seed. All 25 pass PluginManifestSchema. Their cross-border CDN images/videos (cloudinary, higgs.ai, motionsites, cloudfront) are mirrored to Cloudflare R2 (plugin-assets.open-design.ai) and high-fidelity compressed (732MB -> 302MB), so example.html / query / SKILL.md reference the fast public origin instead of slow cross-border hosts. Daemon asset cache (plugin-asset-cache.ts + /api/asset-cache): a same-origin disk-cached proxy for any external preview media that remains. The preview URL rewriter now routes external media (src/poster attrs, CSS url(), and JS string constants) through it, so cross-border assets satisfy the sandbox CSP (img-src 'self') and load from local cache. SSRF-guarded: http(s) only, no credentials, and every resolved address must be public. * fix(asset-cache): tie SSRF validation to the actual outbound connection The previous guard resolved DNS in assertSafePublicUrl and then let fetch() resolve again independently, so a DNS-rebinding host could pass the validation lookup with a public address and steer the real connection to a private one (e.g. 169.254.169.254). Move the authoritative check to a connection-time undici Agent lookup (createValidatingLookup): the address that is validated is the exact address the socket connects to, closing the TOCTOU gap. assertSafePublicUrl is now a cheap up-front reject (scheme / credentials / localhost / literal private IP) only. Adds createValidatingLookup unit tests (public pass, rebinding-to-private reject, all:true any-private reject). * fix(asset-cache): reject IPv4-mapped IPv6 literals in the private-IP guard Node's URL parser normalizes a bracketed mapped literal like `http://[::ffff:127.0.0.1]/` to the hex form `::ffff:7f00:1`, which the old dotted-decimal regex missed — so a literal mapped host slipped past assertSafePublicUrl (and literal IPs skip the DNS lookup hook), letting `/api/asset-cache` target loopback/private IPv4 via its mapped representation. Canonicalize IPv6 now: expandIpv6() folds `::` compression and any embedded dotted IPv4 into eight 16-bit groups, and isPrivateAddress() detects the full `::ffff:0:0/96` mapped range (hex or dotted), feeding the embedded IPv4 back through the v4 private-range checks. Group-based classification also replaces the prefix string-matching for ::, ::1, fe80::/10, fc00::/7, ff00::/8. Regression coverage added for ::ffff:7f00:1 / ::ffff:127.0.0.1 and http://[::ffff:127.0.0.1]/x.png. * fix(asset-cache): full link-local range + stream-cap the upstream body Two SSRF/DoS hardening fixes on the cache path: - Link-local was matched as the single fe80:: prefix, leaking the rest of fe80::/10 (fe90::, febf::, …) through as "public". Classify with a mask ((groups[0] & 0xffc0) === 0xfe80); ULA/multicast use masks too now. - maxBytes was not a hard ceiling for responses without a trustworthy Content-Length: arrayBuffer() buffered the whole body before the size check, a memory-exhaustion path for a caller-supplied proxy. Stream the body and abort the moment the accumulated size exceeds maxBytes, before concatenating. Tests: fe80::1 / fe90::1 / febf::1 rejected; a no-Content-Length 800-byte stream against a 16-byte cap rejects with 413 after <10 pulls (proves it stops reading instead of buffering the full body). --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
10dfd32a3e |
Revert "feat: add screenshot-based visual validation to critique loop (#3660)" (#3865)
This reverts commit
|
||
|
|
931780c914 |
feat: add screenshot-based visual validation to critique loop (#3660)
* feat(daemon): add visual validation atom Generated-By: looper 0.9.3 (runner=worker, agent=codex) * fix(daemon): fail closed in visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): narrow visual validation defaults Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): add visual validation to default critique stages Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): harden visual validation review fixes Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed in visual validation discovery Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * test(daemon): tighten visual validation discovery regression Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): match visual validation reference viewport Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): tighten visual validation capture flow Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed across visual validation refs Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): honor metadata entry file in visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): capture visual validation through preview route Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): fail closed without preview context Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): disable pre-start visual validation worker Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): narrow visual validation spec discovery Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): stop advertising visual validation as runnable Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): restore visual validation critique worker Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): delay visual validation until run success Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * test(daemon): cover post-run visual validation scheduling Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): gate post-run visual validation before finish Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * chore(nix): refresh pnpm deps hash * fix(daemon): preserve deferred pipeline ordering Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): bundle Chromium for visual validation Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(scenarios): keep visual validation out of default critique loop Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): bundle Playwright headless shell Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(packaging): invalidate Playwright resource cache Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * fix(daemon): include visual-validation in bundled atom roster Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * chore(nix): refresh pnpm deps hash * fix: restore pre-run plugin surfaces and nix hashes Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: preserve pre-run surfaces and tolerate headed-only chromium bundles Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: launch visual validation with bundled chromium Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: avoid Playwright fixture teardown races Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: fail packaged visual validation on shell-only chromium Generated-By: looper 0.9.5 (runner=fixer, agent=codex) * fix: isolate synthetic Playwright test bundles Generated-By: looper 0.9.5 (runner=fixer, agent=codex) --------- Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com> |
||
|
|
df9ec8f40d |
examples: add 3D creator portfolio and Velar luxury real-estate templates (#3817)
* examples: add 3D creator portfolio and Velar luxury real-estate templates Two first-party motionsites.ai template seeds under plugins/_official/examples/, each shipping the manifest + locked SKILL.md spec + a self-contained rendered example.html fidelity anchor. - example-3d-creator-portfolio: dark gradient-text hero with a magnetic 3D portrait, scroll marquee, char-reveal About, and sticky-stacking project cards. - example-velar-luxury-real-estate: typewriter preloader, scroll-driven building that scales up while pinning to a dark stats band, count-up stats, and a hover-expand video gallery. Fixed decoration/portrait images are inlined as compressed WebP data URIs so the card and detail previews never break in the sandbox; large GIFs/videos and stable -CDN backgrounds stay as remote URLs. Both manifests validate against PluginManifestSchema (od.kind=scenario). * examples: use first-party metadata for motionsites templates Align the 3D creator portfolio and Velar manifests with the first-party metadata contract used by the rest of plugins/_official/examples/** (MIT, author Open Design, repo homepage) instead of CC-BY-4.0 / third-party motionsites provenance. Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code) * examples: point all inlined-asset references in the locked query at example.html The per-section spec in od.useCase.query.en still named the original remote hosts (figma.site portrait/decorations, cloudinary HOUSE_IMG) as the asset source, while only the trailing note said to reuse the inlined data URIs. Since the query is the authoritative generation brief injected on Use, a port could copy the deprecated remote URLs and regress to sandbox-403 / broken images. Rewrote those references to instruct reusing the inlined data:image/webp URIs from example.html. Genuinely-remote assets on stable CDNs (the 21 motionsites marquee GIFs, 9 higgs project images, 5 cloudfront gallery videos, the higgs hero background) are unchanged. * examples: align Velar nav dark-section refs in the locked query with the seed The Fixed Navigation bullet in od.useCase.query.en said the nav-color logic watches "Section 4 and Section 5", but the seed and SKILL.md define the dark sections as Section 5 (dark statement band) and Section 6 (gallery). Since the query is injected as the generation brief, the stale ref could make a port watch the wrong sections and leave the nav dark over the gallery. Updated the string to match the seed/skill wording. * examples: give the 3D portfolio nav links real anchor targets The hero nav shipped #price and #contact links with no matching ids in the seed, so half the navbar did nothing in the preview (and ports would inherit the dead links). Added id="price" to the Services section and a minimal contact footer (id="contact") so all four nav anchors resolve to real targets. The four-link names stay as the prompt specifies; only the seed gains anchors. * examples: document the 3D portfolio contact footer in the locked query and skill The previous fix added a #contact footer to example.html but left the injected query and SKILL.md describing only five sections (no contact target), so a port could still recreate a dead #contact anchor. Added the Contact footer section to the SECTION ORDER, a nav→anchor mapping (every link must resolve), and a Contact Section spec in both od.useCase.query.en and SKILL.md so the prompt, skill, and seed all agree. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
0d84245b98 |
feat(plugins): add Dashboard UI — Liquid Glass first-party prototype preset (#3779)
* feat(plugins): add Dashboard UI — Liquid Glass first-party prototype preset Bundle a premium liquid-glassmorphism conference dashboard as an official example prototype plugin. Picking it routes the plugin as the active driver and reproduces the template: dual theme-swapped fullscreen background videos, a 4x2 glass/solid card grid, animated voice-wave participant indicators, and a floating control bar. - od.kind: scenario with its own generate pipeline (file-write + live-artifact) and the full build spec in od.useCase.query so the agent reproduces the design. - Ships a rendered, self-contained example.html seed as the fidelity anchor and the HTML preview entry; the marketplace card uses the motionsites animated webp poster. - All 30 avatars are inlined as base64 SVG data URIs so the preview never breaks on external avatar-host rate limits inside the sandbox; background videos and screen-share thumbnails stay on stable CDNs. * fix(plugins): make dashboard-ui-glass avatar instructions consistent with the inlined seed The top-of-file "Avatars (critical)" rule says to keep the bundled data: URI avatars, but the Profile button and Meeting alert bullets still named api.dicebear.com remote URLs — conflicting guidance that could lead a React/Vite export to ship broken sandbox avatars. Both bullets now say to reuse the corresponding inlined avatar from example.html. * fix(plugins): drop dashboard-ui-glass zh-CN query override so it falls back to the full English brief resolvePluginQueryFallback picks od.useCase.query['zh-CN'] ahead of the English fallback, so the shortened Chinese string became the entire generation brief for zh-CN users — dropping the locked avatar/network rules, the card-by-card layout, and the interaction details the English brief carries, and producing a materially different dashboard under a Chinese locale. Remove the zh-CN query override so Chinese users fall back to the authoritative, complete English brief. title_i18n / description_i18n (marketplace display strings) are unaffected. --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
2569f4eba9 |
feat(scenarios): od-share-to-community skill + post-completion Share button (#3657)
* feat(scenarios): add od-share-to-community plugin + Share to Open Design button After the user finishes a generation, they currently have to re-prompt the agent to package what they just made. This adds a quiet "Share to Open Design" pill in the assistant-completion-row — same area as the post-feedback Discord prompt — that injects a single trigger prompt into the chat and lets the bundled `od-share-to-community` scenario auto-derive the manifest from `*.artifact.json`, `brand-spec.md`, and the workspace files instead of asking the user fields the project files already answer. The skill mirrors `home-hero/plugin-authoring.ts`'s constraint surface verbatim: no chained CLI suggestions, no `jq` dependency (not in the agent runtime baseline), and after `od plugin install --source`, point the user at the existing 3-button plugin-folder card (Add to My plugins / Publish repo / Open Design PR) instead of recreating those flows freeform — the source of bug #2332. Verified end-to-end via headless browser: - daemon registers the bundled scenario at /api/plugins - button renders in the live DOM, gated on (isLast && showFeedback) - click fires POST /api/runs with the trigger prompt as a user message - Claude Opus picks up the prompt and starts the share flow * fix(web): debounce share to open design action * fix(plugins): register share community scenario pipeline --------- Co-authored-by: kokisanai <kokisanai@users.noreply.github.com> Co-authored-by: Siri-Ray <2667192167@qq.com> |