mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-24 06:35:10 +00:00
b58d24403bf6eae39a8e4faff81f5cda284e5df7
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b58d24403b |
fix(website): query every raw-id alias when pack slugs collide
Addresses Oracle review feedback: when two raw upstream ids slugify to the same URL slug (e.g. ComfyUI-QwenVL + ComfyUI_QwenVL both -> comfyui-qwenvl) the previous merge kept only the first rawId and used only that single alias to fetch registry metadata. If that one alias missed but its twin would have resolved, the merged pack lost banner/icon/license info. Now NodePack carries rawIds: string[] holding every raw alias seen for the slug. parseCloudNodes flattens all aliases into a single registry batch and pickRegistryPack walks the alias list in insertion order to find the first non-null hit. |
||
|
|
30c106d972 |
fix(website): slugify cloud-node pack ids and mock e2e snapshot
The website's /cloud/supported-nodes routes use pack ids as URL segments, but pack ids come straight from upstream Python module names which mix PascalCase, snake_case, and kebab-case freely. After a Release: Website snapshot refresh that surfaced packs like ComfyUI-Crystools and basic_data_handling, the Playwright assertions in cloud-nodes.spec.ts broke because the slug regex requires kebab-case and the hardcoded comfyui-impact-pack assertions assumed registry contents would never change. Two coordinated fixes: * slugifyPackId in @comfyorg/object-info-parser normalizes every pack id (lowercase + _\u2192-) at the boundaries where it enters the website: groupNodesByPack for fresh fetches and readSnapshot for the bundled fallback. The raw upstream id is preserved as rawId/registryId so registry enrichment continues to hit https://api.comfy.org/nodes with the exact node_id the API expects. Packs whose raw ids collide on the same slug (24 such pairs exist in the live registry today, e.g. ComfyUI-QwenVL + ComfyUI_QwenVL) are merged deterministically instead of producing duplicate static routes. * WEBSITE_CLOUD_NODES_FIXTURE lets the e2e build read a committed fixture snapshot in place of the bundled one. CI sets it to e2e/fixtures/cloud-nodes.fixture.json so Playwright assertions run against deterministic pack content; future snapshot refreshes can no longer break the test contract by removing the Impact Pack or adding underscored ids. Verification: * 99/99 desktop Playwright tests pass against the fixture-built site * 81/81 website Vitest unit tests pass (including new build/fixture coverage) * 48/48 object-info-parser tests pass (11 new slugifyPackId cases, 4 new groupNodesByPack cases) * astro check: 0 errors |
||
|
|
f176d18fe0 |
fix(website): refresh cloud nodes snapshot in release workflow + strict production builds (#12219)
*PR Created by the Glary-Bot Agent* --- ## Summary `Release: Website` only refreshed the Ashby snapshot, so the cloud-nodes snapshot (`apps/website/src/data/cloud-nodes.snapshot.json`) was stale on every release. `loadPacksForBuild()` then silently fell back to that snapshot because `WEBSITE_CLOUD_API_KEY` was never plumbed through CI or Vercel, leaving production at `/cloud/supported-nodes` with placeholder data (e.g. `rgthree-comfy` listed as supported when it isn't — visible at line 104 of the committed snapshot, last fetched 2026-05-04). ## Changes - **New composite action `.github/actions/cloud-nodes-pull`** mirroring `ashby-pull`: runs `pnpm --filter @comfyorg/website cloud-nodes:refresh-snapshot` with `WEBSITE_CLOUD_API_KEY`. The script already `process.exit(1)`s on any non-`fresh` outcome, so refresh failures are loud. - **`release-website.yaml`** now runs both refreshes and opens a single PR with both updated snapshots. Renamed the job to `refresh-snapshots`, updated branch/commit/title/body for the wider scope, and kept the existing `Release:Website` label so downstream automation is unaffected. - **`cloudNodes.build.ts`** throws when the outcome is `'stale'` **and** `VERCEL_ENV === 'production'`. Preview / local builds keep the snapshot fallback so contributors without key access are unaffected. The CI reporter still runs first so the GitHub annotation explaining *why* it's stale is visible in the failed job. - **`ci-vercel-website-preview.yaml`**: passes `WEBSITE_CLOUD_API_KEY` to `vercel build` in both preview and production jobs, and adds a preflight step on `deploy-production` that hard-fails before `vercel build --prod` if the secret is missing — surfacing config drift with a maintainer-friendly error annotation instead of mid-build. - **`apps/website/README.md`**: documents the production-strictness behavior, the new required secret (GitHub Actions + Vercel env), and the manual refresh path. - **New unit tests** in `cloudNodes.build.test.ts` (6 cases): fresh, stale-no-VERCEL_ENV, stale-on-preview, stale-on-production, failed-regardless, and "still reports on stale-in-production before throwing". ## Manual / one-time steps required before merging This PR cannot finish the job alone. A maintainer must also: 1. Add `WEBSITE_CLOUD_API_KEY` as a **GitHub Actions repo secret** in `Comfy-Org/ComfyUI_frontend`. 2. Add `WEBSITE_CLOUD_API_KEY` to the **Vercel project environment** (`production` env at minimum; `preview` recommended). 3. Investigate why `rgthree-comfy` is in the current snapshot — either the Cloud API was actually returning it on 2026-05-04, the snapshot was generated against a non-production environment, or it was hand-edited. The first manual run of `Release: Website` after this PR merges will confirm. Without step 1, the new `Release: Website` job will fail loudly (the refresh script exits 1 with `missing WEBSITE_CLOUD_API_KEY`). Without step 2, the new preflight will fail the production deploy with a clear error annotation pointing at `apps/website/README.md`. Both failure modes are intentional — they replace today's silent stale snapshot. ## Related (out of scope for this PR) The other half of the original report — production 404s on `/p/supported-models/*`, `/cloud/supported-nodes/*`, `/demos/community-workflows` from PRs #11892 / #11903 / #11942 — is a `comfy-router` allow-list gap (those paths exist in the Vercel build as pre-rendered static HTML). That fix needs to land in `Comfy-Org/comfy-router` and is being handled separately since glary doesn't have access to that repo. ## Verification - `pnpm --filter @comfyorg/website test:unit` — 75/75 pass (6 new in `cloudNodes.build.test.ts`) - `pnpm --filter @comfyorg/website typecheck` — 0 errors, 0 warnings (2 pre-existing hints unrelated to this PR) - `pnpm format` + `pnpm exec eslint` on changed files — clean - `js-yaml` validates `release-website.yaml`, `cloud-nodes-pull/action.yaml`, `ci-vercel-website-preview.yaml` - Oracle code review (round 1) raised 1 warning + 1 suggestion; both addressed in commit 2. **Manual verification not applicable**: the runtime changes are GitHub Actions workflows and a Vercel-env-gated branch in a build-time module — they cannot meaningfully run outside of GitHub Actions / Vercel, and the strict-on-stale path is exhaustively covered by the 6 unit tests (including the exact assertions a manual run would check: throws on `VERCEL_ENV=production` + stale, passes on preview, reports observability annotation before throwing). The end-to-end behavior will be verified by the first `Release: Website` dispatch and the next production deploy after the maintainer adds the secret. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12219-fix-website-refresh-cloud-nodes-snapshot-in-release-workflow-strict-production-build-35f6d73d3650816d8f32d403cb39d733) by [Unito](https://www.unito.io) --------- Co-authored-by: glary <bot@glary.dev> |
||
|
|
93edf166d0 |
fix(website): link careers page to Ashby job description, not application form (#12200)
*PR Created by the Glary-Bot Agent*
---
## Summary
The careers page at comfy.org/careers was linking every role to its
Ashby application form (`.../{id}/application`) instead of the job
description page (`.../{id}/`). Users expect to first read the role
description, not land on the submit-resume page.
Ashby's job board API returns both `jobUrl` (description) and `applyUrl`
(application form). `toDomainRole` was preferring `applyUrl`; this PR
switches to `jobUrl` and renames the `Role` field accordingly so the
field name matches its meaning.
## Changes
- `apps/website/src/utils/ashby.ts`: use `job.jobUrl` directly instead
of `job.applyUrl ?? job.jobUrl`.
- `apps/website/src/data/roles.ts`: rename `Role.applyUrl` →
`Role.jobUrl`.
- `apps/website/src/components/careers/RolesSection.vue`: update the `<a
:href>` binding.
- `apps/website/src/data/ashby-roles.snapshot.json`: regenerated
fallback snapshot — URLs stripped of `/application`, `id`s recomputed
from the new URLs.
- Unit + E2E tests updated; new E2E assertion that links do not end in
`/application` prevents regressions.
The Ashby schema (`ashby.schema.ts`) still accepts `applyUrl` since the
API returns it — we just no longer consume it.
## Verification
- `pnpm test:unit` — 70/70 pass
- `pnpm typecheck` — 0 errors
- `pnpm build` — succeeds; inspected `dist/careers/index.html`, all 19
Ashby links now point to description URLs and zero contain
`/application`
- Oracle code review — 0 issues
Fixes user report in #hiring-ideas (Slack).
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-12200-fix-website-link-careers-page-to-Ashby-job-description-not-application-form-35e6d73d3650815cbedadf974f7d3364)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
|
||
|
|
469a5edf99 |
feat: cloud-nodes catalog at /cloud/supported-nodes (#11903)
*PR Created by the Glary-Bot Agent*
---
## Summary
Adds a comfy.org page that lists every custom-node pack supported on
Comfy Cloud, with per-pack detail subpages. Data is fetched at build
time from `cloud.comfy.org/api/object_info` (gated by
`WEBSITE_CLOUD_API_KEY`), sanitized of user content, joined with public
registry metadata from `api.comfy.org/nodes`, and falls back to a
committed snapshot — mirroring the existing Ashby careers integration
pattern.
- Index: `/cloud/supported-nodes` (en) and
`/zh-CN/cloud/supported-nodes` (zh-CN)
- Detail: `/cloud/supported-nodes/[pack]` and
`/zh-CN/cloud/supported-nodes/[pack]`, generated via `getStaticPaths()`
from the same fetcher as the index so the two routes can never diverge.
## What's new
**Shared package (extracted)**
- `@comfyorg/object-info-parser` — Zod schemas (`zComfyNodeDef`,
`validateComfyNodeDef`), node-source classifier (`getNodeSource`,
`isCustomNode`, `CORE_NODE_MODULES`), and helpers (`groupNodesByPack`,
`sanitizeUserContent`). `src/schemas/nodeDefSchema.ts` and
`src/types/nodeSource.ts` become 1-line re-export shims; existing
imports keep compiling.
**Build-time pipeline**
- `apps/website/src/utils/cloudNodes.ts` — Ashby-style fetcher:
retry/backoff `[1s, 2s, 4s]`, 10 s timeout via AbortController, Zod
envelope + per-node validation, snapshot fallback, memoized via
module-level `inflight` promise.
- `apps/website/src/utils/cloudNodes.registry.ts` — Public registry
enrichment (no auth, batches of 50, single retry, soft-fail).
- `apps/website/src/utils/cloudNodes.ci.ts` — GitHub Actions annotations
+ step summary mirroring the Ashby reporter.
- `apps/website/src/utils/cloudNodes.build.ts` — Single
`loadPacksForBuild()` consumed by both index and detail pages so they
share one source of truth.
- `apps/website/scripts/refresh-cloud-nodes-snapshot.ts` — atomic-rename
refresh CLI that walks pack/node string fields with a user-content
extension regex *before* renaming the snapshot into place.
- Mandatory user-content sanitization strips uploaded filenames from
combo lists (`LoadImage`, `LoadImageMask`, `LoadImageOutput`,
`LoadVideo`, `LoadAudio` zeroed; any combo value matching
`/\.(png|jpe?g|webp|gif|mp4|mov|webm|wav|mp3|flac|ogg|safetensors|ckpt|pt)$/i`
filtered).
**Page + components**
- `apps/website/src/pages/cloud/supported-nodes.astro` (en) + zh-CN
twin.
- `apps/website/src/pages/cloud/supported-nodes/[pack].astro` detail
(en) + zh-CN twin, async `getStaticPaths` driven by
`loadPacksForBuild()`.
-
`apps/website/src/components/cloud-nodes/{HeroSection,PackGridSection,PackCard,PackBanner,NodeList,PackDetail}.vue`
— Vue 3.5 destructured props, `cn()` from `@comfyorg/tailwind-utils`,
design-system tokens only, no PrimeVue.
- Pack card name links to its detail page; banner uses the shared
`fallback-gradient-avatar.svg` asset (copied into
`apps/website/public/assets/images/`) when `banner_url` and `icon` are
missing.
- 25 new `cloudNodes.*` i18n keys in `en` + `zh-CN`.
**Tests**
- 33 unit tests in `@comfyorg/object-info-parser` (schemas, classifier,
sanitizer, grouping).
- 19 new website unit tests covering fetcher (10), CI reporter (6),
registry enrichment (3) — Ashby patterns mirrored.
- E2E: index smoke + search + banner + detail click-through + direct
visit + zh-CN parity.
## Required maintainer follow-up
GitHub Apps cannot push `.github/workflows/*` changes (push was rejected
with `refusing to allow a GitHub App to create or update workflow …
without workflows permission`), so the workflow edits prepared in this
branch were reverted in commit `9be2abce8`. The intended diffs are
documented as copy-paste-ready snippets in `apps/website/README.md`
under the new "Cloud nodes integration → CI wiring" section.
A maintainer must:
1. Provision `WEBSITE_CLOUD_API_KEY` in the repo secrets and the Vercel
project env.
2. Apply the `ci-website-build.yaml` and
`ci-vercel-website-preview.yaml` diffs documented in the README directly
to `main` (or as a follow-up commit on this branch with a maintainer
account).
The committed snapshot lets builds succeed without the secret while the
maintainer step is pending — pages render from
`apps/website/src/data/cloud-nodes.snapshot.json`.
## Self-review (Oracle)
Two warnings caught and fixed in commits `deba5ab02` and `99dfc3381`:
- Index/detail pages now share a single source of truth
(`loadPacksForBuild`), so a fresh fetch can't expose packs whose detail
routes weren't generated.
- Refresh script validates parsed snapshot fields *before* the atomic
rename, instead of regex-scanning the serialized JSON after the file is
already in place.
## Quality gates (local)
```
pnpm --filter @comfyorg/object-info-parser test → 33 passed
pnpm --filter @comfyorg/website test:unit → 42 passed
pnpm --filter @comfyorg/website typecheck → 0 errors
pnpm --filter @comfyorg/website build → 47 pages built (incl. 6 cloud-nodes routes)
pnpm lint → 0 errors (1 pre-existing warning in unrelated test file)
pnpm knip → 0 errors (1 pre-existing tag hint in unrelated file)
```
E2E (`pnpm --filter @comfyorg/website test:e2e`) is intended to be run
by the Vercel/CI pipelines.
## Manual verification
Built `dist/`, served locally on port 4321, drove with Playwright:
- `/cloud/supported-nodes` renders both pack cards, search input, sort
dropdown
- `/cloud/supported-nodes/comfyui-impact-pack` renders the metadata grid
(publisher, downloads, stars, version, license, last updated) and 3
categorized node sections with 5 nodes total
- `/zh-CN/cloud/supported-nodes` localizes hero (`Comfy Cloud 上的自定义节点`),
label (`云端节点目录`), search placeholder (`搜索节点包或节点名称`), sort
- `/zh-CN/cloud/supported-nodes/comfyui-controlnet-aux` localizes every
metadata label (`查看仓库`, `发布者`, `下载量`, `GitHub 星标`, `最新版本`, `许可证`,
`最后更新`) and renders dates with `Intl.DateTimeFormat('zh-CN')`
(`2026年4月27日`)
- Search input narrows pack count from 2 to 1 when typing `impact`
(verified via DOM count)
Banners render the shared `fallback-gradient-avatar.svg` when the
snapshot's image URL doesn't resolve — expected in the local sandbox.
## Preview URL (after CI completes)
`https://comfy-website-preview-pr-{N}.vercel.app/cloud/supported-nodes`
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11903-feat-cloud-nodes-catalog-at-cloud-supported-nodes-3566d73d36508194afdec5f389897585)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
Co-authored-by: GitHub Action <action@github.com>
|
||
|
|
65876c635d |
feat(website): add responsive media tooling for marketing assets (#11869)
*PR Created by the Glary-Bot Agent*
---
## Summary
Adds the building blocks for a responsive media system on
`apps/website`, motivated by the gallery video blurriness raised in
Slack. Three independent pieces:
1. **`<SiteVideo>` Vue component + URL helper** — emits a `<video>` with
multiple `<source>` tags, designed to pair with assets named
`${name}-${width}.${format}` on `media.comfy.org`.
2. **`scripts/process-videos.sh`** — local-developer `ffmpeg` helper
that produces VP9/WebM + H.264/MP4 variants and a poster JPG. Not wired
into CI; the team uploads to `media.comfy.org` out-of-band.
3. **Marketing image conventions** — shared `MARKETING_FORMATS` /
`MARKETING_WIDTHS` constants and a README documenting how to render
local marketing images via Astro's built-in `<Picture>` from
`astro:assets`.
This PR is **infrastructure only** — no existing pages are modified.
Adoption (e.g. converting `HeroSection`, gallery videos) is a follow-up.
The new files are added to knip's ignore list with the existing "pending
stacked PR" pattern.
## Why this shape
- **No custom `<Picture>` wrapper.** Astro 5 already ships a
`ResponsiveImage` component (name conflict), and Astro's
`LocalImageProps | RemoteImageProps` discriminated union does not
survive a thin wrapper without unsafe `as` casts. Shared constants give
the consistency benefit at lower cost.
- **No CI media-upload step.** The `Release: Website` workflow currently
only refreshes the Ashby snapshot; wiring GCS uploads into it would
require new secrets and team coordination beyond this PR's scope. The
script runs locally and outputs are uploaded to `media.comfy.org` the
same way as today.
- **Single resolution per `<video>`.** `<source media="...">` inside
`<video>` is unreliable across browsers (Safari ignores it). The script
generates multiple widths so callers can pick one per page; JS-based
selection can be layered on later if metrics demand it.
## What's verified
- `pnpm --filter @comfyorg/website test:unit` — 30 pass (7 new for
`buildVideoSources` / `videoKey`)
- `pnpm --filter @comfyorg/website typecheck` — clean
- `pnpm --filter @comfyorg/website build` — 41 pages built clean
- `pnpm knip` — exit 0
- `oxfmt --check` and `oxlint` clean on all changed files
- `bash -n` on `process-videos.sh` clean; usage and missing-deps paths
exercised manually
- Manual: home page and `/gallery` rendered via `astro dev` — both
unchanged with zero console errors (screenshots attached)
## Review feedback addressed
After Oracle review, three follow-up commits land:
- **`SiteVideo` reactivity** — `sources` is now `computed`; the
`<video>` is keyed on the joined source URLs so it remounts when the
source set changes (browsers don't reload on `<source>` mutation).
- **`SiteVideo` accessibility** — `aria-hidden="true"` only when truly
decorative (no `alt` and no `controls`).
- **Shell script robustness** — probes duration with `ffprobe` and falls
back to `t=0` for clips shorter than 1s; enables `nocaseglob` so
`CLIP.MP4` is picked up.
- **Docs** — clarifies when to use `<SiteVideo>` (lightweight
multi-source) vs `<VideoPlayer>` (captions, controls, scrubber).
## Out of scope (follow-ups)
- Converting existing pages (`HeroSection`, customer detail heros,
gallery) to use the new components. Most current images are CDN-hosted
and migrating them is a separate decision.
- Re-encoding the gallery videos at a higher source width to actually
fix the blurriness — that requires the team to run `process-videos.sh`
against the source clips and re-upload.
- Combining `<SiteVideo>`'s multi-source support with `<VideoPlayer>`'s
rich chrome.
## Screenshots


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11869-feat-website-add-responsive-media-tooling-for-marketing-assets-3556d73d3650818899c7f9ed3204c9a5)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
|
||
|
|
810381ab63 |
Stabilize website GitHub stars in visual snapshots (#11771)
## Summary Stabilize the website nav GitHub star count in visual-test builds so snapshot comparisons do not drift as the live GitHub count changes. ## Changes - **What**: Added `WEBSITE_GITHUB_STARS_OVERRIDE` for build-time star-count overrides and set it to `111000` in the website E2E and screenshot-update workflows. - **Dependencies**: None. ## Review Focus Confirm the deterministic build-time override is preferable to screenshot masking, since Playwright masks draw a colored rectangle whose geometry can also drift when masked content changes size. ## Screenshots (if applicable) Not included; this keeps visual-test input data stable rather than changing the UI. |
||
|
|
5a8ded7959 |
Website: pull careers page listing from ashby API (#11590)
Careers --------- Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> |
||
|
|
bbb043c9cc |
feat(website): Polish and fix UI (#11363)
## Summary <!-- One sentence describing what changed and why. --> Polish and fix UI for new website ## Changes - **What**: <!-- Core functionality added/modified --> - [x] update about video - [x] update Moment factory story content - [x] update homepage visual - [x] update customer story visual - [x] put images and videos to bucket ## Review Focus <!-- Critical design decisions or edge cases that need attention --> <!-- If this PR fixes an issue, uncomment and update the line below --> <!-- Fixes #ISSUE_NUMBER --> ## Screenshots (if applicable) <!-- Add screenshots or video recording to help explain your changes --> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11363-feat-website-Polish-and-fix-UI-3466d73d365081f895aff84b594450c9) by [Unito](https://www.unito.io) --------- Co-authored-by: DrJKL <DrJKL0424@gmail.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Alexander Brown <drjkl@comfy.org> Co-authored-by: github-actions <github-actions@github.com> |