diff --git a/.idea/modules.xml b/.idea/modules.xml
index 46b271a..6ea9d61 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -3,7 +3,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 8a2e8df..f837adc 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -8,6 +8,6 @@
-
+
\ No newline at end of file
diff --git a/AGENTS.md b/AGENTS.md
index c799ec9..c126380 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -16,7 +16,7 @@ The Medoc TCP client is a **subpackage** at `src/heat_task/medoc/` (console scri
- `models.py` — protocol enums/dataclasses (`Command`, `ReturnCode`, `MedocResponse`, …)
- `cli/` — the `medoc` command line (`parser.py`, `commands.py`, `formatting.py`, `__init__.py` wires `main`)
-Task-agnostic experiment plumbing — screen/VSYNC setup, run manifest, CSV writers, setup-wizard primitives, instruction pager, keyboard abstraction — comes from the separate **`psyexp-core`** package. `pyproject.toml` pins it to a git tag (`[tool.uv.sources]`) so clones reproduce exactly. For local co-development, set `UV_NO_SYNC=1` (export it in your shell, or use `uv run --no-sync`) and overlay `uv pip install -e ../psyexp-core` — that stops `uv run`'s auto-sync from reverting the editable install (and from removing the manually-installed Apple Silicon psychtoolbox). See README "Co-developing `psyexp-core` locally".
+Task-agnostic experiment plumbing — screen/VSYNC setup, run manifest, CSV writers, setup-wizard primitives, instruction pager, keyboard abstraction — comes from the separate **`psyexp-core`** package, declared as a published PyPI dependency (`psyexp-core>=X.Y`) and pinned exactly in `uv.lock` so clones reproduce. For local co-development overlay an editable sibling checkout (`uv pip install -e ../psyexp-core`) and run with `uv run --no-sync` (or `UV_NO_SYNC=1`, or the `just core-*` recipes). The two overlays behave differently under sync: `uv sync --inexact` keeps the manually-installed Apple Silicon psychtoolbox (it is *not* in the lock), but it does **not** keep the editable `psyexp-core` (it *is* in the lock, so a sync reverts it) — only skipping the sync preserves that. See README "Co-developing `psyexp-core` locally".
## Terminology
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae04096..d95e30a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## v1.0.0-rc.2
+
+### Changed
+
+- Bumped `psyexp-core` to `v0.8.0`
+
## v1.0.0-rc.1
First release candidate for 1.0.0.
diff --git a/docs/development.md b/docs/development.md
index 3cb8fa8..ef12b42 100644
--- a/docs/development.md
+++ b/docs/development.md
@@ -29,10 +29,11 @@ Silicon, install it manually from the lab build, e.g.
uv pip install ../Psychtoolbox-3/dist/psychtoolbox-3.0.22.2-cp311-cp311-macosx_10_9_universal2.whl
```
-Because `uv sync`/`uv run` are exact by default and will remove the manual install, run them as
-`uv sync --inexact` and `uv run --no-sync …` (or set `UV_NO_SYNC=1`) to keep it. On Windows the lab
-build is needed similarly; otherwise PsychoPy's own transitive `psychtoolbox` (`<3.0.20`,
-non-arm64) applies.
+Because `uv sync` is exact by default it removes the manual install — run it as `uv sync --inexact`
+to keep psychtoolbox. (`uv run`'s implicit sync is *inexact*, so it leaves the manual install alone;
+pass `--no-sync` only when you are also overlaying an editable `psyexp-core`, which *is* in the lock
+and would otherwise be reverted.) On Windows the lab build is needed similarly; otherwise PsychoPy's
+own transitive `psychtoolbox` (`<3.0.20`, non-arm64) applies.
## Quick Start
@@ -71,11 +72,11 @@ are ignored by pip/conda, so the conda install resolves dependencies fresh from
from the lockfile. `psychtoolbox` is still not pulled in automatically (see below) — install the lab
build manually after creating the environment.
-> **Heads up — `uv run` auto-syncs the venv from `uv.lock` on every launch.** That sync will
-> (a) revert a local editable `psyexp-core` back to the pinned git tag and (b) remove the manually
-> installed Apple Silicon psychtoolbox wheel. Disable it by setting `UV_NO_SYNC=1` — either
-> `export UV_NO_SYNC=1` in your shell session or prefix individual commands with
-> `uv run --no-sync …`.
+> **Heads up — `uv run` auto-syncs the venv from `uv.lock` on every launch** (inexactly: it won't
+> remove your manually-installed psychtoolbox, but it *will* revert a local editable `psyexp-core`
+> back to the locked PyPI version, since the core is in the lock). While co-developing the core,
+> skip that sync with `UV_NO_SYNC=1` — `export` it in your shell, prefix commands with
+> `uv run --no-sync …`, or use the `just core-*` recipes.
## Co-developing `psyexp-core` locally
@@ -93,8 +94,16 @@ uv pip install -e ../psyexp-core # one time
uv run heat-task # uses your local core, edits are live
```
-After changing *other* dependencies you'll need a manual `uv sync` (auto-sync is off) — that
-re-clobbers psyexp-core, so re-run the editable install above.
+The `just core-dev` / `just core-run` / `just core-test` recipes wrap this — they overlay the
+editable checkout and run with `--no-sync`. Note `uv sync --inexact` does **not** preserve the
+editable core: `--inexact` only spares packages absent from the lock (that's what keeps
+psychtoolbox), and the core *is* in the lock, so only skipping the sync keeps it. After changing
+*other* dependencies you'll need a manual `uv sync --inexact` — that reverts psyexp-core, so re-run
+the editable install (or `just core-dev`) afterward.
+
+For a setup that survives sync, declare the path source in `pyproject.toml`
+(`[tool.uv.sources] psyexp-core = { path = "../psyexp-core", editable = true }`) and keep that edit
+local with `git update-index --skip-worktree pyproject.toml uv.lock`.
## Updating `psyexp-core`
@@ -107,7 +116,7 @@ uv lock --upgrade-package psyexp-core # rewrite uv.lock to the newest version
uv sync --inexact # apply it; --inexact keeps the manual psychtoolbox install
```
-Then commit the updated `uv.lock`. Raise the `>=` floor in `pyproject.toml` first if you want to
+(`just core-upgrade` runs both commands.) Then commit the updated `uv.lock`. Raise the `>=` floor in `pyproject.toml` first if you want to
require a new minimum. CI (`.github/workflows/tests.yml`) reads the pinned version straight from
`uv.lock` via `uv export --frozen`, so it tracks the upgrade automatically once the lock is
committed.
diff --git a/justfile b/justfile
new file mode 100644
index 0000000..0cbb59d
--- /dev/null
+++ b/justfile
@@ -0,0 +1,51 @@
+# heat-task dev tasks. Run `just` to list recipes.
+# Requires `just` (https://github.com/casey/just): `brew install just`.
+
+# Show available recipes
+default:
+ @just --list
+
+# Install/refresh the venv (--inexact keeps the manual psychtoolbox install)
+sync:
+ uv sync --inexact
+
+# Run the task (locked PyPI core)
+run *args:
+ uv run heat-task {{args}}
+
+# Talk to the thermode via the vendored medoc CLI
+medoc *args:
+ uv run medoc {{args}}
+
+# Run the test suite
+test *args:
+ uv run pytest {{args}}
+
+# --- Co-developing psyexp-core from ../psyexp-core ---------------------------
+# Two overlays, two rules:
+# * psychtoolbox (NOT in the lock) -> kept by `uv sync --inexact`
+# * editable psyexp-core (IN the lock) -> only kept by skipping the sync;
+# `--inexact` does NOT save it.
+# Co-development runs with --no-sync, which preserves both at once.
+
+# Overlay an editable sibling checkout of ../psyexp-core
+core-dev:
+ uv pip install -e ../psyexp-core
+ @echo "Editable psyexp-core overlaid. Use 'just core-run' / 'just core-test' so it isn't reverted."
+
+# Run the task against the editable overlay (no sync; keeps core + psychtoolbox)
+core-run *args:
+ uv run --no-sync heat-task {{args}}
+
+# Run the tests against the editable overlay
+core-test *args:
+ uv run --no-sync pytest {{args}}
+
+# Drop the editable core, restore the locked PyPI version (keeps psychtoolbox)
+core-release:
+ uv sync --inexact
+
+# Upgrade to the newest published psyexp-core and update the lock
+core-upgrade:
+ uv lock --upgrade-package psyexp-core
+ uv sync --inexact
diff --git a/pyproject.toml b/pyproject.toml
index 89c7cfa..d56b571 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -17,10 +17,10 @@ dependencies = [
# Note: psychtoolbox is NOT declared here. PyPI has no arm64 wheel for it, so on
# Apple Silicon install it manually from the lab build, e.g.
# uv pip install ../Psychtoolbox-3/dist/psychtoolbox-3.0.22.2-cp311-cp311-macosx_10_9_universal2.whl
-# Because `uv sync`/`uv run` are exact by default and will remove it, run them as
-# `uv sync --inexact` and `uv run --no-sync ...` (or set UV_NO_SYNC=1) to keep the
-# manual install. On Windows the lab build is needed similarly; PsychoPy's own
-# transitive psychtoolbox (<3.0.20, non-arm64) otherwise applies.
+# Because `uv sync` is exact by default it removes the manual install — run it as
+# `uv sync --inexact` to keep psychtoolbox. (`uv run`'s implicit sync is inexact,
+# so it leaves the manual install alone.) On Windows the lab build is needed
+# similarly; PsychoPy's own transitive psychtoolbox (<3.0.20, non-arm64) otherwise applies.
[project.scripts]
heat-task = "heat_task.__main__:run"