diff --git a/.claude/commands/create-frontend-release.md b/.claude/commands/create-frontend-release.md
index bbd6578c00..f1aa3e9f14 100644
--- a/.claude/commands/create-frontend-release.md
+++ b/.claude/commands/create-frontend-release.md
@@ -244,21 +244,21 @@ echo "Last stable release: $LAST_STABLE"
1. Run complete test suite:
```bash
- npm run test:unit
- npm run test:component
+ pnpm test:unit
+ pnpm test:component
```
2. Run type checking:
```bash
- npm run typecheck
+ pnpm typecheck
```
3. Run linting (may have issues with missing packages):
```bash
- npm run lint || echo "Lint issues - verify if critical"
+ pnpm lint || echo "Lint issues - verify if critical"
```
4. Test build process:
```bash
- npm run build
- npm run build:types
+ pnpm build
+ pnpm build:types
```
5. **QUALITY GATE**: All tests and builds passing?
@@ -488,7 +488,7 @@ echo "Workflow triggered. Waiting for PR creation..."
```bash
# Check npm availability
for i in {1..10}; do
- if npm view @comfyorg/comfyui-frontend-types@${NEW_VERSION} version >/dev/null 2>&1; then
+ if pnpm view @comfyorg/comfyui-frontend-types@${NEW_VERSION} version >/dev/null 2>&1; then
echo "✅ npm package available"
break
fi
diff --git a/.claude/commands/create-hotfix-release.md b/.claude/commands/create-hotfix-release.md
index 5dd2946985..de314309db 100644
--- a/.claude/commands/create-hotfix-release.md
+++ b/.claude/commands/create-hotfix-release.md
@@ -80,7 +80,7 @@ For each commit:
- **CONFIRMATION REQUIRED**: Conflicts resolved correctly?
3. After successful cherry-pick:
- Show the changes: `git show HEAD`
- - Run validation: `npm run typecheck && npm run lint`
+ - Run validation: `pnpm typecheck && pnpm lint`
4. **CONFIRMATION REQUIRED**: Cherry-pick successful and valid?
### Step 6: Create PR to Core Branch
@@ -197,7 +197,7 @@ For each commit:
5. Track progress:
- GitHub release draft/publication
- PyPI upload
- - npm types publication
+ - pnpm types publication
### Step 12: Post-Release Verification
@@ -211,7 +211,7 @@ For each commit:
```
3. Verify npm package:
```bash
- npm view @comfyorg/comfyui-frontend-types@1.23.5
+ pnpm view @comfyorg/comfyui-frontend-types@1.23.5
```
4. Generate release summary with:
- Version released
diff --git a/.claude/commands/verify-visually.md b/.claude/commands/verify-visually.md
index 6a6c63eaa8..66260b159f 100644
--- a/.claude/commands/verify-visually.md
+++ b/.claude/commands/verify-visually.md
@@ -5,7 +5,7 @@ Follow these steps systematically to verify our changes:
1. **Server Setup**
- Check if the dev server is running on port 5173 using browser navigation or port checking
- - If not running, start it with `npm run dev` from the root directory
+ - If not running, start it with `pnpm dev` from the root directory
- If the server fails to start, provide detailed troubleshooting steps by reading package.json and README.md for accurate instructions
- Wait for the server to be fully ready before proceeding
diff --git a/.gitattributes b/.gitattributes
index af4b6adbc9..749554ee14 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2,9 +2,13 @@
* text=auto
# Force TS to LF to make the unixy scripts not break on Windows
+*.cjs text eol=lf
+*.js text eol=lf
+*.json text eol=lf
+*.mjs text eol=lf
+*.mts text eol=lf
*.ts text eol=lf
*.vue text eol=lf
-*.js text eol=lf
# Generated files
src/types/comfyRegistryTypes.ts linguist-generated=true
diff --git a/.github/workflows/chromatic.yaml b/.github/workflows/chromatic.yaml
index 558f04fee9..ed2314e80a 100644
--- a/.github/workflows/chromatic.yaml
+++ b/.github/workflows/chromatic.yaml
@@ -3,14 +3,15 @@ name: 'Chromatic'
# - [Automate Chromatic with GitHub Actions • Chromatic docs]( https://www.chromatic.com/docs/github-actions/ )
on:
- push:
- branches: [main]
+ workflow_dispatch: # Allow manual triggering
pull_request:
branches: [main]
jobs:
chromatic-deployment:
runs-on: ubuntu-latest
+ # Only run for PRs from version-bump-* branches or manual triggers
+ if: github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'version-bump-')
permissions:
pull-requests: write
issues: write
@@ -20,11 +21,16 @@ jobs:
with:
fetch-depth: 0 # Required for Chromatic baseline
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- cache: 'npm'
+ cache: 'pnpm'
- name: Get current time
id: current-time
@@ -32,6 +38,7 @@ jobs:
- name: Comment PR - Build Started
if: github.event_name == 'pull_request'
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -49,8 +56,21 @@ jobs:
---
*This comment will be updated when the build completes*
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ storybook-static
+ tsconfig.tsbuildinfo
+ key: storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.{ts,vue,js}', '*.config.*', '.storybook/**/*') }}
+ restore-keys: |
+ storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
+ storybook-cache-${{ runner.os }}-
+ storybook-tools-cache-${{ runner.os }}-
+
- name: Install dependencies
- run: npm ci
+ run: pnpm install --frozen-lockfile
- name: Build Storybook and run Chromatic
id: chromatic
@@ -68,6 +88,7 @@ jobs:
- name: Comment PR - Build Complete
if: github.event_name == 'pull_request' && always()
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
diff --git a/.github/workflows/claude-pr-review.yml b/.github/workflows/claude-pr-review.yml
index 5b0c0ffbd1..3ec61cb3c2 100644
--- a/.github/workflows/claude-pr-review.yml
+++ b/.github/workflows/claude-pr-review.yml
@@ -53,14 +53,20 @@ jobs:
with:
fetch-depth: 0
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
+ cache: 'pnpm'
- name: Install dependencies for analysis tools
run: |
- npm install -g typescript @vue/compiler-sfc
+ pnpm install -g typescript @vue/compiler-sfc
- name: Run Claude PR Review
uses: anthropics/claude-code-action@main
diff --git a/.github/workflows/dev-release.yaml b/.github/workflows/dev-release.yaml
index 177c01df92..0b45420c64 100644
--- a/.github/workflows/dev-release.yaml
+++ b/.github/workflows/dev-release.yaml
@@ -16,9 +16,26 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ dist
+ tsconfig.tsbuildinfo
+ key: dev-release-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ dev-release-tools-cache-${{ runner.os }}-
+
- name: Get current version
id: current_version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
@@ -29,9 +46,9 @@ jobs:
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
USE_PROD_CONFIG: 'true'
run: |
- npm ci
- npm run build
- npm run zipdist
+ pnpm install --frozen-lockfile
+ pnpm build
+ pnpm zipdist
- name: Upload dist artifact
uses: actions/upload-artifact@v4
with:
diff --git a/.github/workflows/i18n-custom-nodes.yaml b/.github/workflows/i18n-custom-nodes.yaml
index 8d2c354996..a5617c1964 100644
--- a/.github/workflows/i18n-custom-nodes.yaml
+++ b/.github/workflows/i18n-custom-nodes.yaml
@@ -42,9 +42,14 @@ jobs:
with:
repository: ${{ inputs.owner }}/${{ inputs.repository }}
path: 'ComfyUI/custom_nodes/${{ inputs.repository }}'
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
+ cache: 'pnpm'
- uses: actions/setup-python@v4
with:
python-version: '3.10'
@@ -63,8 +68,8 @@ jobs:
working-directory: ComfyUI/custom_nodes/${{ inputs.repository }}
- name: Build & Install ComfyUI_frontend
run: |
- npm ci
- npm run build
+ pnpm install --frozen-lockfile
+ pnpm build
rm -rf ../ComfyUI/web/*
mv dist/* ../ComfyUI/web/
working-directory: ComfyUI_frontend
@@ -79,18 +84,18 @@ jobs:
- name: Start dev server
# Run electron dev server as it is a superset of the web dev server
# We do want electron specific UIs to be translated.
- run: npm run dev:electron &
+ run: pnpm dev:electron &
working-directory: ComfyUI_frontend
- name: Capture base i18n
run: npx tsx scripts/diff-i18n capture
working-directory: ComfyUI_frontend
- name: Update en.json
- run: npm run collect-i18n
+ run: pnpm collect-i18n
env:
PLAYWRIGHT_TEST_URL: http://localhost:5173
working-directory: ComfyUI_frontend
- name: Update translations
- run: npm run locale
+ run: pnpm locale
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
working-directory: ComfyUI_frontend
diff --git a/.github/workflows/i18n-node-defs.yaml b/.github/workflows/i18n-node-defs.yaml
index 3e672cbd1a..1327db3cf7 100644
--- a/.github/workflows/i18n-node-defs.yaml
+++ b/.github/workflows/i18n-node-defs.yaml
@@ -13,22 +13,22 @@ jobs:
update-locales:
runs-on: ubuntu-latest
steps:
- - uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
+ - uses: Comfy-Org/ComfyUI_frontend_setup_action@v3
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
- name: Start dev server
# Run electron dev server as it is a superset of the web dev server
# We do want electron specific UIs to be translated.
- run: npm run dev:electron &
+ run: pnpm dev:electron &
working-directory: ComfyUI_frontend
- name: Update en.json
- run: npm run collect-i18n -- scripts/collect-i18n-node-defs.ts
+ run: pnpm collect-i18n -- scripts/collect-i18n-node-defs.ts
env:
PLAYWRIGHT_TEST_URL: http://localhost:5173
working-directory: ComfyUI_frontend
- name: Update translations
- run: npm run locale
+ run: pnpm locale
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
working-directory: ComfyUI_frontend
diff --git a/.github/workflows/i18n.yaml b/.github/workflows/i18n.yaml
index 3482e74c6f..2f332e9dcb 100644
--- a/.github/workflows/i18n.yaml
+++ b/.github/workflows/i18n.yaml
@@ -1,37 +1,45 @@
name: Update Locales
on:
+ # Manual dispatch for urgent translation updates
+ workflow_dispatch:
+ # Only trigger on PRs to main/master - additional branch filtering in job condition
pull_request:
- branches: [ main, master, dev* ]
- paths-ignore:
- - '.github/**'
- - '.husky/**'
- - '.vscode/**'
- - 'browser_tests/**'
- - 'tests-ui/**'
+ branches: [ main ]
+ types: [opened, synchronize, reopened]
jobs:
update-locales:
- # Don't run on fork PRs
- if: github.event.pull_request.head.repo.full_name == github.repository
+ # Branch detection: Only run for manual dispatch or version-bump-* branches from main repo
+ if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'version-bump-'))
runs-on: ubuntu-latest
steps:
- - uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
+ - uses: Comfy-Org/ComfyUI_frontend_setup_action@v3
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ ComfyUI_frontend/.cache
+ ComfyUI_frontend/.cache
+ key: i18n-tools-cache-${{ runner.os }}-${{ hashFiles('ComfyUI_frontend/pnpm-lock.yaml') }}
+ restore-keys: |
+ i18n-tools-cache-${{ runner.os }}-
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
- name: Start dev server
# Run electron dev server as it is a superset of the web dev server
# We do want electron specific UIs to be translated.
- run: npm run dev:electron &
+ run: pnpm dev:electron &
working-directory: ComfyUI_frontend
- name: Update en.json
- run: npm run collect-i18n -- scripts/collect-i18n-general.ts
+ run: pnpm collect-i18n -- scripts/collect-i18n-general.ts
env:
PLAYWRIGHT_TEST_URL: http://localhost:5173
working-directory: ComfyUI_frontend
- name: Update translations
- run: npm run locale
+ run: pnpm locale
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
working-directory: ComfyUI_frontend
diff --git a/.github/workflows/lint-and-format.yaml b/.github/workflows/lint-and-format.yaml
index 5d9a50d834..b715328db9 100644
--- a/.github/workflows/lint-and-format.yaml
+++ b/.github/workflows/lint-and-format.yaml
@@ -19,20 +19,40 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- cache: 'npm'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ .eslintcache
+ tsconfig.tsbuildinfo
+ .prettierCache
+ .knip-cache
+ key: lint-format-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.{ts,vue,js,mts}', '*.config.*', '.eslintrc.*', '.prettierrc.*', 'tsconfig.json') }}
+ restore-keys: |
+ lint-format-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
+ lint-format-cache-${{ runner.os }}-
+ ci-tools-cache-${{ runner.os }}-
- name: Install dependencies
- run: npm ci
+ run: pnpm install --frozen-lockfile
- name: Run ESLint with auto-fix
- run: npm run lint:fix
+ run: pnpm lint:fix
- name: Run Prettier with auto-format
- run: npm run format
+ run: pnpm format
- name: Check for changes
id: verify-changed-files
@@ -54,12 +74,13 @@ jobs:
- name: Final validation
run: |
- npm run lint
- npm run format:check
- npm run knip
+ pnpm lint
+ pnpm format:check
+ pnpm knip
- name: Comment on PR about auto-fix
if: steps.verify-changed-files.outputs.changed == 'true' && github.event.pull_request.head.repo.full_name == github.repository
+ continue-on-error: true
uses: actions/github-script@v7
with:
script: |
@@ -72,6 +93,7 @@ jobs:
- name: Comment on PR about manual fix needed
if: steps.verify-changed-files.outputs.changed == 'true' && github.event.pull_request.head.repo.full_name != github.repository
+ continue-on-error: true
uses: actions/github-script@v7
with:
script: |
@@ -79,5 +101,5 @@ jobs:
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
- body: '## ⚠️ Linting/Formatting Issues Found\n\nThis PR has linting or formatting issues that need to be fixed.\n\n**Since this PR is from a fork, auto-fix cannot be applied automatically.**\n\n### Option 1: Set up pre-commit hooks (recommended)\nRun this once to automatically format code on every commit:\n```bash\nnpm run prepare\n```\n\n### Option 2: Fix manually\nRun these commands and push the changes:\n```bash\nnpm run lint:fix\nnpm run format\n```\n\nSee [CONTRIBUTING.md](https://github.com/Comfy-Org/ComfyUI_frontend/blob/main/CONTRIBUTING.md#git-pre-commit-hooks) for more details.'
+ body: '## ⚠️ Linting/Formatting Issues Found\n\nThis PR has linting or formatting issues that need to be fixed.\n\n**Since this PR is from a fork, auto-fix cannot be applied automatically.**\n\n### Option 1: Set up pre-commit hooks (recommended)\nRun this once to automatically format code on every commit:\n```bash\npnpm prepare\n```\n\n### Option 2: Fix manually\nRun these commands and push the changes:\n```bash\npnpm lint:fix\npnpm format\n```\n\nSee [CONTRIBUTING.md](https://github.com/Comfy-Org/ComfyUI_frontend/blob/main/CONTRIBUTING.md#git-pre-commit-hooks) for more details.'
})
\ No newline at end of file
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 55c0881635..8958ce1470 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -19,9 +19,25 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ tsconfig.tsbuildinfo
+ key: release-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ release-tools-cache-${{ runner.os }}-
+
- name: Get current version
id: current_version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
@@ -41,9 +57,9 @@ jobs:
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
USE_PROD_CONFIG: 'true'
run: |
- npm ci
- npm run build
- npm run zipdist
+ pnpm install --frozen-lockfile
+ pnpm build
+ pnpm zipdist
- name: Upload dist artifact
uses: actions/upload-artifact@v4
with:
@@ -113,14 +129,31 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
+ cache: 'pnpm'
registry-url: https://registry.npmjs.org
- - run: npm ci
- - run: npm run build:types
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ tsconfig.tsbuildinfo
+ dist
+ key: types-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ types-tools-cache-${{ runner.os }}-
+
+ - run: pnpm install --frozen-lockfile
+ - run: pnpm build:types
- name: Publish package
- run: npm publish --access public
+ run: pnpm publish --access public
working-directory: dist
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/test-browser-exp.yaml b/.github/workflows/test-browser-exp.yaml
index 6f73174c1d..f260c2a3d8 100644
--- a/.github/workflows/test-browser-exp.yaml
+++ b/.github/workflows/test-browser-exp.yaml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
if: github.event.label.name == 'New Browser Test Expectations'
steps:
- - uses: Comfy-Org/ComfyUI_frontend_setup_action@v2.3
+ - uses: Comfy-Org/ComfyUI_frontend_setup_action@v3
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
diff --git a/.github/workflows/test-ui.yaml b/.github/workflows/test-ui.yaml
index 45a84d23a6..4c5e3d25c4 100644
--- a/.github/workflows/test-ui.yaml
+++ b/.github/workflows/test-ui.yaml
@@ -37,9 +37,16 @@ jobs:
path: 'ComfyUI/custom_nodes/ComfyUI_devtools'
ref: 'd05fd48dd787a4192e16802d4244cfcc0e2f9684'
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- uses: actions/setup-node@v4
with:
node-version: lts/*
+ cache: 'pnpm'
+ cache-dependency-path: 'ComfyUI_frontend/pnpm-lock.yaml'
- name: Get current time
id: current-time
@@ -47,6 +54,7 @@ jobs:
- name: Comment PR - Tests Started
if: github.event_name == 'pull_request'
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -64,10 +72,22 @@ jobs:
---
*This comment will be updated when tests complete*
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ ComfyUI_frontend/.cache
+ ComfyUI_frontend/tsconfig.tsbuildinfo
+ key: playwright-setup-cache-${{ runner.os }}-${{ hashFiles('ComfyUI_frontend/pnpm-lock.yaml') }}-${{ hashFiles('ComfyUI_frontend/src/**/*.{ts,vue,js}', 'ComfyUI_frontend/*.config.*') }}
+ restore-keys: |
+ playwright-setup-cache-${{ runner.os }}-${{ hashFiles('ComfyUI_frontend/pnpm-lock.yaml') }}-
+ playwright-setup-cache-${{ runner.os }}-
+ playwright-tools-cache-${{ runner.os }}-
+
- name: Build ComfyUI_frontend
run: |
- npm ci
- npm run build
+ pnpm install --frozen-lockfile
+ pnpm build
working-directory: ComfyUI_frontend
- name: Generate cache key
@@ -114,9 +134,15 @@ jobs:
ComfyUI_frontend
key: comfyui-setup-${{ needs.setup.outputs.cache-key }}
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- uses: actions/setup-python@v4
with:
python-version: '3.10'
+ cache: 'pip'
- name: Get current time
id: current-time
@@ -134,6 +160,7 @@ jobs:
- name: Comment PR - Browser Test Started
if: github.event_name == 'pull_request'
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -158,12 +185,21 @@ jobs:
wait-for-it --service 127.0.0.1:8188 -t 600
working-directory: ComfyUI
+ - name: Cache Playwright browsers
+ uses: actions/cache@v4
+ with:
+ path: ~/.cache/ms-playwright
+ key: playwright-browsers-${{ runner.os }}-${{ hashFiles('ComfyUI_frontend/pnpm-lock.yaml') }}-${{ matrix.browser }}
+ restore-keys: |
+ playwright-browsers-${{ runner.os }}-${{ hashFiles('ComfyUI_frontend/pnpm-lock.yaml') }}-
+ playwright-browsers-${{ runner.os }}-
+
- name: Install Playwright Browsers
run: npx playwright install chromium --with-deps
working-directory: ComfyUI_frontend
- name: Install Wrangler
- run: npm install -g wrangler
+ run: pnpm install -g wrangler
- name: Run Playwright tests (${{ matrix.browser }})
id: playwright
@@ -180,6 +216,7 @@ jobs:
- name: Deploy to Cloudflare Pages (${{ matrix.browser }})
id: cloudflare-deploy
if: always()
+ continue-on-error: true
run: |
# Retry logic for wrangler deploy (3 attempts)
RETRY_COUNT=0
@@ -238,6 +275,7 @@ jobs:
- name: Comment PR - Browser Test Complete
if: always() && github.event_name == 'pull_request'
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
@@ -323,6 +361,7 @@ jobs:
fi
- name: Comment PR - Tests Complete
+ continue-on-error: true
uses: edumserrano/find-create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
diff --git a/.github/workflows/update-electron-types.yaml b/.github/workflows/update-electron-types.yaml
index 2430cf5e59..04d8cc436c 100644
--- a/.github/workflows/update-electron-types.yaml
+++ b/.github/workflows/update-electron-types.yaml
@@ -14,19 +14,33 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- cache: 'npm'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ key: electron-types-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ electron-types-tools-cache-${{ runner.os }}-
- name: Update electron types
- run: npm install @comfyorg/comfyui-electron-types@latest
+ run: pnpm install @comfyorg/comfyui-electron-types@latest
- name: Get new version
id: get-version
run: |
- NEW_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('./package-lock.json')).packages['node_modules/@comfyorg/comfyui-electron-types'].version)")
+ NEW_VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('./pnpm-lock.yaml')).packages['node_modules/@comfyorg/comfyui-electron-types'].version)")
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Create Pull Request
diff --git a/.github/workflows/update-manager-types.yaml b/.github/workflows/update-manager-types.yaml
index 7933c7cbe2..8f3bf6cdb1 100644
--- a/.github/workflows/update-manager-types.yaml
+++ b/.github/workflows/update-manager-types.yaml
@@ -19,14 +19,36 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- cache: 'npm'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ key: update-manager-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ update-manager-tools-cache-${{ runner.os }}-
- name: Install dependencies
- run: npm ci
+ run: pnpm install --frozen-lockfile
+
+ - name: Cache ComfyUI-Manager repository
+ uses: actions/cache@v4
+ with:
+ path: ComfyUI-Manager
+ key: comfyui-manager-repo-${{ runner.os }}-${{ github.run_id }}
+ restore-keys: |
+ comfyui-manager-repo-${{ runner.os }}-
- name: Checkout ComfyUI-Manager repository
uses: actions/checkout@v4
@@ -64,7 +86,7 @@ jobs:
- name: Lint generated types
run: |
echo "Linting generated ComfyUI-Manager API types..."
- npm run lint:fix:no-cache -- ./src/types/generatedManagerTypes.ts
+ pnpm lint:fix:no-cache -- ./src/types/generatedManagerTypes.ts
- name: Check for changes
id: check-changes
diff --git a/.github/workflows/update-registry-types.yaml b/.github/workflows/update-registry-types.yaml
index 39a653697e..0cd2c41dae 100644
--- a/.github/workflows/update-registry-types.yaml
+++ b/.github/workflows/update-registry-types.yaml
@@ -18,14 +18,36 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- cache: 'npm'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ key: update-registry-tools-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ update-registry-tools-cache-${{ runner.os }}-
- name: Install dependencies
- run: npm ci
+ run: pnpm install --frozen-lockfile
+
+ - name: Cache comfy-api repository
+ uses: actions/cache@v4
+ with:
+ path: comfy-api
+ key: comfy-api-repo-${{ runner.os }}-${{ github.run_id }}
+ restore-keys: |
+ comfy-api-repo-${{ runner.os }}-
- name: Checkout comfy-api repository
uses: actions/checkout@v4
@@ -64,7 +86,7 @@ jobs:
- name: Lint generated types
run: |
echo "Linting generated Comfy Registry API types..."
- npm run lint:fix:no-cache -- ./src/types/comfyRegistryTypes.ts
+ pnpm lint:fix:no-cache -- ./src/types/comfyRegistryTypes.ts
- name: Check for changes
id: check-changes
diff --git a/.github/workflows/version-bump.yaml b/.github/workflows/version-bump.yaml
index 8e5f7042f6..77021e5c7c 100644
--- a/.github/workflows/version-bump.yaml
+++ b/.github/workflows/version-bump.yaml
@@ -26,16 +26,21 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- cache: 'npm'
+ cache: 'pnpm'
- name: Bump version
id: bump-version
run: |
- npm version ${{ github.event.inputs.version_type }} --preid ${{ github.event.inputs.pre_release }} --no-git-tag-version
+ pnpm version ${{ github.event.inputs.version_type }} --preid ${{ github.event.inputs.pre_release }} --no-git-tag-version
NEW_VERSION=$(node -p "require('./package.json').version")
echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT
diff --git a/.github/workflows/vitest.yaml b/.github/workflows/vitest.yaml
index 788b6aba4a..cba1dbe058 100644
--- a/.github/workflows/vitest.yaml
+++ b/.github/workflows/vitest.yaml
@@ -13,15 +13,34 @@ jobs:
steps:
- uses: actions/checkout@v4
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
+ cache: 'pnpm'
+
+ - name: Cache tool outputs
+ uses: actions/cache@v4
+ with:
+ path: |
+ .cache
+ coverage
+ .vitest-cache
+ key: vitest-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.{ts,vue,js}', 'vitest.config.*', 'tsconfig.json') }}
+ restore-keys: |
+ vitest-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
+ vitest-cache-${{ runner.os }}-
+ test-tools-cache-${{ runner.os }}-
- name: Install dependencies
- run: npm ci
+ run: pnpm install --frozen-lockfile
- name: Run Vitest tests
run: |
- npm run test:component
- npm run test:unit
+ pnpm test:component
+ pnpm test:unit
diff --git a/.gitignore b/.gitignore
index 8d19ceec56..c2e17be877 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,6 @@ lerna-debug.log*
# Package manager lockfiles (allow users to use different package managers)
bun.lock
bun.lockb
-pnpm-lock.yaml
yarn.lock
# Cache files
@@ -23,7 +22,6 @@ dist-ssr
*.local
# Claude configuration
.claude/*.local.json
-.claude/settings.json
# Editor directories and files
.vscode/*
diff --git a/.storybook/CLAUDE.md b/.storybook/CLAUDE.md
index a8a9371629..3877181a23 100644
--- a/.storybook/CLAUDE.md
+++ b/.storybook/CLAUDE.md
@@ -2,9 +2,9 @@
## Quick Commands
-- `npm run storybook`: Start Storybook development server
-- `npm run build-storybook`: Build static Storybook
-- `npm run test:component`: Run component tests (includes Storybook components)
+- `pnpm storybook`: Start Storybook development server
+- `pnpm build-storybook`: Build static Storybook
+- `pnpm test:component`: Run component tests (includes Storybook components)
## Development Workflow for Storybook
@@ -19,8 +19,8 @@
- Ensure proper theming and styling
3. **Code Quality**:
- - Run `npm run typecheck` to verify TypeScript
- - Run `npm run lint` to check for linting issues
+ - Run `pnpm typecheck` to verify TypeScript
+ - Run `pnpm lint` to check for linting issues
- Follow existing story patterns and conventions
## Story Creation Guidelines
@@ -138,13 +138,13 @@ The Storybook preview is configured with:
```bash
# Check TypeScript issues
-npm run typecheck
+pnpm typecheck
# Lint Storybook files
-npm run lint .storybook/
+pnpm lint .storybook/
# Build to check for production issues
-npm run build-storybook
+pnpm build-storybook
```
## File Organization
diff --git a/.storybook/README.md b/.storybook/README.md
index 902397471b..0d34474ecd 100644
--- a/.storybook/README.md
+++ b/.storybook/README.md
@@ -40,10 +40,10 @@ Storybook is a frontend workshop for building UI components and pages in isolati
```bash
# Start Storybook development server
-npm run storybook
+pnpm storybook
# Build static Storybook for deployment
-npm run build-storybook
+pnpm build-storybook
```
### Creating Stories
diff --git a/AGENTS.md b/AGENTS.md
index f01701cf44..5cec6b8109 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -8,19 +8,19 @@
- Config: `vite.config.mts`, `vitest.config.ts`, `playwright.config.ts`, `eslint.config.js`, `.prettierrc`.
## Build, Test, and Development Commands
-- `npm run dev`: Start Vite dev server.
-- `npm run dev:electron`: Dev server with Electron API mocks.
-- `npm run build`: Type-check then production build to `dist/`.
-- `npm run preview`: Preview the production build locally.
-- `npm run test:unit`: Run Vitest unit tests (`tests-ui/`).
-- `npm run test:component`: Run component tests (`src/components/`).
-- `npm run test:browser`: Run Playwright E2E tests (`browser_tests/`).
-- `npm run lint` / `npm run lint:fix`: Lint (ESLint). `npm run format` / `format:check`: Prettier.
-- `npm run typecheck`: Vue TSC type checking.
+- `pnpm dev`: Start Vite dev server.
+- `pnpm dev:electron`: Dev server with Electron API mocks.
+- `pnpm build`: Type-check then production build to `dist/`.
+- `pnpm preview`: Preview the production build locally.
+- `pnpm test:unit`: Run Vitest unit tests (`tests-ui/`).
+- `pnpm test:component`: Run component tests (`src/components/`).
+- `pnpm test:browser`: Run Playwright E2E tests (`browser_tests/`).
+- `pnpm lint` / `pnpm lint:fix`: Lint (ESLint). `pnpm format` / `format:check`: Prettier.
+- `pnpm typecheck`: Vue TSC type checking.
## Coding Style & Naming Conventions
- Language: TypeScript, Vue SFCs (`.vue`). Indent 2 spaces; single quotes; no semicolons; width 80 (see `.prettierrc`).
-- Imports: sorted/grouped by plugin; run `npm run format` before committing.
+- Imports: sorted/grouped by plugin; run `pnpm format` before committing.
- ESLint: Vue + TS rules; no floating promises; unused imports disallowed; i18n raw text restrictions in templates.
- Naming: Vue components in PascalCase (e.g., `MenuHamburger.vue`); composables `useXyz.ts`; Pinia stores `*Store.ts`.
@@ -33,7 +33,7 @@
## Commit & Pull Request Guidelines
- Commits: Prefer Conventional Commits (e.g., `feat(ui): add sidebar`), `refactor(litegraph): …`. Use `[skip ci]` for locale-only updates when appropriate.
- PRs: Include clear description, linked issues (`Fixes #123`), and screenshots/GIFs for UI changes. Add/adjust tests and i18n strings when applicable.
-- Quality gates: `npm run lint`, `npm run typecheck`, and relevant tests must pass. Keep PRs focused and small.
+- Quality gates: `pnpm lint`, `pnpm typecheck`, and relevant tests must pass. Keep PRs focused and small.
## Security & Configuration Tips
- Secrets: Use `.env` (see `.env_example`); do not commit secrets.
diff --git a/CLAUDE.md b/CLAUDE.md
index 2e15e3b17d..922d1f8531 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,13 +2,13 @@
## Quick Commands
-- `npm run`: See all available commands
-- `npm run typecheck`: Type checking
-- `npm run lint`: Linting
-- `npm run format`: Prettier formatting
-- `npm run test:component`: Run component tests with browser environment
-- `npm run test:unit`: Run all unit tests
-- `npm run test:unit -- tests-ui/tests/example.test.ts`: Run single test file
+- `pnpm`: See all available commands
+- `pnpm typecheck`: Type checking
+- `pnpm lint`: Linting
+- `pnpm format`: Prettier formatting
+- `pnpm test:component`: Run component tests with browser environment
+- `pnpm test:unit`: Run all unit tests
+- `pnpm test:unit -- tests-ui/tests/example.test.ts`: Run single test file
## Development Workflow
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c25dc96741..83b1951bc7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,7 +17,7 @@ Have another idea? Drop into Discord or open an issue, and let's chat!
### Prerequisites & Technology Stack
- **Required Software**:
- - Node.js (v16 or later; v20/v22 strongly recommended) and npm
+ - Node.js (v16 or later; v24 strongly recommended) and pnpm
- Git for version control
- A running ComfyUI backend instance
@@ -39,7 +39,7 @@ Have another idea? Drop into Discord or open an issue, and let's chat!
2. Install dependencies:
```bash
- npm install
+ pnpm install
```
3. Configure environment (optional):
@@ -57,13 +57,13 @@ python main.py --port 8188
### Git pre-commit hooks
-Run `npm run prepare` to install Git pre-commit hooks. Currently, the pre-commit hook is used to auto-format code on commit.
+Run `pnpm prepare` to install Git pre-commit hooks. Currently, the pre-commit hook is used to auto-format code on commit.
### Dev Server
- Start local ComfyUI backend at `localhost:8188`
-- Run `npm run dev` to start the dev server
-- Run `npm run dev:electron` to start the dev server with electron API mocked
+- Run `pnpm dev` to start the dev server
+- Run `pnpm dev:electron` to start the dev server with electron API mocked
#### Access dev server on touch devices
@@ -155,7 +155,7 @@ For ComfyUI_frontend development, you can ask coding assistants to use Playwrigh
##### Setup for Claude Code
-After installing dependencies with `npm i`, the Playwright MCP server will be automatically available when you start Claude Code locally.
+After installing dependencies with `pnpm i`, the Playwright MCP server will be automatically available when you start Claude Code locally.
Here's how Claude Code can use the Playwright MCP server to inspect the interface of the local development server (assuming you're running the dev server at `localhost:5173`):
@@ -210,14 +210,14 @@ Here's how Claude Code can use the Playwright MCP server to inspect the interfac
### Unit Tests
-- `npm i` to install all dependencies
-- `npm run test:unit` to execute all unit tests
+- `pnpm i` to install all dependencies
+- `pnpm test:unit` to execute all unit tests
### Component Tests
Component tests verify Vue components in `src/components/`.
-- `npm run test:component` to execute all component tests
+- `pnpm test:component` to execute all component tests
### Playwright Tests
@@ -228,12 +228,12 @@ Playwright tests verify the whole app. See [browser_tests/README.md](browser_tes
Before submitting a PR, ensure all tests pass:
```bash
-npm run test:unit
-npm run test:component
-npm run test:browser
-npm run typecheck
-npm run lint
-npm run format
+pnpm test:unit
+pnpm test:component
+pnpm test:browser
+pnpm typecheck
+pnpm lint
+pnpm format
```
## Code Style Guidelines
@@ -265,7 +265,7 @@ The project supports three types of icons, all with automatic imports (no manual
2. **Iconify Icons** - 200,000+ icons from various libraries: ``, ``
3. **Custom Icons** - Your own SVG icons: ``
-Icons are powered by the unplugin-icons system, which automatically discovers and imports icons as Vue components. Custom icons are stored in `src/assets/icons/custom/`.
+Icons are powered by the unplugin-icons system, which automatically discovers and imports icons as Vue components. Custom icons are stored in `src/assets/icons/custom/` and processed by `build/customIconCollection.ts` with automatic validation.
For detailed instructions and code examples, see [src/assets/icons/README.md](src/assets/icons/README.md).
diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts
index 738f5719c4..f64ca5c948 100644
--- a/browser_tests/fixtures/ComfyPage.ts
+++ b/browser_tests/fixtures/ComfyPage.ts
@@ -124,6 +124,7 @@ export class ComfyPage {
public readonly url: string
// All canvas position operations are based on default view of canvas.
public readonly canvas: Locator
+ public readonly selectionToolbox: Locator
public readonly widgetTextBox: Locator
// Buttons
@@ -158,6 +159,7 @@ export class ComfyPage {
) {
this.url = process.env.PLAYWRIGHT_TEST_URL || 'http://localhost:8188'
this.canvas = page.locator('#graph-canvas')
+ this.selectionToolbox = page.locator('.selection-toolbox')
this.widgetTextBox = page.getByPlaceholder('text').nth(1)
this.resetViewButton = page.getByRole('button', { name: 'Reset View' })
this.queueButton = page.getByRole('button', { name: 'Queue Prompt' })
diff --git a/browser_tests/fixtures/components/Topbar.ts b/browser_tests/fixtures/components/Topbar.ts
index b138ff7b74..f2c9dfa16f 100644
--- a/browser_tests/fixtures/components/Topbar.ts
+++ b/browser_tests/fixtures/components/Topbar.ts
@@ -65,6 +65,7 @@ export class Topbar {
}
async openTopbarMenu() {
+ await this.page.waitForTimeout(1000)
await this.page.locator('.comfyui-logo-wrapper').click()
const menu = this.page.locator('.comfy-command-menu')
await menu.waitFor({ state: 'visible' })
diff --git a/browser_tests/tests/customIcons.spec.ts b/browser_tests/tests/customIcons.spec.ts
new file mode 100644
index 0000000000..da640fd895
--- /dev/null
+++ b/browser_tests/tests/customIcons.spec.ts
@@ -0,0 +1,57 @@
+import { expect } from '@playwright/test'
+import type { Locator } from '@playwright/test'
+
+import { comfyPageFixture as test } from '../fixtures/ComfyPage'
+
+async function verifyCustomIconSvg(iconElement: Locator) {
+ const svgVariable = await iconElement.evaluate((element) => {
+ const styles = getComputedStyle(element)
+ return styles.getPropertyValue('--svg')
+ })
+
+ expect(svgVariable).toBeTruthy()
+ const dataUrlMatch = svgVariable.match(
+ /url\("data:image\/svg\+xml,([^"]+)"\)/
+ )
+ expect(dataUrlMatch).toBeTruthy()
+
+ const encodedSvg = dataUrlMatch![1]
+ const decodedSvg = decodeURIComponent(encodedSvg)
+
+ // Check for SVG header to confirm it's a valid SVG
+ expect(decodedSvg).toContain("