diff --git a/README.md b/README.md
index b7f0b6312..e6d1ad4cc 100644
--- a/README.md
+++ b/README.md
@@ -193,7 +193,53 @@ https://github.com/user-attachments/assets/c142c43f-2fe9-4030-8196-b3bfd4c6977d
https://github.com/user-attachments/assets/5696a89d-4a47-4fcc-9e8c-71e1264943f2
-### Node developers API
+### Developer APIs
+
+
+ v1.3.22: New settings API
+
+Legacy settings API.
+
+```js
+// Register a new setting
+app.ui.settings.addSetting({
+ id: 'TestSetting',
+ name: 'Test Setting',
+ type: 'text',
+ defaultValue: 'Hello, world!'
+})
+
+// Get the value of a setting
+const value = app.ui.settings.getSettingValue('TestSetting')
+
+// Set the value of a setting
+app.ui.settings.setSettingValue('TestSetting', 'Hello, universe!')
+```
+
+New settings API.
+
+```js
+// Register a new setting
+app.registerExtension({
+ name: 'TestExtension1',
+ settings: [
+ {
+ id: 'TestSetting',
+ name: 'Test Setting',
+ type: 'text',
+ defaultValue: 'Hello, world!'
+ }
+ ]
+})
+
+// Get the value of a setting
+const value = app.extensionManager.setting.get('TestSetting')
+
+// Set the value of a setting
+app.extensionManager.setting.set('TestSetting', 'Hello, universe!')
+```
+
+
v1.3.7: Register commands and keybindings
diff --git a/browser_tests/ComfyPage.ts b/browser_tests/ComfyPage.ts
index 7c4d13644..b4f92d669 100644
--- a/browser_tests/ComfyPage.ts
+++ b/browser_tests/ComfyPage.ts
@@ -528,7 +528,7 @@ export class ComfyPage {
async setSetting(settingId: string, settingValue: any) {
return await this.page.evaluate(
async ({ id, value }) => {
- await window['app'].ui.settings.setSettingValueAsync(id, value)
+ await window['app'].extensionManager.setting.set(id, value)
},
{ id: settingId, value: settingValue }
)
@@ -536,7 +536,7 @@ export class ComfyPage {
async getSetting(settingId: string) {
return await this.page.evaluate(async (id) => {
- return await window['app'].ui.settings.getSettingValue(id)
+ return await window['app'].extensionManager.setting.get(id)
}, settingId)
}
diff --git a/browser_tests/extensionAPI.spec.ts b/browser_tests/extensionAPI.spec.ts
index 4c028ab60..ff7977210 100644
--- a/browser_tests/extensionAPI.spec.ts
+++ b/browser_tests/extensionAPI.spec.ts
@@ -83,4 +83,23 @@ test.describe('Topbar commands', () => {
true
)
})
+
+ test('Should allow adding settings', async ({ comfyPage }) => {
+ await comfyPage.page.evaluate(() => {
+ window['app'].registerExtension({
+ name: 'TestExtension1',
+ settings: [
+ {
+ id: 'TestSetting',
+ name: 'Test Setting',
+ type: 'text',
+ defaultValue: 'Hello, world!'
+ }
+ ]
+ })
+ })
+ expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, world!')
+ await comfyPage.setSetting('TestSetting', 'Hello, universe!')
+ expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, universe!')
+ })
})
diff --git a/src/scripts/ui/settings.ts b/src/scripts/ui/settings.ts
index 5cade7b5b..8121f474b 100644
--- a/src/scripts/ui/settings.ts
+++ b/src/scripts/ui/settings.ts
@@ -169,6 +169,23 @@ export class ComfySettingsDialog extends ComfyDialog {
this.#dispatchChange(id, value)
}
+ /**
+ * Deprecated for external callers/extensions. Use `ComfyExtension.settings` field instead.
+ * Example:
+ * ```ts
+ * app.registerExtension({
+ * name: 'My Extension',
+ * settings: [
+ * {
+ * id: 'My.Setting',
+ * name: 'My Setting',
+ * type: 'text',
+ * defaultValue: 'Hello, world!'
+ * }
+ * ]
+ * })
+ * ```
+ */
addSetting(params: SettingParams) {
const {
id,
diff --git a/src/stores/extensionStore.ts b/src/stores/extensionStore.ts
index 440c3147d..dc02284f4 100644
--- a/src/stores/extensionStore.ts
+++ b/src/stores/extensionStore.ts
@@ -47,6 +47,7 @@ export const useExtensionStore = defineStore('extension', () => {
useKeybindingStore().loadExtensionKeybindings(extension)
useCommandStore().loadExtensionCommands(extension)
useMenuItemStore().loadExtensionMenuCommands(extension)
+ useSettingStore().loadExtensionSettings(extension)
/*
* Extensions are currently stored in both extensionStore and app.extensions.
diff --git a/src/stores/settingStore.ts b/src/stores/settingStore.ts
index c44957937..220271233 100644
--- a/src/stores/settingStore.ts
+++ b/src/stores/settingStore.ts
@@ -16,6 +16,7 @@ import { buildTree } from '@/utils/treeUtil'
import { defineStore } from 'pinia'
import type { TreeNode } from 'primevue/treenode'
import { CORE_SETTINGS } from '@/stores/coreSettings'
+import { ComfyExtension } from '@/types/comfy'
export interface SettingTreeNode extends TreeNode {
data?: SettingParams
@@ -68,6 +69,12 @@ export const useSettingStore = defineStore('setting', {
})
},
+ loadExtensionSettings(extension: ComfyExtension) {
+ extension.settings?.forEach((setting: SettingParams) => {
+ app.ui.settings.addSetting(setting)
+ })
+ },
+
async set(key: K, value: Settings[K]) {
this.settingValues[key] = value
await app.ui.settings.setSettingValueAsync(key, value)
diff --git a/src/stores/workspaceStateStore.ts b/src/stores/workspaceStateStore.ts
index 07127fd5d..32683c831 100644
--- a/src/stores/workspaceStateStore.ts
+++ b/src/stores/workspaceStateStore.ts
@@ -4,6 +4,7 @@ import { useToastStore } from './toastStore'
import { useQueueSettingsStore } from './queueStore'
import { useCommandStore } from './commandStore'
import { useSidebarTabStore } from './workspace/sidebarTabStore'
+import { useSettingStore } from './settingStore'
interface WorkspaceState {
spinner: boolean
@@ -30,6 +31,12 @@ export const useWorkspaceStore = defineStore('workspace', {
},
sidebarTab() {
return useSidebarTabStore()
+ },
+ setting() {
+ return {
+ get: useSettingStore().get,
+ set: useSettingStore().set
+ }
}
},
actions: {
diff --git a/src/types/comfy.d.ts b/src/types/comfy.d.ts
index ddec8d0e7..2e3b9c46b 100644
--- a/src/types/comfy.d.ts
+++ b/src/types/comfy.d.ts
@@ -3,6 +3,7 @@ import { ComfyApp } from '../scripts/app'
import type { ComfyNodeDef } from '@/types/apiTypes'
import type { Keybinding } from '@/types/keyBindingTypes'
import type { ComfyCommand } from '@/stores/commandStore'
+import { SettingParams } from './settingTypes'
export type Widgets = Record<
string,
@@ -43,6 +44,10 @@ export interface ComfyExtension {
* Menu commands to add to the menu bar
*/
menuCommands?: MenuCommandGroup[]
+ /**
+ * Settings to add to the settings menu
+ */
+ settings?: SettingParams[]
/**
* Allows any initialisation, e.g. loading resources. Called after the canvas is created but before nodes are added
* @param app The ComfyUI app instance
diff --git a/src/types/extensionTypes.ts b/src/types/extensionTypes.ts
index 1e71f6b11..5cfb393ab 100644
--- a/src/types/extensionTypes.ts
+++ b/src/types/extensionTypes.ts
@@ -37,9 +37,12 @@ export interface ExtensionManager {
unregisterSidebarTab(id: string): void
getSidebarTabs(): SidebarTabExtension[]
- // Toast
toast: ToastManager
command: CommandManager
+ setting: {
+ get: (id: string) => any
+ set: (id: string, value: any) => void
+ }
}
export interface CommandManager {