The executor kept every commanded point on-screen via a per-strategy
BoundsPolicy of abort / clamp / reflect. Measured against the real
strategies, the other two earned nothing: abort truncated a sweep at the
first edge (line on a narrow screen ran only 90 of 250 steps), and clamp
could park the cursor against an edge (a monotonic ramp stalled 162 steps
in a row) -- both counter to the program's whole purpose of keeping the
cursor moving. reflect bounces off the edge and keeps going, and is
already what line/diagonal need in loop mode. arc's declared clamp was
provably dead code (it clamps its own endpoint, so no sample ever leaves
the screen).
Collapse to reflect-only:
- strategies.ts: remove the BoundsPolicy type and the `bounds` field from
the interface and all six strategies. Keep the local clamp() helper --
it's arc's endpoint geometry, not an on-screen policy; docstring says so.
- executor.ts: resolveTarget loses its policy parameter and its null
return and just reflects both axes; delete clampInt; SweepOutcome drops
"aborted"; ExecuteOptions drops `bounds`; remove the Out of bounds log.
- keeper.ts: loopOpts is now { restore: false, loop: true } -- the
reflect override added with loop mode is redundant.
- tests: drop the abort-outcome, clamp, and bounds-override tests; simplify
fixed() to take no policy; add a regression test that a monotonic ramp
past an edge never yields two identical points in a row (the guarantee
that motivated removing clamp).
Behavior is unchanged for every pattern at normal cursor positions
(verified: line's normal sweep is byte-identical). The only differences
are at a screen edge, where motion now bounces instead of stopping. No
config keys, flags, or pattern names changed.
Docs updated to match, including in-code comments, the README strategies
table (Bounds column removed) and verbose description, the sequence
diagram (resolveTarget signature + getPosition/width ordering + a loop-mode
note), and a CHANGELOG Changed entry.
199 lines
9.1 KiB
Markdown
199 lines
9.1 KiB
Markdown
# Changelog
|
|
|
|
All notable changes to `move` are documented here.
|
|
|
|
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).
|
|
|
|
## [Unreleased]
|
|
|
|
### Added
|
|
- Loop mode: `-l` / `--loop` (and the `loop` config key) keep the mouse
|
|
moving after a sweep is triggered until real user activity is detected,
|
|
instead of firing a single sweep. In loop mode the cursor is never restored
|
|
between iterations, so `line` and `diagonal` bounce edge-to-edge across the
|
|
screen (a roaming-DVD effect) rather than stopping at the first edge.
|
|
Patterns with a finite path (`jitter`, `walk`, `arc`, `figureEight`) chain
|
|
that path cycle after cycle. Interruption remains mouse-movement only.
|
|
|
|
### Changed
|
|
- Simplified on-screen confinement to a single policy: the executor now
|
|
reflects every pattern's out-of-range coordinates back inside the screen.
|
|
The `abort` and `clamp` bounds policies (and the per-strategy `bounds`
|
|
field) were removed. `abort` truncated a sweep at the first edge and `clamp`
|
|
could park the cursor against an edge — both counter to keeping the cursor
|
|
moving — while `reflect` bounces and keeps going. Behavior is unchanged for
|
|
every pattern at normal cursor positions; the only differences are at a
|
|
screen edge, where motion now bounces instead of stopping. No config keys,
|
|
flags, or pattern names changed.
|
|
|
|
## [1.3.3] - 2026-08-17
|
|
|
|
### Changed
|
|
- `install.sh` now installs the newest published tag by default instead of
|
|
tracking the `master` branch, so the plain `curl ... | sh` one-liner
|
|
installs a real release and reports its version (e.g. `v1.3.2`). The tag is
|
|
resolved from the Gitea tags API; if that lookup fails (offline, API
|
|
unreachable, or no tags yet) it falls back to `master`, preserving the old
|
|
behavior. Set `MOVE_VERSION` to pin an explicit branch or tag as before.
|
|
|
|
## [1.3.2] - 2026-08-17
|
|
|
|
### Added
|
|
- `install.sh` is now interactive. When it finds an existing install and a
|
|
controlling terminal is available, it reports what's there and asks before
|
|
replacing it, instead of leaving `MOVE_FORCE` as the only control. If a
|
|
config file already exists it asks separately whether to reseed it from the
|
|
shipped defaults. Both questions are asked before anything is downloaded or
|
|
deleted, so declining changes nothing.
|
|
- `MOVE_RESEED_CONFIG=1` overwrites the user config with the shipped defaults
|
|
without prompting, for unattended use. The previous file is kept as
|
|
`config.json.bak`; the same backup is written when reseeding is confirmed
|
|
at the prompt.
|
|
|
|
### Changed
|
|
- `MOVE_FORCE=1` now means "skip every prompt and reinstall unconditionally".
|
|
It deliberately does not touch the user config, so automation that
|
|
reinstalls the CLI can't take customizations down with it.
|
|
- Existing-install detection looks for the install tree and the wrapper, not
|
|
just the `.installed-version` marker, so a half-finished or hand-moved
|
|
install is caught rather than silently overwritten.
|
|
|
|
### Fixed
|
|
- Installing a *different* version over an existing one used to wipe and
|
|
replace it with no warning; only an exact version match was ever reported.
|
|
That case now prompts. With no terminal (CI, cron, container builds) the
|
|
previous non-interactive behavior is preserved exactly: an identical
|
|
version is a no-op, a different version is replaced.
|
|
|
|
## [1.3.1] - 2026-08-14
|
|
|
|
### Added
|
|
- `docs/execution-happy-path.md`: a sequence diagram (plus invariants) tracing
|
|
a clean idle-triggered sweep end to end, linked from the README.
|
|
|
|
### Fixed
|
|
- Stale comments corrected to match the current code: the `install.sh` /
|
|
`uninstall.sh` header curl URLs pointed at a nonexistent repo-root path
|
|
(they live under `scripts/`), so the documented command 404'd; `move.ts`'s
|
|
module list omitted `editor.ts` and the `--edit` step; and `config.ts` still
|
|
described a removed pixel unit.
|
|
|
|
## [1.3.0] - 2026-08-14
|
|
|
|
### Added
|
|
- Pluggable movement strategies. New `-p, --pattern <name>` flag and
|
|
`pattern` config key select how the cursor moves: `line` (default,
|
|
unchanged behavior), `diagonal`, `jitter`, `walk`, `arc`, `figureEight`.
|
|
Each pattern owns its own size and step count as constants; there is no
|
|
user knob for sweep magnitude.
|
|
- Pattern names are matched leniently: case and separators are ignored, so
|
|
`figureEight`, `figure-eight`, `figure_eight`, and `FIGUREEIGHT` are all
|
|
accepted (on the CLI and in the config file) and resolve to the canonical
|
|
name.
|
|
- `src/device.ts`: injectable `Device` seam over nut.js, enabling unit
|
|
tests for movement without the native binary or a real screen.
|
|
- `src/strategies.ts`: pure, per-pattern path generators plus the registry
|
|
and name validation.
|
|
- `src/executor.ts`: single `executePath` driver owning bounds policy
|
|
(`abort`/`clamp`/`reflect`), pacing, interrupt detection, and restore.
|
|
- Test suites for strategies, the executor (all bounds policies, rounding,
|
|
interrupt), and the keeper loop.
|
|
|
|
### Changed
|
|
- `simulateActivity` no longer hardcodes a straight-line sweep; it selects a
|
|
strategy from the registry and delegates execution to `executePath`. The
|
|
default `line` pattern is byte-for-byte the previous behavior.
|
|
- Interrupt detection now compares against the last *commanded* (rounded)
|
|
point rather than an ideal target, so fractional/curved paths don't
|
|
self-trip.
|
|
- `mouse.config.autoDelayMs = 0` moved from `runKeeper` into
|
|
`createNutDevice` — the single place nut.js is wired up.
|
|
- `runKeeper(config, device?)` accepts an injected device for testing.
|
|
- Interrupt detection tolerates a small (2px) gap between the commanded and
|
|
read-back cursor position, and the `clamp`/`reflect` patterns stay a few
|
|
pixels off the screen edge. Together these avoid false "user activity"
|
|
aborts from sub-pixel cursor placement on scaled or multi-monitor setups,
|
|
which the new edge-seeking patterns would otherwise hit. `line` (policy
|
|
`abort`) is unaffected.
|
|
|
|
### Removed
|
|
- `-n, --step-count` flag and the `stepCount` / `stepSize` config keys. Sweep
|
|
size and step count are now intrinsic to each movement pattern, not user
|
|
knobs. Config files that still contain these keys keep working: the loader
|
|
ignores them with a one-line notice instead of rejecting them, so existing
|
|
installs (all seeded with `stepCount`) don't break on upgrade. The removed
|
|
CLI flag, however, is a hard error like any other unknown option.
|
|
|
|
## [1.2.0] - 2026-06-17
|
|
|
|
### Added
|
|
- `-e, --edit` flag opens the resolved config file in `$EDITOR`.
|
|
|
|
### Changed
|
|
- `keeper.ts` (and `@nut-tree-fork/nut-js`) is lazy-imported, so `--help`
|
|
and `--version` skip the nut.js load and start ~10x faster.
|
|
|
|
## [1.1.1] - 2026-06-17
|
|
|
|
### Changed
|
|
- Tests moved from `src/` to a top-level `tests/` directory.
|
|
- `tsconfig.json` sets `"types": ["bun"]` so VS Code resolves `bun:test`.
|
|
|
|
### Fixed
|
|
- `package.json` version now matches the published tag.
|
|
|
|
## [1.1.0] - 2026-06-17
|
|
|
|
### Added
|
|
- JSON config file support at `${XDG_CONFIG_HOME:-~/.config}/move/config.json`.
|
|
Precedence: CLI flags > config file > defaults. Strict validation.
|
|
- `-C, --config <path>` to override the default config path.
|
|
- Installer seeds `config.json` with project defaults on fresh install only.
|
|
- Bun test suite for `resolveConfig` and `loadConfigFile`.
|
|
|
|
### Changed
|
|
- Installer scripts now live in `scripts/`.
|
|
- `verbose` is now a first-class `Config` field; `resolveVerbose` removed.
|
|
- `CliError` extracted into `src/errors.ts`.
|
|
- `defaultConfigPath()` throws when both `$XDG_CONFIG_HOME` and `$HOME` are unset.
|
|
- `mouse.config.autoDelayMs = 0` moved into `runKeeper` (no module-load side effect).
|
|
- Runtime errors go through a `failRuntime` helper that mirrors `failUser`.
|
|
- `keeper.ts` declares a named `Logger` interface.
|
|
- `dev-setup.sh` is now POSIX `sh`.
|
|
- `tsconfig.json`: enabled `noUncheckedIndexedAccess` and `resolveJsonModule`.
|
|
|
|
## [1.0.1] - 2026-06-17
|
|
|
|
### Added
|
|
- End-user `install.sh` runnable via `curl ... | sh`. XDG-respecting, idempotent.
|
|
- `uninstall.sh` removes the wrapper and install tree; leaves Bun and user
|
|
config alone.
|
|
- `dev-setup.sh` for contributors.
|
|
|
|
### Removed
|
|
- `DISTRIBUTION-PLAN.md` (design notes, superseded by the implementation).
|
|
|
|
## [1.0.0] - 2026-06-15
|
|
|
|
Initial release.
|
|
|
|
### Added
|
|
- `move` CLI for keeping presence-tracking apps marked Available by nudging
|
|
the cursor after a configurable idle period.
|
|
- Flags: `-h/--help`, `-v/--version`, `-m/--move-interval`,
|
|
`-c/--check-interval`, `-d/--step-delay`, `-n/--step-count`, `-V/--verbose`.
|
|
- Quiet-by-default logging.
|
|
- Source split into `src/{move,cli,config,keeper}.ts`.
|
|
- `bin` entry + shebang so `bun link` registers `move` globally.
|
|
|
|
[1.3.3]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.3.2...v1.3.3
|
|
[1.3.2]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.3.1...v1.3.2
|
|
[1.3.1]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.3.0...v1.3.1
|
|
[1.3.0]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.2.0...v1.3.0
|
|
[1.2.0]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.1.1...v1.2.0
|
|
[1.1.1]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.1.0...v1.1.1
|
|
[1.1.0]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.0.1...v1.1.0
|
|
[1.0.1]: https://gitea.cahlen.com/nokeo08/Move/compare/v1.0.0...v1.0.1
|
|
[1.0.0]: https://gitea.cahlen.com/nokeo08/Move/releases/tag/v1.0.0
|