Background
----------
Setting up `scripts/sync_to_dev.py` on a fresh machine required two
pre-steps the script didn't help with: (1) editing `.env` to point at
a path that didn't exist yet, then (2) `mkdir -p` on that path before
the first sync would work. The script errored out cleanly with
"target does not exist" but didn't tell the user the obvious next
move was to create it. This was particularly silent on Mac where the
ComfyUI install path differs from the Windows examples in `.env.example`.
Changes
-------
- **`--init` flag** on `scripts/sync_to_dev.py`. When the target
directory doesn't exist and `--init` is passed, the script creates
it and proceeds with the sync. Without `--init`, it errors out with
the same "first time on this machine?" hint pointing at the new flag.
- **Safety guards** on `--init`. Refuses (exit 3) if:
- the parent directory doesn't exist, OR
- the parent doesn't look like a ComfyUI `custom_nodes/` folder
(heuristic: parent is named `custom_nodes` OR sits inside a
directory named `ComfyUI`).
This prevents a typo in `KOLOOK_COMFYUI_DEV_PATH` from quietly
creating a `ComfyUI-Koolook/` somewhere unexpected on disk. The
refusal message includes a manual escape hatch (`mkdir -p` + retry
without `--init`) for the case where the parent really IS the
ComfyUI install but doesn't match the heuristic.
- **Drop stale `k_easy_version.py`** from `RUNTIME_PATHS`. The file
was deleted in v0.1.10 (PR #41); the script's `if not src.exists()`
guard meant it was a no-op every run, but the entry was misleading.
- **`.env.example`** gains explicit macOS / Linux / Windows path
examples for `KOLOOK_COMFYUI_DEV_PATH` and a 3-step first-run
recipe (cp .env.example → edit → `--init`).
- **`docs/maintainers/dev-iteration-loop.md`** gains a "First-time
setup on a new machine" section with the per-OS path table and the
same 3-step recipe.
Verification
------------
- `python scripts/sync_to_dev.py --dry-run` against a missing target
→ exit 2, hint at `--init`.
- `python scripts/sync_to_dev.py --init` against a real ComfyUI
`custom_nodes/` parent → creates the leaf, copies 9 entries, exits 0.
- `python scripts/sync_to_dev.py` (no flag) re-run after `--init` →
re-syncs cleanly, idempotent.
- `python scripts/sync_to_dev.py --init` against `/tmp/not-custom-nodes`
→ exit 3, "parent does not exist".
- `python scripts/sync_to_dev.py --init` against an existing
`/tmp/wrong-parent` (not custom_nodes) → exit 3, "doesn't look like
a ComfyUI custom_nodes/ folder", manual escape hatch in the message.
- `python -c "import ast; ast.parse(open('scripts/sync_to_dev.py').read())"`
→ syntax OK.
- `python tools/preflight_release.py --skip manager-meta -v` → PASS.
No CHANGELOG entry — dev-tooling under `scripts/` doesn't ship to
users of the published package. Avoiding noise on the [Unreleased]
section that PRs #59 / #60 also touch.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Maintainer docs
Project-internal procedures. If you're cutting a release, forking a node, hitting the Comfy Registry API, or debugging CI — read these first.
These are docs for humans doing the work. The corresponding agent
workflows for Claude Code live in ../../.claude/skills/
and should be kept in sync with these prose docs.
Contents
| File | What it covers |
|---|---|
releasing.md |
Canonical step-by-step release procedure: branch → PR → publish-validate → squash-merge → tag → GitHub Release. Anti-patterns to avoid. The per-release tickbox mirror is .github/ISSUE_TEMPLATE/release_checklist.md. |
registry-api.md |
The Comfy Registry's undocumented version-management endpoints (deprecate, delete, query) reverse-engineered while cleaning up v0.1.0–0.1.5. Includes ready-to-paste curl commands and an optional GitHub Actions workflow YAML for codified version management. |
node-versioning.md |
Hard-won rules for changing INPUT_TYPES / RETURN_TYPES / class names without breaking saved user workflows. The five rules + the suffix-version pattern (MyNode → MyNodeV2) + the alias-then-deprecate migration path. |
curated-sidebar.md |
The "Curated Nodes" sidebar tab workflow. How to capture your in-ComfyUI favorites and ship them as the package's default via web/curated_defaults.json. Storage keys, data flow, reset procedure. |
workflows-sidebar.md |
The "Workflows" section of the same sidebar. Save canvas / save selection / directories / archive on collision / load with named tab. Storage shape, action semantics, reset procedure. |
dev-iteration-loop.md |
The fast iteration pattern we used to build the sidebar — the dev-sync loop, agent trigger phrases (go, dev-sync, paste-JSON), what survives across re-syncs vs what doesn't, push/publish gates. Read this when returning to UI work after a break. |
Read this first if you're confused about version numbers:
../reference/versioning.mdexplains the three independent version axes in this codebase (pack version, fork wrapper version, upstream pinned commit) and which skill/doc owns each one. Worth a one-time read before starting any version-bump work.
Companion agent skills
Skill (in .claude/skills/) |
Mirrors this doc |
|---|---|
license-pre-check |
Runs before any third-party fork; refuses to proceed on incompatible licenses. The principles also apply when a human is doing it manually. |
add-external-fork |
The forks/ workflow — clone outside MAIN, register in forks_manifest.yaml, namespace the IDs. Phase 0 calls license-pre-check. |
docs-sync |
Find-and-replace a version tag (or any string token) across docs, code constants, and manifests in one controlled pass. Used during fork wrapper version bumps. |
menu-comfy |
Lists all project skills with one-liners — quick inventory when you can't remember what's available. Distinct from the global /menu skill so the two don't collide. |