34 Commits
Author SHA1 Message Date
Crystian 91b249cc82 Update README.md 2025-08-17 14:29:48 +02:00
Crystian b63c33ec0c console logs removed 2025-06-01 22:17:24 +02:00
Crystian c7913ae331 deprectaed 2025-06-01 22:08:01 +02:00
Crystian f73b704955 deprecated! 2025-06-01 22:00:25 +02:00
Crystian f5b3dbbb28 Merge pull request #6 from ComfyNodePRs/update-publish-yaml
Update Github Action for Publishing to Comfy Registry
2025-06-01 21:36:50 +02:00
snomiao 134d49ab56 chore(publish): update GitHub Actions workflow for node publishing with conditional execution and permissions adjustments 2025-01-25 04:53:54 +00:00
Crystian dfa85a3d08 visual fixes 2024-09-25 01:39:00 +02:00
Crystian 0f61271f66 update to crystools and horizontal ui 2024-09-23 16:18:29 +02:00
Crystian 9aca152235 new menu on settings 2024-09-21 14:54:31 +02:00
Crystian 29e1597acd Merge pull request #5 from ComfyNodePRs/licence-update
Update PyProject Toml - License
2024-07-31 22:06:26 +02:00
snomiao d7aa366338 chore(licence-update): Update PyProject Toml - License 2024-07-31 18:03:35 +00:00
Crystian e9fbea244e test of comfy org 2024-07-01 03:19:32 +02:00
Crystian 624ef9e9e2 test 2024-07-01 02:34:21 +02:00
Crystian 9e54d0fb2b test 2024-07-01 02:33:48 +02:00
Crystian 37059b31fe test of comfy.org hook 2024-07-01 02:29:32 +02:00
Crystian 49694e0aa6 test of comfy.org hook 2024-07-01 02:21:33 +02:00
Crystian 06d076fe1c comfyui org files added 2024-07-01 02:11:22 +02:00
Crystian ad643e21cc Merge pull request #4 from haohaocreates/pyproject
Add pyproject.toml for Custom Node Registry
2024-07-01 02:06:48 +02:00
Crystian 8c2978f51a Merge pull request #3 from haohaocreates/publish
Add Github Action for Publishing to Comfy Registry
2024-07-01 02:03:16 +02:00
haohaocreates 54a171db29 chore(pyproject): Add pyproject.toml for Custom Node Registry 2024-05-22 18:20:10 -04:00
haohaocreates 4a0fbba606 chore(publish): Add Github Action for Publishing to Comfy Registry 2024-05-22 18:20:07 -04:00
Crystian 5de5c44b94 console log removed 2024-01-28 15:37:51 +01:00
Crystian 1723a76eac fix for rerouter with primitives on load (the value was "undefined") 2024-01-19 20:48:17 +01:00
Crystian 7064725cd0 fix primitive values lost 2024-01-18 22:35:10 +01:00
Crystian 63bb685f0c Standardized names. 2024-01-15 22:47:39 +01:00
Crystian 68e41f7c02 fix issue #10 (inputs widgets reappear)
https://github.com/crystian/ComfyUI-Crystools/issues/10
2024-01-09 23:16:50 +01:00
Crystian 65bdafe91a fix new issue from comfyui update 2024-01-09 00:53:04 +01:00
Crystian b10a562e95 automatic version 2024-01-08 21:44:16 +01:00
Crystian e16488747a doc updated 2024-01-07 18:40:29 +01:00
Crystian 83f12613c8 doc updated 2024-01-07 18:37:07 +01:00
Crystian 4e0754860f label updated 2024-01-07 14:21:40 +01:00
Crystian f930967a8b doc updated 2024-01-05 01:31:55 +01:00
Crystian fadc5245a3 new feature: Show progress bar (on crystools) 2024-01-05 00:44:30 +01:00
Crystian bc332c2587 new feature: Show progress bar (on crystools) 2024-01-05 00:18:43 +01:00
13 changed files with 288 additions and 92 deletions
+23 -7
View File
@@ -7,20 +7,36 @@ assignees: ''
---
**Describe the bug**
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
**To Reproduce**
__Please attach a workflow file to make it easier for others to reproduce the error!__
**Expected behavior**
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Version:**
- ComfyUI Version
**Error in console:**
If applicable, add the error message from the console.
**Additional context**
**Versions:**
Copy the output of the console (4 parts), like this:
```
** Platform: Windows
** Python version: 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
```
```
Total VRAM 12287 MB, total RAM 130996 MB
Set vram state to: NORMAL_VRAM
Device: cuda:0 NVIDIA GeForce RTX 3080 Ti : cudaMallocAsync
```
```
### Loading: ComfyUI-Manager (V1.25.3)
### ComfyUI Revision: 1886 [6a10640f] | Released on '2024-01-08'
```
**Additional context**
Add any other context about the problem here.
+25
View File
@@ -0,0 +1,25 @@
name: Publish to Comfy registry
on:
workflow_dispatch:
push:
branches:
- main
paths:
- "pyproject.toml"
permissions:
issues: write
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'crystian' }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@v1
with:
## Add your own personal access token to your Github Repository secrets and reference it here.
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
+1
View File
@@ -153,3 +153,4 @@ cython_debug/
*.pyc
.idea
/node.zip
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
python .others/version.py
git add __init__.py pyproject.toml version
exit 0
+54
View File
@@ -0,0 +1,54 @@
import os
print("-- Setting up the version --")
versionLabel = "@version:"
version_file = os.path.join(os.path.dirname(__file__), "../version")
with open(version_file, "r") as f:
version = f.read().strip()
if version is None or version == "":
raise RuntimeError(f"File without version: {version_file}")
print(f"Version to set: {version}")
# modify the __init__.py file with @version
file1 = os.path.join(os.path.dirname(__file__), "../__init__.py")
print(f"> File1: {file1}")
file1VersionFound = False
# lines = None
with open(file1, "r") as f:
lines = f.readlines()
for line in lines:
if versionLabel in line:
file1VersionFound = True
lines[lines.index(line)] = f"{versionLabel} {version}\n"
if not file1VersionFound:
raise RuntimeError(f"Version label not found in file: {file1}")
with open(file1, "w") as f2:
f2.writelines(lines)
# modify pyproject.toml file with @version
file3 = os.path.join(os.path.dirname(__file__), "../pyproject.toml")
print(f"> File3: {file3}")
file3VersionFound = False
# lines = None
with open(file3, "r") as f:
lines = f.readlines()
for line in lines:
if "version = " in line:
file3VersionFound = True
lines[lines.index(line)] = f"version = \"{version}\"\n"
if not file3VersionFound:
raise RuntimeError(f"Version label not found in file: {file3}")
with open(file3, "w") as f3:
f3.writelines(lines)
+5 -2
View File
@@ -1,6 +1,6 @@
# ComfyUI-Crystools-save [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fcrystian%2FComfyUI-Crystools-save&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/crystian77)
[deprecated] # ComfyUI-Crystools-save [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fcrystian%2FComfyUI-Crystools-save&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://paypal.me/crystian77)
**_You can save your workflows with a particular file name (finally!), and save author info as metadata_**
🪛 **_You can save your workflows with a particular file name (finally!), and save author info as metadata_** 🪛
With this quality of life extension, you can save your workflow with a specific name and include additional details such as the author, a description, and the version (in metadata/json).
**Important:** When you share your workflow (via png/json), others will be able to see your information!
@@ -33,6 +33,9 @@ If you want to see the metadata, you can use the "[Crystools](https://github.com
* I used a specific field in metadata/json: "workflow.extra." I've created an "info" property to store this information. I don't know, and I haven't found any documentation about this, so I hope it's not a problem.
## Changelog
Because it is the same project for me, I will use the same changelog on that project [ComfyUI-Crystools](https://github.com/crystian/ComfyUI-Crystools?tab=readme-ov-file#changelog).
## Installation
+12 -12
View File
@@ -1,12 +1,12 @@
"""
@author: Crystian
@title: Crystools-save
@nickname: Crystools-save
@version: 1.0.0
@project: "https://github.com/crystian/ComfyUI-Crystools-save",
@description: With this quality of life extension, you can save your workflow with a specific name and include additional details such as the author, a description, and the version (in metadata/json) IG: https://www.instagram.com/crystian.ia
"""
WEB_DIRECTORY = "web"
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
"""
@author: Crystian
@title: Crystools-save
@nickname: Crystools-save
@version: 1.4.2
@project: "https://github.com/crystian/ComfyUI-Crystools-save",
@description: With this quality of life extension, you can save your workflow with a specific name and include additional details such as the author, a description, and the version (in metadata/json) IG: https://www.instagram.com/crystian.ia
"""
WEB_DIRECTORY = "web"
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

+14
View File
@@ -0,0 +1,14 @@
[project]
name = "comfyui-crystools-save"
description = "[Deprecated in favor of the new saving system] With this quality of life extension, you can save your workflow with a specific name and include additional details such as the author, a description, and the version (in metadata/json). Important: When you share your workflow (via png/json), others will be able to see your information!"
version = "1.4.2"
license = { file = "LICENSE" }
[project.urls]
Repository = "https://github.com/crystian/ComfyUI-Crystools-save"
# Used by Comfy Registry https://comfyregistry.org
[tool.comfy]
PublisherId = "crystian"
DisplayName = "ComfyUI-Crystools-save"
Icon = "https://raw.githubusercontent.com/crystian/ComfyUI-Crystools/main/docs/screwdriver.png"
+1
View File
@@ -0,0 +1 @@
1.4.2
+19
View File
@@ -0,0 +1,19 @@
export const commonPrefix = '🪛';
export function injectCss(href) {
if (document.querySelector(`link[href^='${href}']`)) {
return Promise.resolve();
}
return new Promise((resolve) => {
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
const timeout = setTimeout(resolve, 1000);
link.addEventListener('load', (_e) => {
clearInterval(timeout);
resolve();
});
link.href = href;
document.head.appendChild(link);
});
}
+32
View File
@@ -0,0 +1,32 @@
.comfy-menu #crystools-root {
/*background-color: red;*/
display: flex;
width: 100%;
flex-direction: column;
#crystools-project-input-container{
margin: 6px;
width: 100%;
order: 5;
input{
width: 80%;
}
}
}
.comfyui-menu #crystools-root {
/*background-color: red;*/
/*display: flex;*/
/*min-width: 300px;*/
#crystools-project-input-container{
margin: 6px;
/*width: 100%;*/
order: 5;
input{
width: 80px;
}
}
}
+96 -71
View File
@@ -1,6 +1,10 @@
import { app } from '../../../scripts/app.js';
import { $el } from '../../../scripts/ui.js';
import { app } from '../../scripts/app.js';
import { $el } from '../../scripts/ui.js';
import { commonPrefix, injectCss } from './common.js';
injectCss('extensions/ComfyUI-Crystools-save/save.css').then(() => {
// console.log('injectCss');
});
class CrystoolsSave {
// common variables
@@ -19,8 +23,9 @@ class CrystoolsSave {
defaultDescription = '';
defaultVersion = '1';
menuPrefix = '';
htmlIdCrystoolsMenu = 'crystools-menu';
menuPrefix = commonPrefix;
htmlIdCrystoolsRoot = 'crystools-root';
htmlIdCrystoolsInputContainer = 'crystools-project-input-container';
// references of htmls elements
inputRefProjectNameText = null;
@@ -35,49 +40,23 @@ class CrystoolsSave {
createSettings = () => {
/** Form on settings: (the order is important) */
// use new save button
// version
app.ui.settings.addSetting({
id: this.idNewSave,
name: this.menuPrefix + 'Use new save button? (requires page reload)',
type: 'boolean',
tooltip: 'This will replace the save button function and propose the name of project as filename!',
defaultValue: this.defaultNewSave,
onChange: this.saveFunctionSwitch,
});
// show the input on menu
app.ui.settings.addSetting({
id: this.idProjectNameShow,
name: this.menuPrefix + 'Show project name in menu',
type: 'boolean',
defaultValue: this.defaultProjectNameShow,
onChange: this.showProjectName,
});
// project name
app.ui.settings.addSetting({
id: this.idProjectNameText,
name: this.menuPrefix + 'Project name',
id: this.idVersion,
name: 'Version',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'version' ],
type: 'text',
defaultValue: this.defaultProjectNameText,
onChange: this.updateProjectName,
});
// author
app.ui.settings.addSetting({
id: this.idAuthor,
name: this.menuPrefix + 'Author',
type: 'text',
defaultValue: this.defaultAuthor,
defaultValue: this.defaultVersion,
onChange: (value) => {
this.updateInfoOnGraph({author: value});
this.updateInfoOnGraph({version: value});
},
});
// description
app.ui.settings.addSetting({
id: this.idDescription,
name: this.menuPrefix + 'Description',
name: 'Description',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'desc' ],
type: 'text',
defaultValue: this.defaultDescription,
onChange: (value) => {
@@ -85,50 +64,95 @@ class CrystoolsSave {
},
});
// version
// author
app.ui.settings.addSetting({
id: this.idVersion,
name: this.menuPrefix + 'Version',
id: this.idAuthor,
name: 'Author',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'author' ],
type: 'text',
defaultValue: this.defaultVersion,
defaultValue: this.defaultAuthor,
onChange: (value) => {
this.updateInfoOnGraph({version: value});
this.updateInfoOnGraph({author: value});
},
});
// project name
app.ui.settings.addSetting({
id: this.idProjectNameText,
name: 'Project name',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'name' ],
type: 'text',
defaultValue: this.defaultProjectNameText,
onChange: this.updateProjectName,
});
// use new save button
app.ui.settings.addSetting({
id: this.idNewSave,
name: 'New save button',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'new button' ],
type: 'boolean',
tooltip: 'This will replace the save button function and propose the name of project as filename! (requires page reload)',
defaultValue: this.defaultNewSave,
onChange: this.saveFunctionSwitch,
});
// show the input on menu
app.ui.settings.addSetting({
id: this.idProjectNameShow,
name: 'Show project name on menu',
category: ['Crystools', this.menuPrefix + ' [Deprecated] Save', 'menu' ],
type: 'boolean',
defaultValue: this.defaultProjectNameShow,
onChange: this.showProjectName,
});
};
setup() {
app.graph.onConfigure = (a) => {
// save the original onConfigure event
const onConfigure = app.graph.onConfigure;
app.graph.onConfigure = () => {
// when load a workflow from file pass here!
// on drops a file on the canvas
this.getInfoOnGraph().then((p) => {
onConfigure?.bind(this); // recall the original event
if (!p.workflow.extra.info) {
p.workflow.extra.info = {};
}
// this is a hack to wait the rerouters nodes created
setTimeout(() => {
this.getInfoOnGraph().then((p) => {
if (!p.workflow.extra.info) {
p.workflow.extra.info = {
name: this.defaultProjectNameText,
};
}
this.setInfoOnGraph(p.workflow.extra.info);
});
app.ui.settings.setSettingValue(this.idProjectNameText, p.workflow.extra.info.name);
this.setInfoOnGraph(p.workflow.extra.info);
});
}, 100);
};
const queueBtn = document.getElementById('queue-button');
const parentElement = document.getElementById('queue-button');
const ctools = document.createElement('div');
ctools.setAttribute('id', this.htmlIdCrystoolsMenu);
ctools.classList.add(this.htmlIdCrystoolsMenu);
ctools.classList.add('comfy-menu-btns');
ctools.style.margin = '8px 0';
ctools.style.width = '100%';
queueBtn.insertAdjacentElement('afterend', ctools);
let ctoolsRoot = document.getElementById(this.htmlIdCrystoolsRoot);
if(!ctoolsRoot){
ctoolsRoot = document.createElement('div');
ctoolsRoot.setAttribute('id', this.htmlIdCrystoolsRoot);
parentElement.insertAdjacentElement('afterend', ctoolsRoot);
}
const htmlContainer = document.createElement('div');
htmlContainer.setAttribute('id', this.htmlIdCrystoolsInputContainer);
ctoolsRoot.append(htmlContainer);
const projectNameInput = document.createElement('input');
projectNameInput.setAttribute('placeholder', 'Project name');
projectNameInput.style.width = '80%';
ctools.append(projectNameInput);
htmlContainer.append(projectNameInput);
this.inputRefProjectNameText = projectNameInput;
// events for the input to persist the data on workflow
projectNameInput.addEventListener('keyup', (event) => {
this.updateProjectName(event.target.value);
app.ui.settings.setSettingValue(this.idProjectNameText, event.target.value);
});
// this boolean does not save the value on workflow
@@ -144,32 +168,31 @@ class CrystoolsSave {
}
showProjectName = (value) => {
const ctools = document.getElementById(this.htmlIdCrystoolsMenu);
const container = document.getElementById(this.htmlIdCrystoolsInputContainer);
// validation because this run before setup
if (ctools) {
ctools.style.display = value ? 'block' : 'none';
if (container) {
container.style.display = value ? 'block' : 'none';
}
};
// just persist the data on workflow reference
setInfoOnGraph = (values) => {
// create the info object if not exists on workflow
let name = values?.name || this.defaultProjectNameText;
app.ui.settings.setSettingValue(this.idProjectNameText, name);
// app.ui.settings.setSettingValue(this.idProjectNameText, name);
values.name = name;
let author = values?.author || this.defaultAuthor;
app.ui.settings.setSettingValue(this.idAuthor, author);
// app.ui.settings.setSettingValue(this.idAuthor, author);
values.author = author;
let description = values?.description || this.defaultDescription;
app.ui.settings.setSettingValue(this.idDescription, description);
// app.ui.settings.setSettingValue(this.idDescription, description);
values.description = description;
let version = values?.version || this.defaultVersion;
app.ui.settings.setSettingValue(this.idVersion, version);
// app.ui.settings.setSettingValue(this.idVersion, version);
values.version = version;
if (!(values?.created)) {
@@ -201,14 +224,16 @@ class CrystoolsSave {
// just the name of project
updateProjectName = (value) => {
const ctools = document.getElementById(this.htmlIdCrystoolsMenu);
const ctools = document.getElementById(this.htmlIdCrystoolsInputContainer);
// validation because this run before setup
if (ctools && this.inputRefProjectNameText) {
this.getInfoOnGraph().then((p) => {
if (!p.workflow.extra.info) {
p.workflow.extra.info = {};
}
this.setInfoOnGraph(Object.assign(p.workflow.extra.info, {name: value}));
const finalValue = Object.assign(p.workflow.extra.info, {name: value});
// console.log(finalValue);
this.setInfoOnGraph(finalValue);
});
}
};