Merge remote-tracking branch 'origin/main' into vue-nodes-migration

This commit is contained in:
Benjamin Lu
2025-09-04 13:52:26 -07:00
440 changed files with 16610 additions and 5629 deletions

View File

@@ -1,12 +1,18 @@
import type { HTMLAttributes } from 'vue'
export type ButtonSize = 'fit-content' | 'sm' | 'md'
export type ButtonType = 'primary' | 'secondary' | 'transparent'
export type ButtonBorder = boolean
export interface BaseButtonProps {
size?: 'fit-content' | 'sm' | 'md'
type?: 'primary' | 'secondary' | 'transparent'
size?: ButtonSize
type?: ButtonType
border?: ButtonBorder
disabled?: boolean
class?: HTMLAttributes['class']
}
export const getButtonSizeClasses = (size: BaseButtonProps['size'] = 'md') => {
export const getButtonSizeClasses = (size: ButtonSize = 'md') => {
const sizeClasses = {
'fit-content': '',
sm: 'px-2 py-1.5 text-xs',
@@ -15,22 +21,39 @@ export const getButtonSizeClasses = (size: BaseButtonProps['size'] = 'md') => {
return sizeClasses[size]
}
export const getButtonTypeClasses = (
type: BaseButtonProps['type'] = 'primary'
) => {
const typeClasses = {
export const getButtonTypeClasses = (type: ButtonType = 'primary') => {
const baseByType = {
primary:
'bg-neutral-900 border-none text-white dark-theme:bg-white dark-theme:text-neutral-900',
secondary:
'bg-white border-none text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white',
transparent:
'bg-transparent border-none text-neutral-600 dark-theme:text-neutral-400'
} as const
return baseByType[type]
}
export const getBorderButtonTypeClasses = (type: ButtonType = 'primary') => {
const baseByType = {
primary:
'bg-neutral-900 text-white dark-theme:bg-white dark-theme:text-neutral-900',
secondary:
'bg-white text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white',
transparent: 'bg-transparent text-neutral-600 dark-theme:text-neutral-400'
}
return typeClasses[type]
} as const
const borderByType = {
primary: 'border border-solid border-white dark-theme:border-neutral-900',
secondary: 'border border-solid border-neutral-950 dark-theme:border-white',
transparent:
'border border-solid border-neutral-950 dark-theme:border-white'
} as const
return `${baseByType[type]} ${borderByType[type]}`
}
export const getIconButtonSizeClasses = (
size: BaseButtonProps['size'] = 'md'
) => {
export const getIconButtonSizeClasses = (size: ButtonSize = 'md') => {
const sizeClasses = {
'fit-content': 'w-auto h-auto',
sm: 'w-6 h-6 text-xs !rounded-md',
@@ -40,5 +63,9 @@ export const getIconButtonSizeClasses = (
}
export const getBaseButtonClasses = () => {
return 'flex items-center justify-center flex-shrink-0 outline-none border-none rounded-lg cursor-pointer transition-all duration-200'
return [
'flex items-center justify-center shrink-0',
'outline-hidden rounded-lg cursor-pointer transition-all duration-200',
'disabled:opacity-50 disabled:pointer-events-none'
].join(' ')
}

View File

@@ -1,11 +1,8 @@
import type { InjectionKey, Ref } from 'vue'
import type { ComfyWorkflowJSON } from '@/schemas/comfyWorkflowSchema'
import type { AlgoliaNodePack } from '@/types/algoliaTypes'
import type { components } from '@/types/comfyRegistryTypes'
import type { SearchMode } from '@/types/searchServiceTypes'
type WorkflowNodeProperties = ComfyWorkflowJSON['nodes'][0]['properties']
import type { components as managerComponents } from '@/types/generatedManagerTypes'
export type RegistryPack = components['schemas']['Node']
export type MergedNodePack = RegistryPack & AlgoliaNodePack
@@ -19,7 +16,7 @@ export const IsInstallingKey: InjectionKey<Ref<boolean>> =
Symbol('isInstalling')
export enum ManagerWsQueueStatus {
DONE = 'done',
DONE = 'all-done',
IN_PROGRESS = 'in_progress'
}
@@ -31,6 +28,47 @@ export enum ManagerTab {
UpdateAvailable = 'updateAvailable'
}
export interface TabItem {
id: ManagerTab
label: string
icon: string
}
export enum ManagerSortField {
Author = 'author',
CreateDate = 'creation_date',
LastUpdateDate = 'last_update',
Name = 'name',
Stars = 'stars',
Size = 'size'
}
export enum PackEnableState {
Enabled,
Disabled,
NotInstalled
}
export type TaskLog = {
taskName: string
taskId: string
logs: string[]
}
export interface ManagerQueueOptions {
maxConcurrent?: number
}
export interface UseNodePacksOptions {
immediate?: boolean
maxConcurrent?: number
}
export interface SearchOption<T> {
id: T
label: string
}
export enum SortableAlgoliaField {
Downloads = 'total_install',
Created = 'create_time',
@@ -39,206 +77,19 @@ export enum SortableAlgoliaField {
Name = 'name'
}
export interface TabItem {
id: ManagerTab
label: string
icon: string
}
export interface SearchOption<T> {
id: T
label: string
}
export type TaskLog = {
taskName: string
logs: string[]
}
export interface UseNodePacksOptions {
immediate?: boolean
maxConcurrent?: number
}
enum ManagerPackState {
/** Pack is installed and enabled */
INSTALLED = 'installed',
/** Pack is installed but disabled */
DISABLED = 'disabled',
/** Pack is not installed */
NOT_INSTALLED = 'not_installed',
/** Pack failed to import */
IMPORT_FAILED = 'import_failed',
/** Pack has an update available */
NEEDS_UPDATE = 'needs_update'
}
enum ManagerPackInstallType {
/** Installed via git clone */
GIT = 'git-clone',
/** Installed via file copy */
COPY = 'copy',
/** Installed from the Comfy Registry */
REGISTRY = 'cnr'
}
export enum SelectedVersion {
/** Latest version of the pack from the registry */
LATEST = 'latest',
/** Latest commit of the pack from its GitHub repository */
NIGHTLY = 'nightly'
}
export enum ManagerChannel {
/** All packs except those with instability or security issues */
DEFAULT = 'default',
/** Packs that were recently updated */
RECENT = 'recent',
/** Packs that were superseded by distinct replacements of some type */
LEGACY = 'legacy',
/** Packs that were forked as a result of the original pack going unmaintained */
FORKED = 'forked',
/** Packs with instability or security issues suitable only for developers */
DEV = 'dev',
/** Packs suitable for beginners */
TUTORIAL = 'tutorial'
}
export enum ManagerDatabaseSource {
/** Get pack info from the Comfy Registry */
REMOTE = 'remote',
/** If set to `local`, the channel is ignored */
LOCAL = 'local',
/** Get pack info from the cached response from the Comfy Registry (1 day TTL) */
CACHE = 'cache'
}
export interface ManagerQueueStatus {
/** `done_count` + `in_progress_count` + number of items queued */
total_count: number
/** Task worker thread is alive, a queued operation is running */
is_processing: boolean
/** Number of items in the queue that have been completed */
done_count: number
/** Number of items in the queue that are currently running */
in_progress_count: number
}
export interface ManagerPackInfo {
/** Either github-author/github-repo or name of pack from the registry (not id) */
id: WorkflowNodeProperties['aux_id'] | WorkflowNodeProperties['cnr_id']
/** Semantic version or Git commit hash */
version: WorkflowNodeProperties['ver']
}
export interface ManagerPackInstalled {
/**
* The version of the pack that is installed.
* Git commit hash or semantic version.
*/
ver: WorkflowNodeProperties['ver']
/**
* The name of the pack if the pack is installed from the registry.
* Corresponds to `Node#name` in comfy-api.
*/
cnr_id: WorkflowNodeProperties['cnr_id']
/**
* The name of the pack if the pack is installed from github.
* In the format author/repo-name. If the pack is installed from the registry, this is `null`.
*/
aux_id: WorkflowNodeProperties['aux_id'] | null
enabled: boolean
}
/**
* Returned by `/customnode/installed`
*/
export type InstalledPacksResponse = Record<
NonNullable<RegistryPack['name']>,
ManagerPackInstalled
>
/**
* Returned by `/customnode/getlist`
*/
export interface ManagerPack extends ManagerPackInfo {
/** Pack author name or 'Unclaimed' if the pack was added automatically via GitHub crawl. */
author: components['schemas']['Node']['author']
/** Files included in the pack */
files: string[]
/** The type of installation that was used to install the pack */
reference: string
/** The display name of the pack */
title: string
/** The latest version of the pack */
cnr_latest: SelectedVersion
/** The github link to the repository of the pack */
repository: string
/** The state of the pack */
state: ManagerPackState
/** The state of the pack update */
'update-state': 'false' | 'true' | null
/** The number of stars the pack has on GitHub. Distinct from registry stars */
stars: number
/**
* The last time the pack was updated. In ISO 8601 format.
* @example '2024-05-22 20:00:00'
*/
last_update: string
health: string
description: string
trust: boolean
install_type: ManagerPackInstallType
}
/**
* Returned by `/customnode/getmappings`.
*/
export type ManagerMappings = Record<
NonNullable<components['schemas']['Node']['name']>,
[
/** List of ComfyNode names included in the pack */
Array<components['schemas']['ComfyNode']['comfy_node_name']>,
{
/** The display name of the pack */
title_aux: string
}
]
>
/**
* Payload for `/manager/queue/install`
*/
export interface InstallPackParams extends ManagerPackInfo {
/**
* Semantic version, Git commit hash, `latest`, or `nightly`.
*/
selected_version: WorkflowNodeProperties['ver'] | SelectedVersion
/**
* The GitHub link to the repository of the pack to install.
* Required if `selected_version` is `nightly`.
*/
repository: string
/**
* List of PyPi dependency names associated with the pack.
* Used in coordination with pip package whitelist and version lock features.
*/
pip?: string[]
mode: ManagerDatabaseSource
channel: ManagerChannel
skip_post_install?: boolean
}
/**
* Params for `/manager/queue/update_all`
*/
export interface UpdateAllPacksParams {
mode?: ManagerDatabaseSource
}
export interface ManagerState {
selectedTabId: ManagerTab
searchQuery: string
searchMode: SearchMode
searchMode: 'nodes' | 'packs'
sortField: string
}
/**
* Types for import failure information API
*/
export type ImportFailInfoBulkRequest =
managerComponents['schemas']['ImportFailInfoBulkRequest']
export type ImportFailInfoBulkResponse =
managerComponents['schemas']['ImportFailInfoBulkResponse']
export type ImportFailInfoItem =
managerComponents['schemas']['ImportFailInfoItem']

View File

@@ -5142,7 +5142,7 @@ export interface components {
| 'doodle_fill'
| 'doodle_offset_fill'
| 'offset_fill'
| 'outline'
| 'outline-solid'
| 'outline_gradient'
| 'uneven_fill'
| '70s'

View File

@@ -0,0 +1,126 @@
/**
* Type definitions for the conflict detection system.
* These types are used to detect compatibility issues between Node Packs and the system environment.
*
* This file extends and uses types from comfyRegistryTypes.ts to maintain consistency
* with the Registry API schema.
*/
import type { components } from './comfyRegistryTypes'
// Re-export core types from Registry API
export type Node = components['schemas']['Node']
export type NodeVersion = components['schemas']['NodeVersion']
export type NodeStatus = components['schemas']['NodeStatus']
export type NodeVersionStatus = components['schemas']['NodeVersionStatus']
/**
* Conflict types that can be detected in the system
* @enum {string}
*/
export type ConflictType =
| 'comfyui_version' // ComfyUI version mismatch
| 'frontend_version' // Frontend version mismatch
| 'import_failed'
// | 'python_version' // Python version mismatch
| 'os' // Operating system incompatibility
| 'accelerator' // GPU/accelerator incompatibility
| 'banned' // Banned package
| 'pending' // Security verification pending
/**
* Version comparison operators
* @enum {string}
*/
export type VersionOperator = '>=' | '>' | '<=' | '<' | '==' | '!='
/**
* Version requirement specification
*/
export interface VersionRequirement {
/** @description Comparison operator for version checking */
operator: VersionOperator
/** @description Target version string */
version: string
}
/**
* Node Pack requirements from Registry API
* Extends Node type with additional installation and compatibility metadata
*/
export interface NodePackRequirements extends Node {
installed_version: string
is_enabled: boolean
is_banned: boolean
is_pending: boolean
// Aliases for backwards compatibility with existing code
version_status?: string
}
/**
* Current system environment information
*/
export interface SystemEnvironment {
// Version information
comfyui_version: string
frontend_version: string
// python_version: string
// Platform information
os: string
platform_details: string
architecture: string
// GPU/accelerator information
available_accelerators: Node['supported_accelerators']
primary_accelerator: string
gpu_memory_mb?: number
// Runtime information
node_env: 'development' | 'production'
user_agent: string
}
/**
* Individual conflict detection result for a package
*/
export interface ConflictDetectionResult {
package_id: string
package_name: string
has_conflict: boolean
conflicts: ConflictDetail[]
is_compatible: boolean
}
/**
* Detailed information about a specific conflict
*/
export interface ConflictDetail {
type: ConflictType
current_value: string
required_value: string
}
/**
* Overall conflict detection summary
*/
export interface ConflictDetectionSummary {
total_packages: number
compatible_packages: number
conflicted_packages: number
banned_packages: number
pending_packages: number
conflicts_by_type_details: Record<ConflictType, string[]>
last_check_timestamp: string
check_duration_ms: number
}
/**
* Response payload from conflict detection API
*/
export interface ConflictDetectionResponse {
success: boolean
error_message?: string
summary: ConflictDetectionSummary
results: ConflictDetectionResult[]
detected_system_environment?: Partial<SystemEnvironment>
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
import type { ComputedRef, InjectionKey } from 'vue'
export interface ImportFailedContext {
importFailed: ComputedRef<boolean>
showImportFailedDialog: () => void
}
export const ImportFailedKey: InjectionKey<ImportFailedContext> =
Symbol('ImportFailed')

View File

@@ -1,51 +0,0 @@
export type DefaultField = 'Workflow' | 'Logs' | 'SystemStats' | 'Settings'
export interface ReportField {
/**
* The label of the field, shown next to the checkbox if the field is opt-in.
*/
label: string
/**
* A unique identifier for the field, used internally as the key for this field's value.
*/
value: string
/**
* The data associated with this field, sent as part of the report.
*/
getData: () => unknown
/**
* Indicates whether the field requires explicit opt-in from the user
* before its data is included in the report.
*/
optIn: boolean
}
export interface IssueReportPanelProps {
/**
* The type of error being reported. This is used to categorize the error.
*/
errorType: string
/**
* Which of the default fields to include in the report.
*/
defaultFields?: DefaultField[]
/**
* Additional fields to include in the report.
*/
extraFields?: ReportField[]
/**
* Tags that will be added to the report. Tags are used to further categorize the error.
*/
tags?: Record<string, string>
/**
* The title displayed in the dialog.
*/
title?: string
}