Answers 'is it even running?' within seconds of 'atm run' — no waiting
30 min for heartbeat + no need for a live trigger to occur.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
With tol=25 all dots in the strip fused into one blob via 1px anti-aliased
bridges between adjacent dots → centroid landed mid-strip instead of on the
rightmost dot. Erosion (3x3 kernel, 2 iters) cleanly separates discrete
dots before connected-components labelling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dots on M2D MAPS strip are so close that anti-aliased edge pixels bridge
adjacent dots column-counts → the previous walk-left approach merged the
entire strip into one cluster and picked its midpoint.
Connected components (8-connectivity) treats each dot as a separate blob
even when antialiased edges touch. We pick the blob with the largest
right-edge, then return its centroid. Robust, O(pixels), one opencv call.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Also: calibrate._sample_rgb now snaps to the most-saturated pixel within 15px
of the click, so rough clicks still pick up the dot's pure colour. Default
dot-colour tolerance bumped 30→60 to absorb anti-aliasing.
Test fixture _SAMPLED_RGB recomputed for the new 36/49 dilution (was 24/49
when sampling at the trailing edge).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
User's chart background is pure black (0,0,0) but detector hardcoded (18,18,18)
with tol=15. Gap pixels between dots (0,0,0) fell outside background tolerance,
so find_rightmost_dot locked onto a gap pixel rather than a dot. Now falls back
to the config's background spec if defined.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same fix as atm debug: desktop snapshot happens several seconds after user
confirms, giving time to alt-tab TradeStation to the foreground and get
rid of terminal/IDE windows covering it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Quick sanity check after calibration. Prints window/dot detection state,
classified colour + confidence, saves full/cropped/annotated frames to logs/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Problem: region-select crop is in its own coord-frame, but runtime capture
used pygetwindow+mss with the window's coords → ROI coords mismatch, chart
not captured correctly.
Fix: region-select now returns (image, virtual-desktop region). Wizard saves
'chart_window_region' in config. At runtime, _build_capture() prefers region
mode: grabs the same virtual-desktop rectangle, so ROI coords line up.
Users who calibrated before this commit must re-run 'atm calibrate' OR add
chart_window_region to their TOML manually. If window moves, canary will
detect drift and auto-pause.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Window-level PrintWindow/mss returns blank on GPU-accelerated apps
(TradeStation, some trading terminals). Switch to full-desktop screenshot
+ drag-rectangle as the default method — reliable across all apps.
- Title prompt still asked (needed by 'atm run' to locate window at runtime).
- Captured region saved to logs/calibrate_capture_<ts>.png for verification.
- Old window-capture path kept as fallback if region-select is cancelled.
- Minor: silence pyright windll attr warning.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Enumerate all matching windows, let user pick the largest one if multiple.
- Try PrintWindow first (works with GPU-accelerated apps like TradeStation
that render blank under plain mss capture).
- Detect blank/uniform captures and fall back to mss automatically.
- Save captured frame to logs/calibrate_capture_<ts>.png for debugging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace skeletal wizard (window title only) with complete click-to-sample flow:
- Screenshot target window via mss+pygetwindow (Windows) or --screenshot PNG
- Single-canvas Tk wizard with scaled display + back/skip/save controls
- Stepwise clicks collect: dot_roi, all 7 dot colours (+ optional background),
chart_roi, 2 y-axis reference points with prices, canary region
- Auto-compute canary baseline phash at save time
- Pull Discord/Telegram creds from ATM_DISCORD_URL/ATM_TG_TOKEN/ATM_TG_CHAT env
- Add --screenshot flag to 'atm calibrate' for non-Windows dev testing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Cast res.color to DotColor in run_live loop.
- Add [tool.pyright] extraPaths to pyproject.toml for IDE resolution.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>