Merged origin/main (release v3.0.0) into main and preserved fork features:
- Minimal compact prompt window (140px) that expands with editor/history.
- Larger pet speech bubbles that scale with pet/window size.
- Improved chat command memory extraction (/remember, /memorize, /note, don't forget).
- Continuous pet scale slider from 0.16x to 10x (screen-filling).
Version bumped to 3.1.0.
- Prompt window opens at 140px compact height and expands to 456px when editor/history shown.
- Pet speech bubbles scale with larger pets and window sizes; removed text overflow clipping.
- Extracted prompt memory extraction into testable module; added /remember, /memorize, /note, don't forget patterns.
- Replaced pet scale dropdown with continuous slider from 0.16x to 10x.
- Added prompt-memory-extraction.test.ts and updated packaging/onboarding tests.
- packages/sdk: new types-only @open-pets/plugin-sdk — OpenPetsContext + the
ambient OpenPetsPlugin global, plus a mock-ctx contract test. Zero runtime
deps; published for editor autocomplete (npm i -D @open-pets/plugin-sdk).
- cli: `openpets plugin new <name>` scaffolds a plugin folder (manifest +
entry + README) so step zero is npx, not copy-paste.
- desktop: compile-time conformance guard tying the runtime plugin SDK
(namespaces + JS permission set) to the published @open-pets/plugin-sdk
contract, so the two can't drift.
- release-npm: include packages/sdk in the publish order.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Multi-monitor fix: pet stays on its current display instead of being
clamped back to the primary screen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pet window position was always clamped to the primary display's
work area via clampToPrimaryWorkArea. On a multi-monitor setup, a pet
dragged onto an external monitor was yanked back to the built-in screen
whenever its position was read, saved, or restored — most visibly when
display-metrics-changed fires (display sleep/wake, scale changes, Space
switches), which macOS emits frequently.
Clamp to the display nearest the window's centre instead, so the pet
stays on whatever monitor it lives on. If that display is disconnected,
getDisplayNearestPoint falls back to a connected one, preserving the
keep-on-screen safety net.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a heartbeat fails, the MCP server previously cleared the lease and
stopped heartbeating permanently, making the pet unresponsive for the
rest of the session.
Now on heartbeat failure:
- Enters retry mode with exponential backoff (5s → 10s → 20s → 40s → 60s cap)
- Re-acquires lease automatically when the desktop app recovers
- Resumes normal 5s heartbeat after successful re-acquisition
Also adds on-demand lease recovery in react/say tool handlers — if the
lease is expired when a tool is called, it attempts to acquire a new one
before returning an error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>