Versioned deterministic mapper from motor profiles to assistive cursor configs. DSP-grounded tremor compensation with EMA cutoff formulas, power-law deadzones, and phase compensation.
$ dotnet add package CursorAssist.Policy日本語 | 中文 | Español | Français | हिन्दी | Italiano | Português (BR)
A deterministic engine for assistive cursor control, UI accessibility benchmarking, and adaptive motor-skill training.
DateTime.Now, no Random, no platform-dependent floats. Every frame is reproducible and verifiable via FNV-1a hash chains.This workspace contains two products that share a common deterministic core:
For people with motor impairments (tremor, limited range, fatigue). Runs as a system tray application that intercepts and transforms raw pointer input in real time.
For building the dexterity to need less assistance over time. A .NET MAUI desktop game with fixed-timestep simulation.
The four CursorAssist libraries are published to NuGet as independent packages:
# Install individual packages
dotnet add package CursorAssist.Canon
dotnet add package CursorAssist.Trace
dotnet add package CursorAssist.Policy
dotnet add package CursorAssist.Engine
Or add to your .csproj:
<PackageReference Include="CursorAssist.Canon" Version="1.0.3" />
<PackageReference Include="CursorAssist.Trace" Version="1.0.3" />
<PackageReference Include="CursorAssist.Policy" Version="1.0.3" />
<PackageReference Include="CursorAssist.Engine" Version="1.0.3" />
You only need the packages you use. Canon and Trace are zero-dependency leaves. Policy depends on Canon. Engine depends on Canon and Trace.
using CursorAssist.Canon.Schemas;
using CursorAssist.Policy;
var profile = new MotorProfile
{
ProfileId = "user-001",
CreatedUtc = DateTimeOffset.UtcNow,
TremorFrequencyHz = 6f,
TremorAmplitudeVpx = 4.5f,
PathEfficiency = 0.72f,
OvershootRate = 1.2f,
};
AssistiveConfig config = ProfileToConfigMapper.Map(profile);
// config.SmoothingMinAlpha --> ~0.31 (closed-form from 6 Hz tremor)
// config.DeadzoneRadiusVpx --> ~2.7 (power-law freq-weighted)
// config.MagnetismRadiusVpx --> ~63.6 (scaled from path deficiency)
// config.PhaseCompensationGainS --> ~0.005 (conservative lag offset)
using CursorAssist.Engine.Core;
using CursorAssist.Engine.Transforms;
var pipeline = new TransformPipeline()
.Add(new SoftDeadzoneTransform())
.Add(new SmoothingTransform())
.Add(new PhaseCompensationTransform())
.Add(new DirectionalIntentTransform())
.Add(new TargetMagnetismTransform());
var engine = new DeterministicPipeline(pipeline, fixedHz: 60);
var context = new TransformContext
{
Tick = 0,
Dt = 1f / 60f,
Config = config,
Targets = []
};
var raw = new InputSample(X: 500f, Y: 300f, Dx: 2.1f, Dy: -0.8f,
PrimaryDown: false, SecondaryDown: false, Tick: 0);
EngineFrameResult result = engine.FixedStep(in raw, context);
// result.FinalCursor --> smoothed, deadzone-filtered, phase-compensated position
// result.DeterminismHash --> FNV-1a hash for replay verification
using CursorAssist.Trace;
using var writer = new TraceWriter("session.castrace.jsonl");
writer.WriteHeader(new TraceHeader
{
SessionId = "sess-001",
StartedUtc = DateTimeOffset.UtcNow,
TickRateHz = 60
});
writer.WriteSample(new TraceSample { Tick = 0, X = 500f, Y = 300f });
writer.WriteSample(new TraceSample { Tick = 1, X = 502.1f, Y = 299.2f });
CursorAssist libraries:
Canon --> (nothing) Schemas + DTOs (leaf)
Trace --> (nothing) Input recording (leaf)
Policy --> Canon Profile-to-config mapping
Engine --> Canon, Trace Transform pipeline
Runtime.Core --> Engine, Policy Thread management, config swap
Runtime.Windows --> Runtime.Core Win32 hooks, raw input
MouseTrainer libraries:
Domain --> (nothing) RNG, events, run identity (leaf)
Simulation --> Domain Game loop, mutators, levels
Audio --> Domain Cue system, asset verification
Apps:
CursorAssist.Pilot --> all CursorAssist libs Tray-based assistant
MouseTrainer.MauiHost --> all MouseTrainer libs MAUI desktop game
CLI tools:
CursorAssist.Benchmark.Cli --> Engine, Policy Replay benchmarking
CursorAssist.Profile.Cli --> Engine, Canon Motor profiling
Raw Input --> SoftDeadzone --> Smoothing --> PhaseCompensation --> DirectionalIntent --> TargetMagnetism --> Output
Each transform implements IInputTransform and is composed via TransformPipeline. The DeterministicPipeline wraps the chain in a fixed-timestep accumulator loop with FNV-1a hash verification on every tick.
DateTime.Now, no Random, no platform-dependent floats in the hot path. Every frame is hash-verified.fc = alpha * Fs / 2pi). Deadzone radii use power-law frequency weighting. Phase compensation is velocity-attenuated to prevent overshoot.# Clone
git clone https://github.com/mcp-tool-shop-org/CursorAssist.git
cd CursorAssist
# Build all projects
dotnet build
# Run all tests (214+ tests)
dotnet test
# Run CursorAssist tests only
dotnet test tests/CursorAssist.Tests/
# Run MouseTrainer tests only
dotnet test tests/MouseTrainer.Tests/
dotnet pack src/CursorAssist.Canon/CursorAssist.Canon.csproj -c Release -o ./nupkg
dotnet pack src/CursorAssist.Trace/CursorAssist.Trace.csproj -c Release -o ./nupkg
dotnet pack src/CursorAssist.Policy/CursorAssist.Policy.csproj -c Release -o ./nupkg
dotnet pack src/CursorAssist.Engine/CursorAssist.Engine.csproj -c Release -o ./nupkg
CursorAssist/
├── src/
│ ├── CursorAssist.Canon/ # Schemas + DTOs (NuGet leaf)
│ ├── CursorAssist.Trace/ # JSONL trace format (NuGet leaf)
│ ├── CursorAssist.Policy/ # Profile --> config mapper (NuGet)
│ ├── CursorAssist.Engine/ # Transform pipeline (NuGet)
│ │ ├── Core/ # Pipeline, InputSample, TransformContext
│ │ ├── Transforms/ # SoftDeadzone, Smoothing, PhaseComp, Intent, Magnetism
│ │ ├── Analysis/ # TremorAnalyzer, CalibrationSession
│ │ ├── Layout/ # UILayout for target/button mapping
│ │ ├── Mapping/ # Engine-internal mapper (delegates to Policy)
│ │ └── Metrics/ # IMetricsSink, Benchmark, Tracing, MotorProfile sinks
│ ├── CursorAssist.Runtime.Core/ # Thread management, config hot-swap
│ ├── CursorAssist.Runtime.Windows/ # Win32 hooks, raw input capture
│ ├── CursorAssist.Pilot/ # Tray-based assistant app
│ ├── CursorAssist.Benchmark.Cli/ # Replay benchmarking tool
│ ├── CursorAssist.Profile.Cli/ # Motor profiling tool
│ ├── MouseTrainer.Domain/ # RNG, events, run identity
│ ├── MouseTrainer.Simulation/ # Game loop, mutators, levels
│ ├── MouseTrainer.Audio/ # Event-driven audio cues
│ └── MouseTrainer.MauiHost/ # MAUI desktop game app
├── tests/
│ ├── CursorAssist.Tests/ # Engine, Policy, Canon, Trace tests
│ └── MouseTrainer.Tests/ # Domain, Simulation, Audio tests
├── tools/
│ └── MouseTrainer.AudioGen/ # Audio asset generator
├── docs/
│ ├── product-boundary.md # MouseTrainer scope definition
│ └── modular.manifesto.md # Modularity principles
└── MouseTrainer.Deterministic.sln # Solution file
CursorAssist is a local-first desktop application and NuGet library suite.
.castrace.jsonl), MAUI local storage for game sessionsFull policy: SECURITY.md
| Category | Score |
|---|---|
| A. Security | 10/10 |
| B. Error Handling | 10/10 |
| C. Operator Docs | 10/10 |
| D. Shipping Hygiene | 10/10 |
| E. Identity (soft) | 10/10 |
| Overall | 50/50 |
Built by MCP Tool Shop