Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
201 commits
Select commit Hold shift + click to select a range
0eea7ea
Merge pull request #58 from trissim/object-state-extraction
trissim Jan 26, 2026
a6d7457
fix(pyqt_gui): use canonical dotted field ids
trissim Jan 26, 2026
c01eb20
refactor(materialization): typed options, generic specs, and tabular …
trissim Jan 27, 2026
6040843
docs: update materialization API examples in architecture docs
trissim Jan 27, 2026
47fcfbf
Simplify materialization API: remove handler and analysis_type parame…
trissim Jan 27, 2026
c4a5ee1
Refactor core.py: eliminate boilerplate with helper classes
trissim Jan 27, 2026
607ee08
Further reduce core.py below 1000 lines
trissim Jan 27, 2026
28998e6
Radical simplification: ABC-based generic materialization architecture
trissim Jan 27, 2026
e7c35da
refactor(materialization): switch to writer-based specs
trissim Jan 27, 2026
bf22c67
docs: update materialization docs for writer API
trissim Jan 27, 2026
f035f93
fix(materialization): allow MaterializationSpec(outputs=...) construc…
trissim Jan 27, 2026
afdb9d4
fix(materialization): rebuild specs via ObjectState hook
trissim Jan 27, 2026
b92c82e
docs: note ObjectState rebuild hook for custom dataclasses
trissim Jan 27, 2026
cdc030a
fix(backends): remove legacy materialization spec strings
trissim Jan 27, 2026
417a2de
chore(submodules): bump ObjectState to v1.0.4
trissim Jan 27, 2026
bd5945f
chore(submodules): bump pyqt-reactive and python-introspect
trissim Jan 27, 2026
cde65ca
fix(factory): streaming configs return concrete StreamingConfig type
trissim Jan 27, 2026
9cf2aa0
fix(factory): import StreamingConfig for type annotation
trissim Jan 27, 2026
1f72c00
fix(factory): use string literal for StreamingConfig forward reference
trissim Jan 27, 2026
4b86701
fix(config): remove use_scroll_area comment causing syntax error
trissim Jan 27, 2026
d062fd2
chore(submodules): update pyqt-reactive and python-introspect
trissim Jan 28, 2026
ebcdaa6
chore(submodule): update python-introspect to add enableable.py
trissim Jan 28, 2026
eee89f4
Merge branch 'main' of https://github.com/trissim/openhcs into materi…
trissim Jan 28, 2026
620c15a
Add group abbreviations to configs and streaming config factory
trissim Jan 28, 2026
272bf6f
Fix sig-diff grouping by using strategy consistently
trissim Jan 28, 2026
fc3b732
feat: migrate config classes to @abbreviation decorator system
trissim Jan 28, 2026
cdd3230
chore: update submodules to latest commits
trissim Jan 28, 2026
d263b8a
chore: update pyqt-reactive submodule for dimmer placeholder checkmark
trissim Jan 28, 2026
72efcb5
chore: update pyqt-reactive submodule - fix checkbox dimming
trissim Jan 28, 2026
568c18b
chore: update pyqt-reactive submodule - grey placeholder checkmark
trissim Jan 28, 2026
a090060
chore: update submodules with abbreviation and always viewable fields…
trissim Jan 28, 2026
ec2e040
fix(scope): properly propagate scope accent colors during widget crea…
trissim Jan 29, 2026
da5d42e
chore(submodule): update pyqt-reactive to latest
trissim Jan 29, 2026
874617b
chore: update python-introspect submodule to v0.1.2
trissim Jan 29, 2026
1e56827
chore: update python-introspect submodule to include Enableable mixin
trissim Jan 29, 2026
4762d25
chore: update python-introspect submodule pointer to main with Enable…
trissim Jan 29, 2026
d667658
chore: update python-introspect submodule to v0.1.3 with Enableable m…
trissim Jan 29, 2026
ad03476
chore: configure submodules to track main branches
trissim Jan 29, 2026
e14b25b
ci: auto-update submodules to latest main in all jobs
trissim Jan 29, 2026
6561340
chore(submodules): update all external modules to latest main
trissim Jan 29, 2026
c45472f
Merge branch 'materialize-refactor' of https://github.com/trissim/ope…
trissim Jan 29, 2026
0415d7f
chore: add submodule auto-update hook script
trissim Jan 29, 2026
fcc0e7c
chore: move hook to committed hooks directory
trissim Jan 29, 2026
c547487
chore: add committed hooks directory and gitconfig
trissim Jan 29, 2026
d8b5f0a
chore: add Makefile with dev setup and hook installation
trissim Jan 29, 2026
49efab9
Fix transport_mode not being passed from config to streaming backend
trissim Jan 29, 2026
f739d89
docs(llm): update system prompts to use simple materialization presets
trissim Jan 29, 2026
1c524c3
Update ObjectState submodule to v1.0.5
trissim Jan 29, 2026
2ea2e05
fix(validation): add missing GroupBy import
trissim Jan 29, 2026
b5abe6a
Merge pull request #69 from trissim/materialize-refactor
trissim Jan 29, 2026
12328f7
fix(pyqt-reactive): sync enabled styling during time-travel (undo/redo)
trissim Jan 29, 2026
9bffce8
Merge branch 'main' of https://github.com/trissim/openhcs
trissim Jan 29, 2026
58f601d
chore: update pyqt-reactive to v0.1.4
trissim Jan 29, 2026
e303ca0
fix(hooks): checkout submodule branches to avoid detached HEAD
trissim Jan 29, 2026
54e8125
fix(hooks): add post-merge hook for submodule updates
trissim Jan 29, 2026
dbc50e1
chore: update PolyStore submodule with streaming fix
trissim Jan 29, 2026
2e55437
chore: update PolyStore submodule with documentation
trissim Jan 29, 2026
3428339
chore(submodule): update pyqt-reactive submodule to include scope acc…
trissim Jan 29, 2026
c41b0a6
chore(submodule): update pyqt-reactive to include scope accent deriva…
trissim Jan 29, 2026
8510ef2
chore(submodule): update pyqt-reactive for help color improvements
trissim Jan 29, 2026
96ffd0c
ui(image_browser): apply scope-accented styles to primary buttons
trissim Jan 29, 2026
6773e25
Revert "ui(image_browser): apply scope-accented styles to primary but…
trissim Jan 29, 2026
60cf038
Integrate ViewerStateManager and fix UI freeze with context propagation
trissim Jan 29, 2026
f78ee06
Fix inconsistent patterns and sneaky error hiding
trissim Jan 29, 2026
c437e80
Fix missing threading import causing runtime error
trissim Jan 29, 2026
449b632
chore: update submodules - ObjectState metaclass fix, python-introspe…
trissim Jan 30, 2026
cdd339d
Refactor streaming config UI to use registry-based architecture
trissim Jan 30, 2026
d55b84e
refactor(gui): migrate to WindowManager-based declarative window system
trissim Jan 30, 2026
f1125c1
chore(submodule): update pyqt-reactive for BaseFormDialog integration
trissim Jan 30, 2026
45dbc8b
chore(submodule): update pyqt-reactive to strip trailing zeros from f…
trissim Jan 30, 2026
4ba7996
feat(widgets): increase float precision limit from 6 to 15 decimals
trissim Jan 30, 2026
712c98d
chore(submodule): update pyqt-reactive to increase float precision limit
trissim Jan 30, 2026
4b33f10
Add forward_to_parent_state method for parent notification propagation
trissim Jan 30, 2026
6bbbf6a
Update submodules: ObjectState and pyqt-reactive
trissim Jan 30, 2026
e7fc168
chore: update submodules to latest releases
trissim Jan 31, 2026
21681f1
chore: update submodules to latest releases
trissim Feb 1, 2026
058b1f7
fix: determine tab selection by object type instead of dirty fields
trissim Feb 1, 2026
3c8fafe
feat: scroll to dirty field on time-travel
trissim Feb 1, 2026
9a108cc
refactor: simplify time-travel scrolling using provenance pattern
trissim Feb 1, 2026
153a423
fix: time-travel scroll uses dual editor select_and_scroll
trissim Feb 1, 2026
9bdcd52
refactor: make dual editor scroll deterministic
trissim Feb 1, 2026
c683292
fix: route time-travel scroll based on ObjectState type
trissim Feb 1, 2026
1d84e2f
refactor: make scroll routing strict on ObjectState
trissim Feb 1, 2026
aca8ebf
fix: time-travel select non-func dirty field first
trissim Feb 1, 2026
ef50304
fix: choose best dirty field for time-travel navigation
trissim Feb 1, 2026
7193652
fix: use isinstance and direct property access for field selection
trissim Feb 1, 2026
f5c8f26
chore: update ObjectState to v1.0.8 (last_dirty_field tracking)
trissim Feb 1, 2026
2d71542
debug: add TIME_TRAVEL_NAV log
trissim Feb 1, 2026
85e3a42
feat: install global Shift+Wheel horizontal scrolling
trissim Feb 1, 2026
602154f
fix(dual_editor): add debug logging to select_and_scroll_to_field
trissim Feb 2, 2026
4749025
Fix streaming config resolution in compiler
trissim Feb 2, 2026
a3dbcce
Update submodule external/pyqt-reactive to latest
trissim Feb 2, 2026
7d1f314
Update external repo pointers
trissim Feb 2, 2026
4192df2
bump version to 0.5.1
trissim Feb 2, 2026
8ca14fa
refactor(compiler): standardize all step config access to ObjectState…
trissim Feb 2, 2026
359305c
fix(compiler): update step with corrected processing_config after app…
trissim Feb 2, 2026
d29191c
fix(compiler): use direct attribute assignment instead of dataclasses…
trissim Feb 2, 2026
385aef6
fix(compiler): move ObjectState resolution before path planning
trissim Feb 2, 2026
3215c9f
fix(compiler): remove ensure_analysis_materialization legacy function
trissim Feb 2, 2026
8d1fe0b
refactor(compiler): make compilation ObjectState-native end-to-end
trissim Feb 2, 2026
aab99ad
chore(deps): bump ObjectState submodule
trissim Feb 2, 2026
d2f2db3
fix(compiler): avoid config mutation in ZMQ execution
trissim Feb 3, 2026
a15ab5c
bump version to 0.5.2
trissim Feb 3, 2026
6c9a607
fix(gui): prevent time-travel history index crash
trissim Feb 3, 2026
219ef1f
bump version to 0.5.3
trissim Feb 3, 2026
211293b
fix(packaging): remove direct URL deps from PyPI metadata
trissim Feb 3, 2026
d09cfe7
bump version to 0.5.4
trissim Feb 3, 2026
5cecf2d
refactor(compiler): replace env var with explicit is_zmq_execution pa…
trissim Feb 3, 2026
dc6b546
fix(gui): update pyqt-reactive for tree flash on enable
trissim Feb 3, 2026
652d4bd
chore(gui): bump pyqt-reactive to v0.1.8
trissim Feb 3, 2026
d0a3d4a
fix(gui): bump pyqt-reactive for smooth monitor plots
trissim Feb 3, 2026
e017137
feat(zmq/gui): compile on server and share client
trissim Feb 4, 2026
e4791fc
refactor(gui): reuse pyqt-reactive scope styling
trissim Feb 4, 2026
506c218
chore(submodules): bump ObjectState/pyqt-reactive/zmqruntime
trissim Feb 4, 2026
290d96f
docs(changelog): document remote compile and auto-add output plate
trissim Feb 4, 2026
0e17d61
bump version to 0.5.5
trissim Feb 4, 2026
9d87962
fix(gui): init scope styling before editors
trissim Feb 4, 2026
0e45b34
bump version to 0.5.6
trissim Feb 4, 2026
ef02ffd
refactor(scripts): organize figure generation scripts into dedicated …
trissim Feb 4, 2026
bb9e3fe
feat(scripts): add napari orthogonal projections plugin
trissim Feb 4, 2026
6a4616f
Implement ZMQ-based progress reporting infrastructure and expand figu…
trissim Feb 4, 2026
8595a2d
Document figure generation updates and ZMQ progress plan
trissim Feb 4, 2026
97d1afd
Update submodule pointers after feature commits
trissim Feb 4, 2026
319ddd0
Add progress tracking and generic ZMQ messaging architecture
trissim Feb 5, 2026
002f830
Refactor progress/runtime architecture and extract reusable server-br…
trissim Feb 6, 2026
5cc7645
bump version to 0.5.7
trissim Feb 6, 2026
b6dd06d
Fix CI external dependency sourcing with selectable submodule/PyPI mode
trissim Feb 6, 2026
bfd94a9
Stabilize Napari viewer readiness handshake on cold start
trissim Feb 6, 2026
670cc64
Fix direct integration pipeline path to use explicit progress queue/c…
trissim Feb 6, 2026
43cd6ab
Bump runtime submodules after strict ZMQ typing and release
trissim Feb 6, 2026
69456ab
bump version to 0.5.8
trissim Feb 6, 2026
8a738cc
Fix multiprocessing context mismatch for progress queues
trissim Feb 6, 2026
161214d
Refine status-bar timeline layout and history label placement
trissim Feb 6, 2026
0e8c538
Update pyqt-reactive submodule pointer to v0.1.12 release
trissim Feb 6, 2026
d615730
Fix ZMQ batch run to submit live pipeline definitions
trissim Feb 6, 2026
d70cea5
docs(rst): add pattern grouping and special outputs guide
trissim Feb 7, 2026
0c4d643
feat(compiler): integrate ObjectState into path planner for lazy data…
trissim Feb 7, 2026
9937eb2
feat(gui): add get_pipeline_for_plate() method to pipeline editor
trissim Feb 7, 2026
953cffe
fix(compiler): resolve function references for multiprocessing pickling
trissim Feb 7, 2026
b114e08
feat(orchestrator): add viewer initialization progress events
trissim Feb 7, 2026
54fdfc1
feat(runtime): ZMQ progress stream and compile-only tracking
trissim Feb 7, 2026
696e6c5
feat(gui): ZMQ progress and server browser improvements
trissim Feb 7, 2026
41e50f0
refactor(gui): strongly-typed execution state management
trissim Feb 7, 2026
96da801
feat(gui): type-safe time-travel navigation system
trissim Feb 7, 2026
9348392
fix(registry): filter injectable parameters from function kwargs
trissim Feb 7, 2026
b9e5938
chore(serialization): minor pycodify formatter improvements
trissim Feb 7, 2026
f0f27fb
test: update tests for execution state and progress infrastructure
trissim Feb 7, 2026
74c5d83
chore(submodules): bump pyqt-reactive to v0.1.13 and zmqruntime to v0…
trissim Feb 7, 2026
8924d1d
bump version to 0.5.9
trissim Feb 7, 2026
34eb53b
ci: Install system graphics libraries for PyQt6 in Linux CI
trissim Feb 7, 2026
b3e900a
feat: Add count_cells_simple function with min/max size filtering
trissim Feb 7, 2026
1524df2
chore: Update pyqt-reactive submodule (copy functions to all dict keys)
trissim Feb 7, 2026
46aa464
fix: Pass dtype_config through to ArrayBridge instead of filtering it
trissim Feb 8, 2026
62f51e9
fix: Wrap external library functions with ArrayBridge decorator
trissim Feb 8, 2026
c3971fc
fix: Update test_main to use dtype_config instead of flattened dtype_…
trissim Feb 8, 2026
31a5dcb
fix: Populate missing injectable params with defaults for internal fu…
trissim Feb 8, 2026
6a17c77
chore: Update submodule pointers for kwargs flattening fixes
trissim Feb 8, 2026
e57b5f8
fix: Drain progress queue with consumer thread to prevent executor de…
trissim Feb 8, 2026
9ac4758
chore: Update pyqt-reactive submodule pointer for click-to-provenance…
trissim Feb 8, 2026
8f73531
fix: Allow Ctrl+Z/Y in code editor for text undo/redo
trissim Feb 8, 2026
afd897f
fix: Display original function names in function table browser
trissim Feb 8, 2026
02953a7
chore: Update pyqt-reactive submodule pointer for function name displ…
trissim Feb 8, 2026
cd23977
chore: Update ObjectState submodule pointer for performance optimizat…
trissim Feb 8, 2026
71f4d61
fix: add missing system dependencies to Linux CI jobs
trissim Feb 8, 2026
714f149
fix: Replace deprecated pkg_resources with packaging.version
trissim Feb 8, 2026
8653de5
fix: Remove unavailable libegl1 package and add fallback for system d…
trissim Feb 8, 2026
32380f0
ci: install EGL/GL libs on ubuntu runners
trissim Feb 8, 2026
227a17b
bump version to 0.5.10
trissim Feb 8, 2026
5c0e873
feat: hierarchical progress tracking and server stability improvements
trissim Feb 8, 2026
d1748a4
Update README: fix logo, add killer features, improve installation in…
trissim Feb 8, 2026
728025e
Fix ASCII logo centering: use <pre> instead of code fence
trissim Feb 8, 2026
54313fc
bump version to 0.5.11
trissim Feb 8, 2026
8daf01b
Update project URLs to OpenHCSDev organization
trissim Feb 8, 2026
4d9bb45
bump version to 0.5.12
trissim Feb 8, 2026
3e3e009
chore: Update pyqt-reactive to v0.1.14-9-g48851ba
trissim Feb 9, 2026
f124625
chore: Update pyqt-reactive to v0.1.14-10-g423debe
trissim Feb 9, 2026
5e13736
chore: Update pyqt-reactive to v0.1.14-11-ge6d3f40
trissim Feb 9, 2026
d5baf74
chore: Update pyqt-reactive to v0.1.16
trissim Feb 9, 2026
4742a9a
chore: Update pyqt-reactive to v0.1.18
trissim Feb 9, 2026
07bd3d0
feat(microscopes): Add parse caching for performance optimization
trissim Feb 9, 2026
649d1f6
chore: update pyqt-reactive to v0.1.19
trissim Feb 9, 2026
531ebb4
feat(microscopes): improve ImageXpress filename parsing and formatting
trissim Feb 9, 2026
a2bf01e
fix(microscopes): revert parse_filename caching refactor due to regre…
trissim Feb 9, 2026
bc0aea4
bump version to 0.5.13
trissim Feb 9, 2026
b76ffe9
fix(plate_manager): clear stale server info on stop/force-kill to res…
trissim Feb 9, 2026
2bc19e8
Fix streaming race condition and improve worker assignment architecture
trissim Feb 9, 2026
d9bea44
chore: update pyqt-reactive and polystore submodule pointers
trissim Feb 9, 2026
7f1c5e0
fix: add null check in closeEvent to prevent crash when step_editor i…
trissim Feb 9, 2026
33a9f10
Add launching viewer indicators to ZMQ server browser tree
trissim Feb 9, 2026
ecdc143
Fix analysis consolidation to use compiler-resolved configs and step …
trissim Feb 9, 2026
33656dc
Add demo video showcasing OpenHCS platform
trissim Feb 10, 2026
44fb718
Add demo video link to README
trissim Feb 10, 2026
d5cc5bd
Embed demo video directly in README
trissim Feb 10, 2026
f8b3ff9
Fix README demo video URL and add direct fallback link
trissim Feb 10, 2026
9cb651f
Use GitHub-safe demo links in README
trissim Feb 10, 2026
fcb8524
Point README demo link to ReadTheDocs hosted MP4 player URL
trissim Feb 10, 2026
1dccadb
Remove debug lock-finding code from orchestrator
trissim Feb 11, 2026
f35afc9
bump version to 0.5.14
trissim Feb 11, 2026
497ae1e
bump version to 0.5.15
trissim Feb 11, 2026
d0ffba3
ci: skip existing versions on PyPI publish
trissim Feb 16, 2026
2cb6d23
ok
popjell Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[core]
hooksPath = hooks
91 changes: 84 additions & 7 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,25 @@ on:
options:
- cpu-only
- full-coverage
dependency_source:
description: 'Dependency source for external modules'
required: true
default: 'submodules'
type: choice
options:
- submodules
- pypi

env:
OPENHCS_CI_DEP_SOURCE: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.dependency_source || 'submodules' }}

jobs:
# Group 1: Python version boundary testing (6 jobs)
# Test oldest (3.11) and newest (3.13) Python on all 3 OSes
# Python 3.14 excluded: no pre-built NumPy wheels yet (builds from source stall on Windows)
python-boundary-tests:
runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -64,12 +75,30 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
# ubuntu-latest (23.10+) no longer provides libgl1-mesa-glx; use libgl1.
# PyQt6 requires libEGL.so.1 (EGL) and libGL.so.1 (OpenGL).
sudo apt-get install -y libgl1
sudo apt-get install -y libegl1 || sudo apt-get install -y libegl1-mesa
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 xvfb

- name: Install local external modules (submodule mode)
if: env.OPENHCS_CI_DEP_SOURCE == 'submodules'
run: |
python -m pip install --upgrade pip
python -c "import subprocess,sys;mods=['external/ObjectState','external/python-introspect','external/metaclass-registry','external/arraybridge','external/pycodify','external/PolyStore','external/pyqt-reactive','external/zmqruntime'];[subprocess.check_call([sys.executable,'-m','pip','install','-e',m]) for m in mods]"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -145,7 +174,7 @@ jobs:
# Test all backend/microscope combinations on all 3 OSes with Python 3.12
backend-microscope-tests:
runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -156,12 +185,30 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
# ubuntu-latest (23.10+) no longer provides libgl1-mesa-glx; use libgl1.
# PyQt6 requires libEGL.so.1 (EGL) and libGL.so.1 (OpenGL).
sudo apt-get install -y libgl1
sudo apt-get install -y libegl1 || sudo apt-get install -y libegl1-mesa
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 xvfb

- name: Install local external modules (submodule mode)
if: env.OPENHCS_CI_DEP_SOURCE == 'submodules'
run: |
python -m pip install --upgrade pip
python -c "import subprocess,sys;mods=['external/ObjectState','external/python-introspect','external/metaclass-registry','external/arraybridge','external/pycodify','external/PolyStore','external/pyqt-reactive','external/zmqruntime'];[subprocess.check_call([sys.executable,'-m','pip','install','-e',m]) for m in mods]"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -239,7 +286,7 @@ jobs:
# See: https://github.com/glencoesoftware/zeroc-ice-py-linux-x86_64/releases/tag/20240202
omero-tests-linux:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -253,12 +300,29 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install system dependencies (Linux)
run: |
sudo apt-get update
# ubuntu-latest (23.10+) no longer provides libgl1-mesa-glx; use libgl1.
# PyQt6 requires libEGL.so.1 (EGL) and libGL.so.1 (OpenGL).
sudo apt-get install -y libgl1
sudo apt-get install -y libegl1 || sudo apt-get install -y libegl1-mesa
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 xvfb

- name: Install local external modules (submodule mode)
if: env.OPENHCS_CI_DEP_SOURCE == 'submodules'
run: |
python -m pip install --upgrade pip
python -c "import subprocess,sys;mods=['external/ObjectState','external/python-introspect','external/metaclass-registry','external/arraybridge','external/pycodify','external/PolyStore','external/pyqt-reactive','external/zmqruntime'];[subprocess.check_call([sys.executable,'-m','pip','install','-e',m]) for m in mods]"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down Expand Up @@ -299,11 +363,13 @@ jobs:
# Code quality checks (linting, formatting, type checking)
code-quality:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python
uses: actions/setup-python@v5
Expand Down Expand Up @@ -333,7 +399,7 @@ jobs:
# Test PyPI-style installation across Python versions and OSes (6 jobs)
pypi-installation-test:
runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
Expand All @@ -343,6 +409,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
Expand Down Expand Up @@ -401,17 +469,27 @@ jobs:
# Run integration tests against wheel installation
wheel-integration-test:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'pull_request' || startsWith(github.ref, 'refs/tags/v')
if: github.event_name == 'push' || github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: ${{ env.OPENHCS_CI_DEP_SOURCE == 'submodules' && 'recursive' || 'false' }}

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install system dependencies (Linux)
run: |
sudo apt-get update
# PyQt6 requires libEGL.so.1 (EGL) and libGL.so.1 (OpenGL).
sudo apt-get install -y libgl1
sudo apt-get install -y libegl1 || sudo apt-get install -y libegl1-mesa
sudo apt-get install -y libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 xvfb

- name: Build wheel
run: |
python -m pip install --upgrade pip build
Expand All @@ -435,4 +513,3 @@ jobs:
name: coverage-wheel-integration
path: .coverage.wheel
retention-days: 1

2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ jobs:
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine check dist/*
twine upload dist/*
twine upload dist/* --skip-existing
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,4 @@ win_logs.txt
# Chunkhound
.chunkhound/
docs/generated_md/
.grepai/
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[submodule "external/python-introspect"]
path = external/python-introspect
url = https://github.com/OpenHCSDev/python-introspect.git
branch = master
branch = main
[submodule "external/arraybridge"]
path = external/arraybridge
url = https://github.com/OpenHCSDev/arraybridge.git
Expand Down
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

#### LLM-Powered Code Generation
#### Auto-Add Output Plate Feature
- **Automatic output plate registration** - New `auto_add_output_plate_to_plate_manager` config option in GlobalPipelineConfig
- When enabled, successfully completed plate runs automatically add the computed output plate to Plate Manager
- Allows immediate visualization of processed results without manual plate addition
- Environment variable: `OPENHCS_AUTO_ADD_OUTPUT_PLATE`
- Accessible via Config Window under Pipeline Settings

#### Compilation Architecture Improvements
- **Remote compilation via ZMQ server** - Compilation now happens on the ZMQ execution server instead of locally
- New shared `ZMQClientService` for managing ZMQ client connections between compilation and execution
- `CompilationService` and `ZMQExecutionService` now share a single client service instance
- Improved consistency and resource management across compile/run workflows
- Requires ZMQ server to be running for compilation (same as execution)

#### LLM-Powered Code Generation Improvements
- **LLM Assist in Code Editor** - Added LLM-powered code generation directly into the OpenHCS code editor
- **Automatic array backend handling** - Generated functions no longer require manual backend conversions (`cp.asnumpy()`, `cle.pull()`)
- **Context-aware system prompts** - New `get_system_prompt(code_type)` method provides different prompts for pipeline vs function generation
- **Array format clarification** - Documentation now specifies (C, Y, X) a.k.a. (Z, Y, X) format for 3D arrays
- **Memory decorator awareness** - LLM understands `@numpy`, `@cupy`, `@pyclesperanto` decorators and their implications
- New `LLMPipelineService` for communicating with local LLM endpoints (Ollama)
- New `LLMChatPanel` widget with chat interface for natural language code generation
- Integrated LLM panel into `QScintillaCodeEditorDialog` with toggle button
Expand Down
19 changes: 19 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.PHONY: dev install-hooks help

help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

dev: install-hooks ## Set up development environment (installs hooks and dependencies)
pip install -e ".[dev]"
@echo "✅ Development environment ready!"
@echo "Hooks are installed and will auto-update submodules on git operations."

install-hooks: ## Install git hooks for submodule auto-update
@git config core.hooksPath hooks
@echo "✅ Git hooks installed"

update-submodules: ## Manually update all submodules to latest
git submodule update --remote

status: ## Show submodule status
git submodule status
Loading