Skip to content

Commit 8a369e9

Browse files
Merge remote-tracking branch 'upstream/main' into fix-ogg-syntax-9256
Resolved conflicts in ogg.ts by integrating the NaN/Infinity parsing logic from #12217 into the new robust Ogg parser.
2 parents 221cbeb + 9cc09cd commit 8a369e9

277 files changed

Lines changed: 15431 additions & 1424 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
name: add-model-page
3+
description: 'add, update, or remove a model page entry on the comfy org website. creates a PR to Comfy-Org/ComfyUI_frontend apps/website folder with the change and posts a Vercel preview link back to Slack.'
4+
---
5+
6+
# add-model-page
7+
8+
add, update, or remove model pages in the ComfyUI website.
9+
10+
## Trigger phrases
11+
12+
- `Add a model page for <model-name>`
13+
- `Update the model page for <model-name>`
14+
- `Remove <model-name> from model pages`
15+
16+
## Phase 1 — Parse the request
17+
18+
Extract:
19+
20+
- **action**: `add` | `update` | `remove`
21+
- **model-name**: raw string (e.g. `flux1-schnell`, `flux1_dev.safetensors`)
22+
23+
Normalize to a slug: lowercase, replace `_` and `.` with `-`, strip file extensions.
24+
Example: `flux1_dev.safetensors``flux1-dev`
25+
26+
## Architecture overview
27+
28+
Models come from two sources merged at build time:
29+
30+
| File | Purpose |
31+
| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
32+
| `apps/website/src/config/generated-models.json` | Auto-generated from workflow_templates (slug, name, directory, huggingFaceUrl, workflowCount, displayName, thumbnailUrl, docsUrl) |
33+
| `apps/website/src/config/model-metadata.ts` | Hand-curated overrides (docsUrl, blogUrl, featured) — only add entries that need overrides |
34+
| `apps/website/src/config/models.ts` | Merges the two above; exports typed `Model[]` |
35+
36+
To regenerate the JSON from workflow_templates:
37+
38+
```bash
39+
pnpm tsx apps/website/scripts/generate-models.ts
40+
```
41+
42+
This writes `apps/website/src/config/generated-models.json` directly.
43+
Thumbnails are populated from local `.webp` files in `workflow_templates/templates/` — no network access needed.
44+
45+
---
46+
47+
## Phase 2 — Gather model data (ADD / UPDATE)
48+
49+
Run the generator to get fresh data, then find the model:
50+
51+
```bash
52+
pnpm tsx apps/website/scripts/generate-models.ts
53+
jq '.[] | select(.slug | contains("MODEL_SLUG"))' \
54+
apps/website/src/config/generated-models.json
55+
```
56+
57+
The JSON fields are:
58+
59+
- `slug` — URL slug
60+
- `name` — exact filename or display name for partner nodes
61+
- `huggingFaceUrl` — download URL (empty for partner nodes)
62+
- `directory``diffusion_models` | `loras` | … | `partner_nodes`
63+
- `workflowCount` — integer
64+
- `displayName` — human-readable name
65+
66+
If no match and it is a known API/partner model, add it to `API_PROVIDER_MAP` in
67+
`generate-models.ts` and re-run. Otherwise tell the user.
68+
69+
---
70+
71+
## Phase 3 — Check for existing entry
72+
73+
```bash
74+
jq --arg slug "${SLUG}" '.[] | select(.slug == $slug)' \
75+
apps/website/src/config/generated-models.json
76+
```
77+
78+
- Match found + action is `add` → switch to UPDATE flow automatically
79+
- No match + action is `update` → stop and tell the user
80+
81+
---
82+
83+
## Phase 4A — ADD: new partner/API model not in workflow_templates
84+
85+
For partner nodes (no local file), add an entry to `API_PROVIDER_MAP` in
86+
`apps/website/scripts/generate-models.ts`:
87+
88+
```typescript
89+
mymodel: { name: 'My Model', slug: 'my-model' },
90+
```
91+
92+
Then re-run `pnpm tsx apps/website/scripts/generate-models.ts` — it will appear
93+
in `generated-models.json` automatically.
94+
95+
If you also want a `docsUrl`, `blogUrl`, or a link to the hub model page, add an entry to `model-metadata.ts`:
96+
97+
```typescript
98+
'my-model': {
99+
docsUrl: 'https://docs.comfy.org/tutorials/...',
100+
blogUrl: 'https://blog.comfy.org/...',
101+
hubSlug: 'my-model', // slug at comfy.org/workflows/model/{hubSlug} — only set if the page exists (returns 200)
102+
featured: true
103+
}
104+
```
105+
106+
No changes to `models.ts` or `translations.ts` are needed.
107+
108+
---
109+
110+
## Phase 4B — UPDATE: edit existing entry
111+
112+
Only `model-metadata.ts` needs editing for most updates (docsUrl, blogUrl,
113+
featured). For `displayName` or `directory` changes, edit the entry directly in
114+
`generated-models.json` (until the next generator run would overwrite it — then
115+
fix the source in `generate-models.ts`).
116+
117+
---
118+
119+
## Phase 4C — REMOVE: delete entry
120+
121+
Remove the entry from `generated-models.json` (or mark it with `canonicalSlug`
122+
pointing to the replacement). No translation file changes needed.
123+
124+
---
125+
126+
## Phase 5 — Verify TypeScript
127+
128+
```bash
129+
pnpm typecheck 2>&1 | grep -E "error|warning" | head -20
130+
```
131+
132+
Fix any type errors before proceeding. Common issues:
133+
134+
- `ModelDirectory` type not matching a new `directory` value — add it to the union
135+
- JSON import shape mismatch — `generated-models.json` must match `OutputModel`
136+
137+
---
138+
139+
## Phase 6 — Create PR
140+
141+
```bash
142+
BRANCH="add-model-page-MODEL-SLUG" # or update- / remove-
143+
git checkout -b $BRANCH
144+
git add apps/website/src/config/generated-models.json \
145+
apps/website/scripts/generate-models.ts \
146+
apps/website/src/config/model-metadata.ts
147+
git commit -m "feat(models): add model page for MODEL-SLUG"
148+
git push -u origin $BRANCH
149+
gh pr create \
150+
--title "Add model page: MODEL-SLUG" \
151+
--body "$(cat <<'EOF'
152+
Adds a new model page entry for MODEL-SLUG.
153+
154+
## Changes
155+
- `generated-models.json`: regenerated with new entry (workflowCount N, directory DIRECTORY)
156+
- `model-metadata.ts`: editorial overrides (docsUrl, featured) if needed
157+
EOF
158+
)"
159+
```
160+
161+
For UPDATE use branch `update-model-page-MODEL-SLUG`.
162+
For REMOVE use `remove-model-page-MODEL-SLUG`.
163+
164+
---
165+
166+
## Error states
167+
168+
| Situation | Response |
169+
| ------------------------------- | ---------------------------------------------------------------- |
170+
| Model not in workflow templates | Ask user to verify spelling or add it manually as a partner node |
171+
| Slug already exists (add) | Switch to update flow automatically |
172+
| Slug not found (update/remove) | Stop and ask user to confirm |
173+
| Typecheck fails | Fix the error before pushing |

.coderabbit.yaml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,26 @@ reviews:
1919
- name: End-to-end regression coverage for fixes
2020
mode: error
2121
instructions: |
22-
Use only PR metadata already available in the review context: the PR title, commit subjects in this PR, the files changed in this PR relative to the PR base (equivalent to `base...head`), and the PR description.
23-
Do not rely on shell commands. Do not inspect reverse diffs, files changed only on the base branch, or files outside this PR. If the changed-file list or commit subjects are unavailable, mark the check inconclusive instead of guessing.
22+
Use only PR metadata already available in the review context:
23+
- the PR title
24+
- commit subjects in this PR
25+
- The files changed in this PR relative to the PR base (equivalent to `base...head`)
26+
- the PR description.
27+
Do not rely on shell commands.
28+
Do not inspect reverse diffs, files changed only on the base branch, or files outside this PR.
29+
If the changed-file list or commit subjects are unavailable, mark the check inconclusive instead of guessing.
2430
25-
Pass if at least one of the following is true:
26-
1. Neither the PR title nor any commit subject in the PR uses bug-fix language such as `fix`, `fixed`, `fixes`, `fixing`, `bugfix`, or `hotfix`.
27-
2. The PR changes at least one file under `browser_tests/`.
28-
3. The PR description includes a concrete, non-placeholder explanation of why an end-to-end regression test was not added.
31+
Fail if all of the following are true:
32+
1. The PR title and/or any commit subject in the PR uses bug-fix language such as `fix`, `fixed`, `fixes`, `fixing`, `bugfix`, or `hotfix`.
33+
2. The PR changes files under `src/` or `packages/` related to the main frontend application but the PR does not change at least one file under `browser_tests/`.
34+
3. The PR description lacks a concrete explanation of why an end-to-end regression test was not added.
35+
36+
Do not fail if the changes are exclusively in `apps/website`, just documentation changes, or changes related to CI processes.
37+
The goal is to make sure that fixes include End-to-End regression tests. Do not insist on tests when the PR is not fixing a bug.
38+
39+
Pass otherwise.
40+
When failing, mention which bug-fix signal you found and ask the author to either add or update a Playwright regression test under `browser_tests/` or add a concrete explanation in the PR description of why an end-to-end regression test is not practical.
2941
30-
Fail otherwise. When failing, mention which bug-fix signal you found and ask the author to either add or update a Playwright regression test under `browser_tests/` or add a concrete explanation in the PR description of why an end-to-end regression test is not practical.
3142
- name: ADR compliance for entity/litegraph changes
3243
mode: warning
3344
instructions: |
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Model Page Discovery
2+
3+
on:
4+
schedule:
5+
- cron: '0 9 * * 1'
6+
workflow_dispatch:
7+
8+
jobs:
9+
discover:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
issues: write
14+
15+
steps:
16+
- name: Fetch model labels from hub API
17+
id: hub
18+
shell: bash
19+
run: |
20+
set -euo pipefail
21+
curl -fsSL 'https://comfy.org/api/hub/labels?type=model' -o hub-labels.json
22+
echo "Fetched $(jq '.labels | length' hub-labels.json) model labels from hub"
23+
24+
- name: Checkout ComfyUI_frontend
25+
uses: actions/checkout@v6
26+
with:
27+
sparse-checkout: apps/website/src/config/generated-models.json
28+
29+
- name: Compare against existing models
30+
id: compare
31+
shell: bash
32+
run: |
33+
set -euo pipefail
34+
35+
HUB_SLUGS=$(jq -r '[.labels[].name]' hub-labels.json)
36+
37+
EXISTING_SLUGS=$(node -e "
38+
const fs = require('fs');
39+
const models = JSON.parse(
40+
fs.readFileSync(
41+
'apps/website/src/config/generated-models.json',
42+
'utf8'
43+
)
44+
);
45+
console.log(JSON.stringify(models.map(m => m.slug)));
46+
" 2>/dev/null || echo '[]')
47+
48+
ADDED_SLUGS=$(node -e "
49+
const hub = $HUB_SLUGS;
50+
const existing = new Set($EXISTING_SLUGS);
51+
console.log(JSON.stringify(hub.filter(s => !existing.has(s))));
52+
")
53+
54+
COUNT=$(node -e "console.log($ADDED_SLUGS.length)")
55+
echo "new_count=$COUNT" >> \$GITHUB_OUTPUT
56+
echo "new_slugs=$ADDED_SLUGS" >> \$GITHUB_OUTPUT
57+
58+
if [ "\$COUNT" -eq 0 ]; then
59+
echo "No new models found."
60+
else
61+
echo "Found \$COUNT new model(s)"
62+
fi
63+
64+
- name: Check for existing open discovery issue
65+
id: existing_issue
66+
if: steps.compare.outputs.new_count != '0'
67+
env:
68+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
69+
shell: bash
70+
run: |
71+
COUNT=$(gh issue list \
72+
--repo "$GITHUB_REPOSITORY" \
73+
--state open \
74+
--search 'in:title "New models detected"' \
75+
--json number \
76+
--jq 'length')
77+
echo "open_count=$COUNT" >> $GITHUB_OUTPUT
78+
79+
- name: Open GitHub issue for new models
80+
if: |
81+
steps.compare.outputs.new_count != '0' &&
82+
steps.existing_issue.outputs.open_count == '0'
83+
env:
84+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85+
NEW_SLUGS: ${{ steps.compare.outputs.new_slugs }}
86+
NEW_COUNT: ${{ steps.compare.outputs.new_count }}
87+
shell: bash
88+
run: |
89+
SLUG_LIST=$(node -e "
90+
const slugs = $NEW_SLUGS;
91+
console.log(slugs.map(s => '- \`' + s + '\`').join('\n'));
92+
")
93+
94+
gh issue create \
95+
--repo "$GITHUB_REPOSITORY" \
96+
--title "New models detected — add to model pages" \
97+
--body "## $NEW_COUNT new model(s) found in hub
98+
99+
The weekly model discovery scan found model labels on the hub not yet in
100+
\`apps/website/src/config/generated-models.json\`.
101+
102+
### New slugs ($NEW_COUNT)
103+
104+
$SLUG_LIST
105+
106+
### Next steps
107+
108+
1. Review which of these warrant an SEO model page
109+
2. For local models: run \`SKIP_THUMBNAILS=1 pnpm generate:models\` and commit the result
110+
3. For partner/API models: add to \`API_PROVIDER_MAP\` in \`generate-models.ts\`, regenerate, commit
111+
112+
---
113+
*Generated by the [model-page-discovery workflow](https://github.com/$GITHUB_REPOSITORY/actions/workflows/model-page-discovery.yaml)*"
114+
115+
- name: Skip — open issue already exists
116+
if: |
117+
steps.compare.outputs.new_count != '0' &&
118+
steps.existing_issue.outputs.open_count != '0'
119+
run: echo "An open discovery issue already exists — skipping creation."
120+
121+
- name: No new models found
122+
if: steps.compare.outputs.new_count == '0'
123+
run: echo "No new models found — nothing to do."

.oxlintrc.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@
8585
"typescript/no-unused-vars": "off",
8686
"unicorn/no-empty-file": "off",
8787
"vitest/require-mock-type-parameters": "off",
88+
"vitest/consistent-each-for": [
89+
"error",
90+
{
91+
"test": "for",
92+
"it": "for",
93+
"describe": "for",
94+
"suite": "for"
95+
}
96+
],
8897
"unicorn/no-new-array": "off",
8998
"unicorn/no-single-promise-in-promise-methods": "off",
9099
"unicorn/no-useless-fallback-in-spread": "off",

apps/desktop-ui/src/i18n.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import en from '@frontend-locales/en/main.json' with { type: 'json' }
99
import enNodes from '@frontend-locales/en/nodeDefs.json' with { type: 'json' }
1010

1111
import enSettings from '@frontend-locales/en/settings.json' with { type: 'json' }
12+
import { getDefaultLocale } from '@frontend-locales/localeConfig'
1213
import { createI18n } from 'vue-i18n'
1314

1415
function buildLocale<
@@ -167,7 +168,7 @@ const messages: Record<string, LocaleMessages> = {
167168
export const i18n = createI18n({
168169
// Must set `false`, as Vue I18n Legacy API is for Vue 2
169170
legacy: false,
170-
locale: navigator.language.split('-')[0] || 'en',
171+
locale: getDefaultLocale(),
171172
fallbackLocale: 'en',
172173
messages,
173174
// Ignore warnings for locale options as each option is in its own language.

apps/website/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ git commit apps/website/src/data/ashby-roles.snapshot.json
113113
The script exits non-zero on any non-fresh outcome so stale/empty
114114
snapshots can't be accidentally committed.
115115

116+
## Cloud nodes integration
117+
118+
`/cloud/supported-nodes` (and `/zh-CN/`) lists custom-node packs preinstalled on Comfy Cloud, joined with public metadata from the [ComfyUI Custom Node Registry](https://registry.comfy.org) ([`api.comfy.org`](https://api.comfy.org)). See [`src/pages/cloud/supported-nodes/AGENTS.md`](src/pages/cloud/supported-nodes/AGENTS.md) for the build pipeline, source-file map, and key invariants.
119+
120+
Build-time env var: `WEBSITE_CLOUD_API_KEY` (Cloud `/api/object_info` auth; the build falls back to the committed snapshot when unset). Must also be set in the Vercel project environment.
121+
116122
## HubSpot contact form
117123

118124
The contact page uses HubSpot's hosted form embed for the interest form:
@@ -146,3 +152,4 @@ renders the documented embed container.
146152
- `pnpm test:unit` — Vitest unit tests
147153
- `pnpm test:e2e` — Playwright E2E tests (requires `pnpm build` first)
148154
- `pnpm ashby:refresh-snapshot` — refresh the committed careers snapshot
155+
- `pnpm cloud-nodes:refresh-snapshot` — refresh the committed cloud nodes snapshot

0 commit comments

Comments
 (0)