diff --git a/CHANGELOG.md b/CHANGELOG.md index ab72c6f..da7e6e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,38 @@ # Changelog -## Unreleased +## 1.1.0 (2026-09-26) + +Workflows now live in folders, like a shared drive, and sharing follows them. + +### Added + +- **Workspace folders**: a private **My files** folder per account (`users//`), **Shared** folders owned by whoever creates them, and common workflows at the top level. The server enforces them on ComfyUI's own file API, and ComfyUI's workflow browser lists only what you can open +- **Files** sidebar tab with **My files**, **Shared** and, for admins, **All** (the whole workflows folder); new folders, rename, move and delete; a green dot on live files; **From computer** +- **Save asks where**: a name plus the same folder tabs, starting in My files or the last folder used +- **Open from RigShare…** in the Workflow menu (Ctrl+Alt+O) +- Folder access lists: a shared folder's owner or an admin can restrict it to chosen people, each with view or edit. For a live workflow in a folder you own, *This tab* shows **Folder access** +- Only admins delete common workflows; a shared folder's owner deletes in that folder; you delete in yours +- Whole chat history: stored in `chat.jsonl` with no limit (`chat_keep` trims it). The panel shows the latest 50 messages and loads older ones as you scroll up, with date dividers. The old `chat.json` is imported once +- Test suite: pytest unit and end-to-end tests against a real aiohttp server, Node tests for the client, and a GitHub Actions workflow ### Changed -- Sharing follows folders: every saved workflow outside a private folder is live while it is open, with nothing to share by hand. Unsaved tabs and files in *My files* stay private -- The **Live** list shows the workflows someone has open right now, with their folder and who is in them; the Files tab marks live files -- A private workflow's panel offers **Move to Shared…** to take it live -- Deleting a live file closes it for the people who have it open (a snapshot is kept); moving one into a private folder takes it out of live sharing -- Renaming or moving a file or folder re-points everyone's open tabs to the new path, so nobody recreates it under the old name. People who can't open the new location are told nothing about it and keep a private copy - -- The Files tab has **My files**, **Shared** and, for admins, **All** tabs instead of a Home screen; the same tabs appear in the Open, Save and Move dialogs -- Who can open a workflow now follows its folder only. For a live workflow in a folder you own, *This tab* shows **Folder access** - -- Chat keeps its whole history (`chat.jsonl`, `chat_keep` to trim) instead of the last 200 messages. The panel shows the latest 50 and loads older ones as you scroll up, with date dividers. The old `chat.json` is imported once +- Sharing follows folders: every saved workflow outside a private folder is live while it is open, with nothing to share by hand. Unsaved tabs and files in My files stay private +- The **Live** tab lists the workflows someone has open right now, with their folder and who is in them. A private workflow's panel offers **Move to Shared…** +- Renaming or moving a workflow or folder keeps everyone's open tabs on it, under the new name. People who can't open the new location learn nothing about it and keep a private copy +- Deleting a live workflow closes it for the people who have it open, keeping a snapshot; moving one into a private folder takes it out of live sharing +- Who can open a workflow follows its folder only ### Fixed +- Opening a file could overwrite the shared workflow of the previous tab - Switching straight between the RigShare and Files sidebar tabs could leave the previous tab's content on screen ### Removed -- Per-workflow access lists (restrict the folder instead). Lists set on individual workflows before are dropped +- Per-workflow access lists (restrict the folder instead). Lists set on individual workflows are dropped - *Share this tab*, *Stop sharing*, the automatic-sharing settings and the admin 🗑 for idle rooms +- Live rooms for unsaved tabs (`tmp:`): save the workflow outside My files to work on it together ## 1.0.0 diff --git a/README.md b/README.md index c350391..fdd5ec0 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ # ComfyUI RigShare -> One ComfyUI rig, a whole team: accounts, live co-editing of every workflow, chat and a GPU monitor +> One ComfyUI rig, a whole team: accounts, shared folders, live co-editing, chat and a GPU monitor [![GitHub Release](https://img.shields.io/github/v/release/xiaodoudou/ComfyUI-RigShare?style=flat-square&color=e94560)](https://github.com/xiaodoudou/ComfyUI-RigShare/releases/latest) [![Stars](https://img.shields.io/github/stars/xiaodoudou/ComfyUI-RigShare?style=flat-square&color=yellow)](https://github.com/xiaodoudou/ComfyUI-RigShare/stargazers) [![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](LICENSE) [![ComfyUI](https://img.shields.io/badge/ComfyUI%20frontend-1.53%2B-7c3aed?style=flat-square)](docs/install.md) [![Python](https://img.shields.io/badge/Python-3.10%2B-3776ab?style=flat-square)](docs/install.md) [![Dependencies](https://img.shields.io/badge/Dependencies-none-brightgreen?style=flat-square)](docs/install.md) [![Auth](https://img.shields.io/badge/Auth-JWT%20%7C%20API%20keys-orange?style=flat-square)](docs/security.md) -A custom node that turns a single ComfyUI server into a shared workspace. Everyone signs in, opens any workflow, and edits it together in real time while seeing each other's cursors. Fork of +A custom node that turns a single ComfyUI server into a shared workspace. Everyone signs in, keeps their own workflows in a private folder, and edits the shared ones together in real time while seeing each other's cursors. Fork of [daxcay/ComfyUI-Nexus](https://github.com/daxcay/ComfyUI-Nexus), rewritten for the current ComfyUI frontend. @@ -18,14 +18,16 @@ A custom node that turns a single ComfyUI server into a shared workspace. Everyo ## What it does - asks everyone to sign in before ComfyUI loads, and creates the admin account on first run -- shares every workflow: people who open the same saved file edit it together, and unsaved tabs join as soon as you edit them -- lets you switch tabs freely, because only the tab on screen syncs +- organises workflows like a shared drive: a private **My files** folder per account, **Shared** folders, and an **All** view for admins, in a Files tab of its own +- asks where to save, with the same folders, and opens workflows from them (Ctrl+Alt+O) +- makes every workflow outside a private folder live while it is open: people who open the same file edit it together, with nothing to share by hand +- lets folder owners restrict a shared folder to chosen people, each able to view or edit +- lets you switch tabs freely, because only the tab on screen syncs, and keeps open tabs pointed at a workflow when someone renames or moves it - shows who is online and which workflow they are on, plus live cursors and selections - lets you follow someone, jumping to their tab and view -- keeps a chat with an unread badge, a blinking icon and a sound +- keeps the whole chat history, loading older messages as you scroll up, with an unread badge, a blinking icon and a sound - keeps per-workflow history: snapshots every few minutes, named snapshots, one-click restore - gives each account permissions to edit, queue, use ComfyUI Manager or administer, enforced by the server and not just hidden in the UI -- lets you restrict a workflow to chosen people, each able to view or edit - keeps simultaneous edits apart: two people adding or connecting nodes at the same moment both keep their work - issues personal API keys, so scripts and other apps can call ComfyUI with their owner's permissions - shows CPU, RAM, and for each GPU the load, VRAM, temperature and power, plus the queue, in a panel tab or a floating widget @@ -36,28 +38,32 @@ What this fork adds over Nexus: - **Built for the new frontend.** It lives in a sidebar tab and works with workflow tabs and subgraphs. It needs no legacy menu and no litegraph patching. - **Real accounts.** A login page, hashed passwords, JWT sessions and API keys replace the shared `/login account password` chat command and the plaintext `admins.json`. - **The server is in charge.** It checks permissions and identity on every message, so a browser cannot impersonate someone or edit without the right to. -- **Every workflow is shared**, not a single canvas that everybody fights over. +- **Folders, not one canvas.** Everyone has their own space, shared work lives in shared folders, and nobody fights over a single canvas. ## Screenshots - + + + + + - + + - - - - -
Workflows tab: this tab, history and shared workflows
Shared workflows and history
Live tab: the workflow on screen, its history and the live workflows
Live workflows and history
Files tab: My files, Shared and All
Files: My files, Shared, All
Shared folders in the Files tab
Shared folders, live files marked
People tab
Who is online, and on which workflow
Chat tab
Chat
Chat tab
Chat, with the whole history
Access list of a shared folder
Who can open a folder
Server tab
Server monitor
Account and API keys
Account and API keys
Admin tab
Accounts and server settings
Access list of a shared folder
Who can open a folder
+

+ Save dialog: name and location
Save asks where +

+

Floating server monitor over the canvas
Floating server monitor

@@ -77,6 +83,8 @@ git clone https://github.com/xiaodoudou/ComfyUI-RigShare.git Open ComfyUI in a browser. There are no accounts yet, so the login page asks you to create the administrator. Sign in, open the **RigShare** tab in the sidebar and add your team under **Admin → Accounts**. That is the whole setup. +Each person gets a private **My files** folder. Put what you work on together in **Shared**, in the **Files** tab: it goes live for everyone who opens it. + Everyone then signs in at the same address. To use the API from a script, create a key under your avatar → **API keys**: ```bash @@ -89,7 +97,8 @@ Behind a reverse proxy, turn on WebSocket support, or nothing will be live. See | | | |---|---| -| [Installing](docs/install.md) | Custom node, Docker/compose, first-run setup, upgrading from Nexus | +| [Installing](docs/install.md) | Custom node, Docker/compose, first-run setup, upgrading from 1.0 or Nexus | +| [Files and folders](docs/files.md) | My files, Shared, All, saving, opening, who can do what | | [Sharing workflows](docs/sharing.md) | Live workflows by folder, folder access, snapshots, follow | | [Accounts and permissions](docs/accounts.md) | Edit, Queue, Admin, renaming, what viewers can do | | [API access](docs/api.md) | API keys, websockets, trusted IPs, other apps such as Open WebUI | @@ -111,10 +120,11 @@ I run one ComfyUI box for several people. [ComfyUI-Nexus](https://github.com/dax - [x] Login page, JWT sessions, first-run admin setup - [x] Per-user API keys -- [x] Every workflow shared, per-workflow snapshots +- [x] Live co-editing of every shared workflow, per-workflow snapshots - [x] Cursors, selections, follow mode -- [x] Chat with badge, blink and sound +- [x] Chat with badge, blink and sound, whole history with scroll back - [x] Server monitor with floating widget - [x] Conflict-free node ids when two people add nodes at the same instant +- [x] Private folder per account, shared folders, Save asks where - [x] Folder access lists (share with specific people) -- [ ] Publish to the Comfy registry +- [x] Publish to the Comfy registry diff --git a/docs/files.md b/docs/files.md new file mode 100644 index 0000000..09a5531 --- /dev/null +++ b/docs/files.md @@ -0,0 +1,56 @@ +# Files and folders + +RigShare organises ComfyUI's workflows folder like a shared drive. Where a workflow is saved decides who can open it and whether it is live. See [Sharing workflows](sharing.md) for the live part. + +## The folders + +| Folder | On disk (`user/default/workflows/`) | Who can open it | +|---|---|---| +| **My files** | `users//` | You, plus admins. Created when you first sign in. | +| **Shared folders** | `shared//` | Everyone, or only the people the folder's owner chooses. | +| **Common workflows** | anything else at the top level | Everyone, with their account permissions. | + +- Workflows in My files are never live. Everything else is live while someone has it open. +- Renaming an account renames its private folder too, and open tabs follow. + +## The Files tab + +**Files** has its own icon in the sidebar, with three tabs: + +- **My files**: your private folder. +- **Shared**: the shared folders plus the common workflows at the top level. +- **All** (admins only): the whole workflows folder, including everyone's private folders. + + + + + + + +
My files
My files
Shared
Shared
All, for admins
All (admins)
+ +Click a workflow to open it. The Files tab marks live workflows with a green dot. **From computer** opens a workflow file from your machine, like ComfyUI's own *Open*. + +Hover a row for its actions: **Rename**, **Move to…**, **Delete**, and on a shared folder you own, 🔒 **Who can open it**. The folder button creates a folder. In the Shared tab it creates a shared folder that you own. + +## Saving + +

Save dialog

+ +**Save** (Ctrl+S) on a new workflow, and **Save As**, open a dialog with a name and the same three tabs. It starts in My files, or in the folder you last saved to. Pick any folder you can edit and click **Save here**. Clicking an existing workflow reuses its name, and ComfyUI asks before overwriting. + +## Opening + +- **Workflow → Open from RigShare…** (Ctrl+Alt+O) browses the same folders and opens a workflow. +- ComfyUI's own workflow browser still works. It lists only the workflows you can open. + +## Who can do what + +| | My files | Shared folder | Common | +|---|---|---|---| +| Open | owner, admins | everyone, or the folder's list | everyone | +| Save, rename | owner, admins | *Edit* permission and not *Can view* on the list | *Edit* permission | +| Delete, move out | owner, admins | the folder's owner, admins | admins | + +- A shared folder's owner is whoever created it. The owner and admins can restrict it to chosen people, each with **Can view** or **Can edit**, and rename or delete it. +- The server checks every rule on ComfyUI's own file API, not just in the panel, so a script or another browser cannot get around them. diff --git a/docs/images/access.png b/docs/images/access.png index 373ecf4..38c5940 100644 Binary files a/docs/images/access.png and b/docs/images/access.png differ diff --git a/docs/images/account.png b/docs/images/account.png index 650866a..d11f7b0 100644 Binary files a/docs/images/account.png and b/docs/images/account.png differ diff --git a/docs/images/admin.png b/docs/images/admin.png index be8b1dc..35d5035 100644 Binary files a/docs/images/admin.png and b/docs/images/admin.png differ diff --git a/docs/images/chat.png b/docs/images/chat.png index 1e0cbf2..86657dd 100644 Binary files a/docs/images/chat.png and b/docs/images/chat.png differ diff --git a/docs/images/files-all.png b/docs/images/files-all.png new file mode 100644 index 0000000..de1ebeb Binary files /dev/null and b/docs/images/files-all.png differ diff --git a/docs/images/files-shared.png b/docs/images/files-shared.png new file mode 100644 index 0000000..19ef68d Binary files /dev/null and b/docs/images/files-shared.png differ diff --git a/docs/images/files.png b/docs/images/files.png new file mode 100644 index 0000000..16355e1 Binary files /dev/null and b/docs/images/files.png differ diff --git a/docs/images/floating.png b/docs/images/floating.png index 9c9f9fd..9d47061 100644 Binary files a/docs/images/floating.png and b/docs/images/floating.png differ diff --git a/docs/images/history.png b/docs/images/history.png index 89b7411..ec0d5e4 100644 Binary files a/docs/images/history.png and b/docs/images/history.png differ diff --git a/docs/images/people.png b/docs/images/people.png index 8e9475c..fe22fb8 100644 Binary files a/docs/images/people.png and b/docs/images/people.png differ diff --git a/docs/images/save.png b/docs/images/save.png new file mode 100644 index 0000000..3c83ff2 Binary files /dev/null and b/docs/images/save.png differ diff --git a/docs/images/server.png b/docs/images/server.png index b29ae93..829c779 100644 Binary files a/docs/images/server.png and b/docs/images/server.png differ diff --git a/docs/install.md b/docs/install.md index 2c8a6a1..ac78d73 100644 --- a/docs/install.md +++ b/docs/install.md @@ -49,12 +49,21 @@ The data folder is `/rigshare`; point it elsewhere with `RIGS | `sessions.json` | Active logins (session ids, not tokens) | | `secret.key` | Key that signs session tokens. Keep it private | | `config.json` | Server settings, see [Settings](settings.md) | -| `rooms/` | Current state of every shared workflow | +| `folders.json` | Shared folders: owners and access lists | +| `rooms/` | Latest live state of each workflow | | `snapshots/` | Workflow history | | `chat.jsonl` | The whole chat history, one message per line | Back up the folder to keep accounts and history. Deleting `secret.key` signs everyone out. +## Upgrading from RigShare 1.0 + +Update the folder (`git pull`, or ComfyUI Manager) and restart ComfyUI. Then: + +- Workflows already at the top level become *common*: everyone can open them, and they are live while open. Move personal ones into each person's **My files**, and group shared ones in **Shared** folders. Admins can do this for everyone from **Files → All**. +- Access lists set on individual workflows are dropped. Restrict a shared folder instead. +- The chat history moves from `chat.json` to `chat.jsonl` on the first start, with nothing lost. From then on, all of it is kept. + ## Upgrading from ComfyUI-Nexus Remove or disable `custom_nodes/ComfyUI-Nexus` and install RigShare. Nexus kept plaintext passwords in `nexus/admins.json`, so nothing is imported: create the admin on first run, then delete the old `nexus` folder. diff --git a/pyproject.toml b/pyproject.toml index 0913a60..cb1e1e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-rigshare" description = "Multi-user collaboration for ComfyUI: accounts and login, live-shared workflows, cursors, chat, snapshots and a server monitor." -version = "1.0.0" +version = "1.1.0" license = { file = "LICENSE" } dependencies = []