- Replace activeWorkflow mock with LoadedComfyWorkflow type and double-cast
- Replace selectedItems mocks with Positionable type and double-cast
- Import Mock type from vitest for checkState mock
- Define MockSettingStore interface with proper Mock types
- Create mockSettingStoreTyped with double-cast to useSettingStore return type
- Replace all mockSettingStore usages in initializeIfNewUser calls
- Import useSettingStore type from correct path
- Define MockSearchClient interface with search: Mock property
- Replace mockSearchClient: any with MockSearchClient type
- Apply double-cast when setting up mock return value
- Note: File still has other any instances for global properties and test casts
- Replace mockColorContext: any with proper MockColorContext interface
- Apply double-cast at draw() call sites to satisfy DefaultConnectionColors type
- Pattern: colorContext: mockColorContext as unknown as DefaultConnectionColors
- Replace `wrapper.vm as any` with properly typed ComponentInstance
- Define ComponentInstance type with error property
- Improve type safety for internal state access in tests
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `events: any[]` with properly typed `MockEvent[]`
- Define MockEvent interface matching the test data structure
- Improve type safety for event testing
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `props: any` with ComponentProps<typeof ApiKeyForm>
- Import ComponentProps from vue-component-type-helpers
- Linter optimized to direct ComponentProps usage
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `props: any` and return type with proper types
- Use Record<string, unknown> with ComponentProps cast
- Refactor tests to check FormItem component props instead of internal state
- Import ComponentProps from vue-component-type-helpers
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `props: any` with `Record<string, unknown>`
- Use ComponentProps type assertion for type safety
- Import ComponentProps from vue-component-type-helpers
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `as any` with proper `Mock` type from vitest
- Import Mock type and access mock.calls with type safety
- Explicitly type selectionCallback as `() => void`
- Break down mock access into steps for clarity
Part of Phase 2 - Quick wins (1 instance removed)
- Replace `props: any` with `Record<string, unknown>`
- Use ComponentProps type assertion for type safety
- Refactor tests to check input.element.value instead of internal state
- This tests actual DOM behavior rather than implementation details
Part of Phase 2 - Quick wins (1 instance removed)
Replaced any with Record<string, unknown> for mountComponent props parameter.
Uses as unknown as cast to allow testing edge cases with invalid prop types.
All tests passing (11/11), 0 typecheck errors.
Part of #8092
Removed all 14 any types from Pinia store mocks.
Changes:
- Replaced as any with as unknown as ReturnType<typeof store> pattern
- Removed as any from $state and _p properties (empty objects)
All tests passing (6/6), 0 typecheck errors.
Part of #8092
Replaced any with proper type for mockCanvas.
Changes:
- Typed mockCanvas as { selectedItems: Set<Positionable> }
- Added as unknown as Positionable casts for MockNode instances
- Added as unknown as cast for getCanvas mock return value
All tests passing (18/18), 0 typecheck errors.
Part of #8092
Removed all 3 any types and replaced with proper TypeScript types.
Changes:
- Replaced as any with as unknown as for partial mockCanvasStore
- Removed as any from null assignments (TypeScript infers correctly)
All tests passing (7/7), 0 typecheck errors.
Part of #8092
Removed all 7 any types by removing unnecessary type assertions.
TypeScript can infer return types correctly for mockImplementation
callbacks returning literal values.
All tests passing (8/8), 0 typecheck errors.
Part of #8092
Removed all 3 any types and replaced with proper TypeScript types.
Changes:
- Replaced as any with Partial<ReturnType<typeof useSettingStore>>
- Used as unknown as for partial mock subgraph (114+ missing properties)
All tests passing (3/3), 0 typecheck errors.
Part of #8092
Introduces `useFeatureUsageTracker` composable that tracks how many
times a user has used a specific feature, along with first and last
usage timestamps. Data persists to localStorage using `@vueuse/core`'s
`useStorage`. This composable provides the foundation for triggering
surveys after a configurable number of feature uses. Includes
comprehensive unit tests.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8175-feat-add-feature-usage-tracker-for-nightly-surveys-2ee6d73d36508118859ece6fcf17561d)
by [Unito](https://www.unito.io)
Removed all 11 any types and replaced with proper TypeScript types.
Changes:
- Typed executionStore mock with proper structure
- Typed workflowStore.activeWorkflow based on actual usage
- Replaced (settingStore.get as any) with vi.mocked(settingStore.get)
- Fixed vi.fn() signature to accept key parameter
All tests passing (8/9, 1 skipped), 0 typecheck errors.
Part of #8092
Extends the existing 'Show Advanced' button (previously subgraph-only)
to also appear on regular nodes that have widgets marked with
`options.advanced = true`.
## Changes
- Updates `showAdvancedInputsButton` computed to check for advanced
widgets on regular nodes
- Updates `handleShowAdvancedInputs` to set `node.showAdvanced = true`
and trigger canvas redraw for regular nodes
## Related
- Backend PR that adds `advanced` flag: comfyanonymous/ComfyUI#11939
- Canvas hide PR: feat/advanced-widgets-canvas-hide (this PR provides
the toggle for that)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8148-feat-canvas-show-Show-Advanced-button-on-nodes-with-advanced-widgets-2ec6d73d36508155a8adfa0a8ec84d46)
by [Unito](https://www.unito.io)
## Summary
Adds a compile-time `__IS_NIGHTLY__` constant that detects whether the
build is from the main branch (nightly) or a core/* branch (RC/stable).
The detection logic in vite.config.mts auto-detects based on
`GITHUB_REF_NAME === 'main'` in CI, with explicit override support via
`IS_NIGHTLY` environment variable. Exports `isNightly` from
`src/platform/distribution/types.ts` for use throughout the codebase.
Includes unit tests for the detection logic.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8149-feat-add-isNightly-build-flag-for-nightly-only-features-2ec6d73d365081c09930edec1c6644f5)
by [Unito](https://www.unito.io)
Removed all 5 any types and replaced with proper TypeScript types.
Changes:
- Replaced any with Partial<Load3d> for mock objects
- Used ReturnType<typeof useLoad3dService> for service mocks
- Used ReturnType<typeof useToastStore> for store mocks
- Used Load3d['sceneManager'] etc. for nested manager types
- Minimized type assertions to 2 necessary as unknown casts
Remaining type assertions:
- mockNode: Partial LGraphNode mock (constructor incompatible)
- sceneManager: Simplified gridHelper mock (vs 82+ Three.js properties)
Both mocks accurately reflect implementation usage patterns.
All tests passing (33/33), 0 typecheck errors.
Part of #8092
Replace all 8 `any` types with proper TypeScript types:
- Use proper function signatures in mock definitions
- Use JobListItem['state'] for state type assertion
- Use Partial<TaskItemImpl> for partial task mocks
- Use typed parameters for all mock functions (downloadFile, copyToClipboard, interrupt, deleteItem, etc.)
- Use Record<string, { id: string }> for nodeDefsByName
- Handle optional parameters correctly in downloadFile mock
All 36 tests passing, 0 typecheck errors.
## Summary
Continues the TypeScript strict typing improvements by removing `any`
types from core scripts and dialog components.
### Changes
**api.ts (6 instances)**
- Define `V1RawPrompt` and `CloudRawPrompt` tuple types for queue prompt
formats
- Export `QueueIndex`, `PromptInputs`, `ExtraData`, `OutputsToExecute`
from apiSchema
- Type `#postItem` body, `storeUserData` data, and `getCustomNodesI18n`
return
**groupNodeManage.ts (all @ts-expect-error removed)**
- Add `GroupNodeConfigEntry` interface to LGraph.ts
- Extend `GroupNodeWorkflowData` with `title`, `widgets_values`, and
typed `config`
- Type all class properties with definite assignment assertions
- Type all method parameters and event handlers
- Fix save button callback with proper generic types for node ordering
**changeTracker.ts (4 instances)**
- Type `nodeOutputs` as `Record<string, ExecutedWsMessage['output']>`
- Type prompt callback with `CanvasPointerEvent` and proper value types
**asyncDialog.ts and dialog.ts**
- Make `ComfyAsyncDialog` generic with `DialogAction<T>` type
- Type `ComfyDialog` constructor and show method parameters
- Update `ManageGroupDialog.show` signature to match base class
## Test plan
- [x] `pnpm typecheck` passes
- [x] `pnpm lint` passes
- [x] Sourcegraph checks for external usage
---
Related: Continues from #8083
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8092-Road-to-No-Explicit-Any-Part-7-Scripts-and-Dialog-Cleanup-2ea6d73d365081fbb890e73646a6ad16)
by [Unito](https://www.unito.io)
Replace all 10 `any` types with proper TypeScript types:
- Use IWidget for widget mocks with correct type properties
- Use Size for onResize handler parameter
- Use CanvasRenderingContext2D for onDrawBackground
- Use CanvasPointerEvent for mouse event handlers
- Use Partial<T> for partial mock objects (Load3d, LGraph, ToastStore)
- Use shallowRef for LGraphNode ref typing
- Replace type hacks (as unknown as never) with proper types
All tests passing, 0 typecheck errors.
## Summary
Optimizes the Manager dialog to use the cached `GET /nodes` endpoint
instead of `GET /nodes/search` for empty search queries (when the dialog
first opens). This significantly reduces Algolia usage since empty
searches account for the majority of search requests.
## Changes
- **registrySearchProvider.ts**: Modified `searchPacks()` to detect
empty queries and route them to `listAllPacks()` instead of `search()`
- **registrySearchProvider.test.ts**: Added 5 new test cases covering
empty query behavior
- Cache clearing now clears both `search` and `listAllPacks` caches
## Technical Details
**Empty Query Flow (NEW):**
- Query: `""` or whitespace
- Endpoint: `GET /nodes?limit=X&page=Y`
- Cache: Server-side cached (via omitting `latest` parameter)
- Result: Fast, cached node pack list
**Non-Empty Query Flow (UNCHANGED):**
- Query: Any non-empty string
- Endpoint: `GET /nodes/search?search=X` or `comfy_node_search=X`
- Result: Search results as before
## Testing
```bash
pnpm test:unit -- src/services/providers/registrySearchProvider.test.ts
pnpm typecheck
```
#8112 updated control widgets to be disabled when the controlled widget
is disabled. However, some workflows already exist that contain a
promoted control widget which does not function. This widget wouldn't be
marked as disabled (and thus, demoted) until the interior subgraph was
entered as updating `computedDisabled` is tacked to node draw. This is
fixed by having subgraphs eagerly update the `computedDisabled` state on
each node when configured.
Additionally, when `createCopyForNode` was used, linkedWidget retained
pointers to widgets which no longer have relation to the newly cloned
widget. This is resolved by instead not copying linkedWidgets.
Functionally, linkedWidgets is only used for control widgets and not
copying has the effect of ensuring that seed widgets linked to a
subgraph input will not display a control popover button in vue mode
which does nothing.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8160-Control-widget-fixes-2ed6d73d3650816cb397f83f558471b3)
by [Unito](https://www.unito.io)