Commit Graph
62 Commits
Author SHA1 Message Date
Vito Sansevero 5093cb213f chore: valid packaging metadata, flake8 config file, ignore local config with secrets
pyproject.toml carried requirements.txt comment lines as dependencies, which
fails PEP 508 parsing. flake8 never read [tool.flake8] from pyproject, so the
settings move to .flake8 and pre-commit runs the full rule set. config.json
(holds the CivitAI API key and machine paths) and other local artifacts are
now ignored. coverage joins the dev requirements.
2026-10-08 18:01:34 -07:00
Vito 6c7e4d5b35 feat: release 3.2.4 — recently used sorting, run counts, positive-prompt image linking (#152)
* chore: start 3.2.4

* feat: track prompt usage (run_count, last_used_at) with server-side sorting

- Migration adds last_used_at and run_count; existing prompts are estimated
  from linked images (count, newest image time, else created_at). The
  backfill only touches NULL rows, so it self-heals rows written after a
  downgrade or an interrupted upgrade.
- Every node run records a use, including re-runs of an existing prompt;
  a tracking failure is logged and never blocks generation.
- search_prompts/get_recent_prompts accept a whitelisted sort key
  (last_used, created, run_count, rating, text); default stays newest first.

Refs #90

* feat: sort param on /recent and /search; microsecond last_used_at

- /prompt_manager/recent and /search accept ?sort= (whitelisted in the DB
  layer; unknown values fall back to newest first).
- last_used_at is written with microseconds from Python so a re-run in the
  same millisecond as another save still sorts first; ordering stays correct
  against millisecond values from the backfill.

Refs #90

* feat: server-side sort in admin UI with Recently Used / Most Used and run badges

- New web/js/prompt-list-sort.js owns the sort options, validation and
  request URLs; admin.js fills the dropdown from it and re-fetches from the
  server on change, so every sort spans all pages (the old client-side sort
  only reordered the current page).
- Default sort is Recently Used; prompt cards show a run-count badge with
  the last-used time on hover.
- The node's Recent button now lists recently used prompts.
- Contract test keeps the UI sort keys and the node's key in sync with the
  server whitelist.

Refs #90

* fix: link images and count runs by the positive prompt, not node execution

With a negative-prompt PromptManager node in the workflow, every executed
PromptManager node pushed onto the image-linking queue, so images could be
linked to the negative prompt or to a previous run. ComfyUI also skips
unchanged nodes, so re-runs of the same prompt were never counted.

- utils/prompt_graph.py finds the PromptManager nodes feeding a sampler's
  positive input (KSampler, CFG/Basic guiders, ControlNet and combine
  pass-throughs, PromptManagerText into encoders), falling back to all
  PromptManager nodes when none can be traced.
- Runs are counted by a ComfyUI on-prompt hook when a workflow is queued;
  prompts not yet saved are counted when the node first saves them.
- Nodes receive the queued graph (hidden PROMPT/UNIQUE_ID). Only the run's
  positive prompt becomes the current prompt; only batch items with linked
  text are pushed onto the FIFO queue.
- The image monitor links from the image's own metadata first, using the
  positive node, and falls back to the queue for batch items.

Refs #90

* fix: address review — count cached runs of linked text, keep repeated pending runs

- Text from known pure string nodes (core PrimitiveString/StringConcatenate,
  WAS Text Concatenate/Multiline, pysssss ShowText) is resolved at queue
  time, so cached re-runs of such prompts are counted and their images link
  from metadata. Unknown nodes are never guessed; the node compares its real
  text with the queue-time resolution and falls back to counting and
  queueing itself on any mismatch.
- A new prompt queued several times before its first run keeps every
  pending run; the first save records all of them.
- Registration flag is a threading.Event; consistent unittest imports;
  logging instead of print in the init fallback.

* refactor: unquote PendingFirstUse annotation so Tuple usage is visible
2026-10-07 13:52:09 -07:00
Vito aa768f57dd fix: release 3.2.3 — metadata parsing, null-safe saves, auto-hide, tag search (#151)
* fix: release 3.2.3 — metadata parsing, null-safe saves, auto-hide, tag search

- fix(#75): stop SaveImage patch from writing the last-run prompt into every
  PromptManager node (negative prompts were saved as copies of the positive)
- fix(#75): replace four duplicated metadata parsers with a shared
  web/js/comfy-metadata.js that traces sampler links (KSampler, CFGGuider /
  SamplerCustomAdvanced, LoRA chains, ControlNet pass-through, any checkpoint
  loader) and recovers per-node text for images saved by older versions
- fix(#143): treat null JSON body fields as empty in prompt API handlers
- fix(#149): keep auto-hide timeout 0 (disabled) instead of falling back to
  the default; validate result_timeout on save
- feat(#150): support tag:name filters in the node search box
- docs(#142): scan dialog mentions A1111/Forge metadata support
- docs(#144): fix ComfyUI-Lora-Manager links
- ci: run JS tests with node --test

* fix: bound metadata graph traversal to prevent tab freeze on crafted PNGs

Link resolution tried every linked input recursively with only a depth cap,
so a PNG whose prompt graph has cycles and fan-out could force ~inputs^25
paths and hang the gallery/metadata page. Each lookup now shares a visited
set (each node expanded once) with a hard cap of 500 visits.

* fix: read the matching output of multi-output settings nodes

KSampler settings linked to a node like SamplerCombo all resolved to its
first value, so steps, cfg and sampler showed the sampler name. Scalar
resolution now prefers the linked node's input with the same field name.

* fix: address review — trust API text, restore workflow-only parsing

- Workflow widget text now only replaces API text for metadata showing the
  pre-3.2.3 corruption signature (2+ PromptManager nodes with identical API
  text but different widgets). Otherwise the API graph wins, so expanded
  dynamic prompts and linked text display what actually ran.
- Images with only a UI workflow are converted to the API graph shape and
  traced the same way: prompts, KSamplerAdvanced, UNET/checkpoint loaders,
  KJNodes Set/Get, Reroute, bypassed and muted nodes.
2026-10-07 11:27:40 -07:00
Vito 8146250274 feat: PromptSearchList batch workflow support & image linking v3.2.2 (#139)
* fix(search): PromptSearchList crash, filters, and batch output (#52)

- Fix empty list crash (OUTPUT_IS_LIST requires at least one element)
- Add partial tag matching (LIKE instead of exact)
- Add preview and count outputs for batch visibility
- Add skip_multipart filter for Clip_N video prompts
- Add LoRA-only prompt filter
- Collapse newlines for StringOutputList compatibility

* feat(db): add tag_partial parameter for LIKE tag matching (#52)

Allows search_prompts to use LIKE matching for tags instead of exact.
Used by PromptSearchList for discovery-style search.
Existing callers default to exact matching (unchanged behavior).

* feat(tracker): add FIFO prompt queue for batch image linking (#52)

Batch workflows encode all prompts first, then save all images later.
The queue preserves encode order so each image links to the correct
prompt by position (pop on save matches push on encode).

* fix(monitor): multi-strategy image-to-prompt linking (#52)

Previous approach relied on live prompt tracker state, which was
always stale for batch workflows (all images linked to last prompt).

New 5-strategy priority chain:
1. FIFO queue pop (batch-correct by position)
2. Metadata-based DB lookup (extracts prompt from PNG)
3. Prompt snapshot at file-creation time
4. Live prompt tracker
5. Most recent DB prompt fallback

* test: add tests for prompt queue and search filters (#52)

- 6 queue tests: FIFO ordering, batch simulation, exhaustion
- 15 filter tests: newline collapse, Clip_ filter, LoRA-only filter
- Fix _make_tracker helper to include queue fields

* chore: bump version to 3.2.2

* fix: address code review — regex backtracking and queue expiry (#52)

- Replace backtracking-prone LoRA-only regex with subtraction approach
  (re.sub removes tags, check if anything remains). Fixes CodeQL alert.
- Add expiry check to pop_next_prompt — skips stale entries to prevent
  incorrect linking from accumulated queue entries across sessions.
- Cleanup thread now also prunes expired queue entries.
2026-04-10 12:49:59 -07:00
Vito 00284d92da feat: LoraManager integration — trigger words & example import (#52) (#136)
* feat: add LoRA utility module for LoraManager integration (#52)

Detection, metadata reading, trigger word cache, and prompt injection
for ComfyUI-Lora-Manager. All functions return empty results when
LoraManager is not installed.

* feat: add IntegrationConfig for opt-in third-party integrations (#52)

* feat(api): add LoraManager integration endpoints (#52)

Detection, enable/disable, scan/import, trigger word lookup,
and cache refresh endpoints under /prompt_manager/lora/*.

* feat: inject LoRA trigger words into prompts at encoding time (#52)

When enabled, scans for <lora:NAME:WEIGHT> tags in prompt text and
appends trigger words from LoraManager metadata. Behind config toggle.

* feat(ui): add LoraManager integration settings and import UI (#52)

Integrations section in settings with auto-detection badge, enable
toggle, trigger word toggle, and Import LoRA Data button.

* fix: detect LoraManager with case-insensitive directory scan (#52)

* fix: simplify LoraManager heuristic to match real install structure (#52)

* fix: find ComfyUI root via folder_paths and handle symlinked installs (#52)

* fix(ui): add pointer-events-none to toggle switch overlays (#52)

The styled div was intercepting clicks meant for the sr-only checkbox
input, preventing toggle switches from being clickable.

* fix: use lora-manager category and tag for imported LoRA data (#52)

* fix: use rglob to find metadata in lora subdirectories (#52)

* feat: discover LoRA dirs from extra_model_paths.yaml and folder_paths (#52)

Only models/loras under the ComfyUI root was checked. Now also parses
extra_model_paths.yaml and uses folder_paths.get_folder_paths('loras')
at runtime to find all configured LoRA directories.

* fix: use example prompts instead of trigger words, serve LoRA preview images (#52)

- Prompt text now uses civitai example prompts (images[].meta.prompt)
  when available, falling back to model name instead of trigger words
- Image serving now allows paths within LoRA directories when the
  integration is enabled, fixing 403 errors on preview images

* fix: handle null civitai field, link all preview images (#52)

- Guard against civitai: null in metadata (was crashing the scan)
- Link all local preview images per LoRA, not just the first
- Add get_civitai_image_urls() for future remote image support

* feat: reimport clears previous lora-manager data first (#52)

Clicking Import LoRA Data now deletes all existing lora-manager
category prompts before scanning, ensuring a clean reimport.

* feat: download civitai example images during LoRA import (#52)

Images from civitai.images[] are downloaded to data/lora_images/ cache
and linked to prompts alongside local preview files. Cached files are
reused on reimport. Image serving allows the cache directory.

* feat: add CivitAI API key setting for authenticated image downloads (#52)

Most civitai example images (especially NSFW) require authentication.
Adds API key field to the Integrations settings panel, passed as
Bearer token when downloading example images.

* feat(ui): add progress modal for LoRA import (#52)

Closes settings modal and shows a dedicated progress modal with
progress bar, status text, and processed/imported counts during
LoRA import. Auto-closes after completion.

* fix: reduce download timeout to 5s, update progress per LoRA (#52)

5K images at 15s timeout was painfully slow. Reduced to 5s fail-fast.
Progress now updates for every LoRA with image count, not every 5th.

* perf: use 512px thumbnails and parallel downloads for LoRA images (#52)

Full-size civitai images averaged 5.6MB each (27GB total for 5K images).
Now requests /width=512/ thumbnails (~50-100KB) and downloads 8 in
parallel per LoRA. Expected speedup: ~100x smaller + 8x parallel.

* fix: resize downloaded images to 512px thumbnails locally (#52)

Civitai CDN returns 401 for /width=N/ thumbnail URLs with API key auth.
Instead, download the original and resize to 512px via PIL before saving.
Reduces disk usage from ~5MB to ~30-50KB per image.

* docs: update README for v3.2.1 LoRA Manager integration (#52)

- Add LoRA Manager integration section with setup guide and CivitAI key docs
- Add folder filter section with rescan note for existing libraries
- Add v3.2.1 changelog entry, split from v3.2.0
- Add WIP notice for LoRA Manager feature
- Update AutoTag section to include WD14 models
- Fix stale references (KikoTextEncode, outdated file structure)
- Remove dated v2 development note
- Add screenshots for settings, integration, and filtered results
- Fix code review items: remove unused constant, add comments to empty excepts
- Bump version to 3.2.1

* test: add unit tests for LoRA integration and folder filter (#52)

- test_lora_utils.py: 32 tests covering trigger word extraction, example
  prompts, image URLs, metadata parsing, cache dir, TriggerWordCache
- test_lora_database.py: 17 tests covering delete_prompts_by_category,
  folder filter search, get_prompt_subfolders, LoRA import workflow
- test_config.py: 7 new IntegrationConfig tests for structure, enable,
  partial update, reset, and roundtrip

* fix: remove unused MagicMock import in test_lora_utils (#52)
2026-04-03 18:26:23 -07:00
Vito 6fc6e683eb feat: multi-directory gallery scan with folder filter (#126) (#135)
* refactor(api): add multi-root output dir infrastructure (#126)

- Change _gallery_cache from None to {} (dict keyed by path string)
- Update invalidate_gallery_cache() to clear dict instead of setting None
- Add _get_all_output_dirs() helper as single source of truth for
  resolving configured + fallback output directories
- Update _enrich_prompt_images() to iterate all output roots when
  computing relative paths and thumbnail URLs

* feat(api): support multiple gallery scan paths in settings endpoint (#126)

* feat(ui): dynamic multi-path settings with add/remove buttons (#126)

* cleanup: remove dead galleryRootPath assignment in loadSettings

* feat(api): multi-directory gallery scan with subfolder filter and multi-root serve (#126)

* feat(db): add folder filter to search_prompts and get_prompt_subfolders (#126)

* feat(api): add subfolders endpoint and folder filter to prompt search (#126)

* feat(ui): add folder dropdown filter to search bar (#126)

* fix: escape LIKE wildcards in folder filter and remove dead _gallery_cache_time field

* feat(scan): scan all media types across all output dirs with batched extraction (#126)

* chore: gitignore SQLite WAL-mode temp files

* fix: enrich prompt images with URLs and check all output dirs for serving

- Extract _enrich_images() for flat image lists, used by get_prompt_images
- get_prompt_images now adds url/thumbnail_url (fixes stuck "Loading images...")
- serve_image checks all output dirs not just first (fixes 403 on multi-path)
- Fix diagnostics monitor check to read current module attribute, not stale import

* feat(ui): add version-scoped update notice popup for rescan (#126)

* chore: bump version to 3.2.0
2026-04-03 06:46:01 -07:00
Vito 7f45bc6df7 feat(ui): show prompt and copy button in filmstrip viewer (#124) (#131)
* feat(ui): show prompt metadata sidebar in filmstrip viewer (#124)

The filmstrip viewer opened images without any metadata or prompt
display. Added shown/viewed callbacks to attach the existing metadata
sidebar with prompt text and copy button. Also added hidden callback
to both admin viewers for proper sidebar cleanup on close.

* chore: bump version to 3.1.6

* fix(ui): scope metadata sidebar to active viewer container (#124)

addMetadataSidebar() used querySelector('.viewer-container') which
grabbed the first match in the DOM. If a gallery viewer was opened
previously, its stale hidden container would be selected instead of
the active filmstrip viewer. Now iterates all containers and picks
the visible one.
2026-03-18 07:57:22 -07:00
Vito ad32a51497 fix: database path config option now works (#119) (#130)
* fix: resolve database path from config.json (#119)

PromptDatabase() was hardcoded to "prompts.db" relative to CWD,
ignoring the DEFAULT_DB_PATH setting from config.json. Added
_resolve_db_path() that reads from PromptManagerConfig when available
and resolves relative paths against the extension root directory.
This fixes Docker deployments where the CWD differs from the extension.

* test: add unit tests for database path resolution (#119)

Cover explicit absolute/relative paths, config fallback, relative
config paths resolved to extension root, and PromptDatabase constructor
integration with _resolve_db_path.

* docs: update database path configuration instructions (#119)

Replace outdated advice to edit py/config.py with correct config.json
approach. Add Docker-specific guidance for absolute paths.

* chore: bump version to 3.1.5

* fix: remove unused import and variables from test (#119)

Address code review: remove unused MagicMock import and unused db
local variables in constructor tests.
2026-03-18 07:29:58 -07:00
Vito 0e95dc3431 fix(ui): enable click-to-close on image viewer (#125) (#129)
* fix(ui): enable click-to-close on all image viewers (#125)

The admin gallery viewer had backdrop: 'static' which prevented closing
by clicking the dark overlay. Changed to backdrop: true and added
explicit button: true across all three ViewerJS instances so users can
close the viewer by clicking outside or using the close button.

* chore: bump version to 3.1.4
2026-03-18 07:09:22 -07:00
Vito 8dfa290417 fix: resolve UnboundLocalError and connected text input issues (#123) (#128)
* fix: initialize extended_tags before conditional block (#123)

extended_tags was only assigned inside the `if storage_text` block,
causing UnboundLocalError when text input is empty or whitespace-only.
Initialize to empty list before the conditional in both PromptManager
and PromptManagerText nodes.

* test: add unit tests for empty text input handling (#123)

Cover empty string, whitespace-only, empty with prepend/append, and
normal text for both PromptManagerText and PromptManager nodes.

* fix: use parts-based join to prevent double space on empty text (#123)

When main text is empty with prepend/append connected, the old string
concatenation produced "before  after" (double space). Switch to
building a parts list and joining with single space so empty text is
cleanly skipped.

* test: add concatenation tests for prepend/append with empty text (#123)

Cover double-space regression, all-parts-present case, and
prepend-only with empty text for both node variants.

* fix: preserve connected input values in widget sync and queue hooks (#123)

The queuePrompt interceptor, syncPromptManagerWidgets, and serialize
hook were overwriting connected input link references with the widget's
empty DOM value. When text is connected from another node, ComfyUI puts
a link reference array in the output — these hooks now check for
connections before syncing, so externally connected text flows through.

* test: add connected-input contract tests for text + prepend + append (#123)

Verifies that externally connected text appears in the final output
alongside prepend/append — the exact scenario from the QA screenshot.
Covers both PromptManagerText and PromptManager (CLIP) variants.

* chore: bump version to 3.1.3
2026-03-18 06:43:23 -07:00
Vito ff090c5ebb fix: add OUTPUT_NODE = True to all nodes to prevent caching skip (#120) (#121)
ComfyUI's execution engine walks backwards from output nodes. Without
OUTPUT_NODE = True, our nodes could be silently skipped when downstream
nodes are cached — even when IS_CHANGED returns a new value.

Since all three nodes have side effects (database writes, execution
tracking), they must be marked as output nodes so ComfyUI always
includes them in the execution graph.

Adds regression tests for OUTPUT_NODE and IS_CHANGED contracts.
Bumps version to 3.1.2.
2026-03-06 12:33:48 -08:00
Vito Sansevero d0c747a609 chore: bump version to 3.1.1 in pyproject.toml 2026-02-11 05:57:19 -08:00
Vito Sansevero fdda1c4ad5 chore: bump version to 3.1.0, update changelog, fix tag styling and filters
- Add append: to autotag skip-tagged filter alongside prepend:
- Update tag chip styling to dark fill with white text
- Add v3.1.0 changelog entry covering all changes since v3.0.26
2026-02-10 17:36:33 -08:00
Vito Sansevero d60e4ca52f chore: bump project version to 3.0.37 in pyproject.toml 2026-02-09 05:48:19 -08:00
Vito Sansevero 0a2c274a27 chore: bump version to 3.0.36 in pyproject.toml 2026-02-08 13:26:01 -08:00
Vito Sansevero f7e6fed1af chore: bump project version to 3.0.35 in pyproject.toml 2026-02-08 08:49:52 -08:00
Vito Sansevero 15bbfc4044 chore: bump project version to 3.0.34 in pyproject.toml 2026-02-08 05:40:44 -08:00
Vito Sansevero 224fcc7803 chore(ci): add code quality, security scanning, and Dependabot
- Add code-quality.yml: Black formatting check, flake8 linting, bandit
  security scan
- Add dependabot.yml: weekly updates for pip deps and GitHub Actions
- Add requirements-dev.txt: single source of truth for CI dependencies
- Harden test.yml: add permissions, pip caching, use requirements-dev.txt
- Add Black/flake8/bandit config to pyproject.toml (line-length=88)
2026-02-07 08:30:00 -08:00
Vito Sansevero 5c5fe512c8 chore: bump version to 3.0.33 in pyproject.toml 2026-02-07 08:09:26 -08:00
Vito Sansevero 091689f9f5 chore: bump version to 3.0.32 in pyproject.toml 2026-02-06 14:34:00 -08:00
Vito Sansevero f485825bfb fix: resolve gallery crash when thumbnails exist and prevent thumbnail-as-image linking
- Fix AttributeError: 'str' has no attribute 'as_posix' on thumbnail_rel_path
  in get_output_images and find_duplicates (thumbnail_rel_path is already a
  string from f-string construction, not a Path object)
- Fix NameError: total_images undefined in generate_thumbnails (was defined as
  total_media, causing progress logging and response to fail)
- Add URL encoding for paths in scan_output_dir for filenames with spaces
- Exclude thumbnails directory from image monitor to prevent linking thumbnail
  files to prompts via fallback mechanism
- Bump version to 3.0.31
2026-02-03 14:07:23 -08:00
Vito Sansevero 846b0b64b9 chore: bump version to 3.0.30 2026-02-03 08:39:29 -08:00
Vito Sansevero 9688e94b4c chore: bump version to 3.0.29 in pyproject.toml 2026-02-02 16:01:08 -08:00
Vito Sansevero 4f273e9b21 chore: bump version to 3.0.28 in pyproject.toml 2026-02-02 15:21:58 -08:00
Vito Sansevero b137c998b3 chore(pyproject): bump version to 3.0.27 2026-02-02 15:11:03 -08:00
Vito Sansevero 33a66da2f1 chore: bump version to 3.0.26 in pyproject.toml 2025-12-09 14:13:44 -08:00
Vito Sansevero 067320e9c5 chore: bump version to 3.0.25 in pyproject.toml 2025-12-09 12:51:32 -08:00
Vito Sansevero 75fad23464 chore: bump version to 3.0.24 in pyproject.toml 2025-12-09 09:32:10 -08:00
Vito Sansevero b8d6b9072d chore(pyproject): bump version to 3.0.23 2025-12-07 17:38:04 -08:00
Vito Sansevero b5e6bec141 chore: bump version to 3.0.22 in pyproject.toml 2025-12-06 07:27:26 -08:00
Vito Sansevero e0e61ad618 chore: bump version to 3.0.21 in pyproject.toml 2025-09-09 09:30:09 -07:00
Vito Sansevero 8f01bc1541 chore: bump version to 3.0.20 in pyproject.toml 2025-08-30 17:33:53 -07:00
Vito Sansevero 0b94063e73 chore: remove local settings, bump version to 3.0.19 2025-08-11 19:32:28 -07:00
Vito Sansevero d949585b35 chore: bump version to 3.0.18 in pyproject.toml 2025-08-11 15:32:48 -07:00
Vito Sansevero a6997e0c8c chore: bump version to 3.0.17 in pyproject.toml 2025-08-11 14:20:49 -07:00
Vito Sansevero 190146f7b6 chore(pyproject): bump version to 3.0.16 2025-08-04 07:00:14 -07:00
Vito Sansevero f488eec029 chore: bump version to 3.0.15 in pyproject.toml 2025-08-04 06:32:48 -07:00
Vito Sansevero cb3d09ad46 chore: bump version to 3.0.13 in pyproject.toml 2025-06-19 16:56:52 -07:00
Vito Sansevero 283268a1ec chore: bump version to 3.0.12 in pyproject.toml 2025-06-19 13:06:37 -07:00
Vito Sansevero 890060bc38 chore(pyproject): update version and add icon URL 2025-06-16 06:38:16 -07:00
Vito Sansevero f3d49a95d6 chore: bump version to 3.0.10 in pyproject.toml 2025-06-11 13:43:27 -07:00
Vito Sansevero 592812918d chore: bump version to 3.0.9 in pyproject.toml 2025-06-09 08:41:56 -07:00
Vito Sansevero 6321991af0 chore(pyproject): bump version to 3.0.8 2025-06-08 15:53:20 -07:00
Vito Sansevero feb8248fdd chore: bump version to 3.0.7 in pyproject.toml 2025-06-08 15:50:48 -07:00
Vito Sansevero 5e3e258501 chore: bump version to 3.0.6 in pyproject.toml 2025-06-08 15:38:07 -07:00
Vito Sansevero 533c234957 chore: bump version to 3.0.5 in pyproject.toml 2025-06-08 13:45:58 -07:00
Vito Sansevero 81334571fb chore: bump version to 3.0.4 in pyproject.toml 2025-06-04 08:58:00 -07:00
Vito Sansevero b7649754bd chore: bump version to 3.0.3 in pyproject.toml 2025-06-04 06:53:19 -07:00
Vito Sansevero c765181e18 chore: bump version to 3.0.2 in pyproject.toml 2025-06-03 17:57:56 -07:00
Vito Sansevero 4505e62261 chore: bump version to 3.0.1 in pyproject.toml 2025-06-03 17:07:08 -07:00