Refactor CLI, add refresh command, fix port detection, add device tracking

- Remove build/upload/monitor subcommands (projects are self-contained)
- Remove ctrlc dependency (only used by removed monitor watch mode)
- Update next-steps messaging to reference project scripts directly

- Add 'anvil refresh [DIR] [--force]' to update project scripts
  to latest templates without touching user code

- Fix Windows port detection: replace fragile findstr/batch TOML
  parsing with proper comment-skipping logic; add _detect_port.ps1
  helper for reliable JSON-based port detection via PowerShell

- Add .anvil.local for machine-specific config (gitignored)
  - 'anvil devices --set [PORT] [-d DIR]' saves port + VID:PID
  - 'anvil devices --get [-d DIR]' shows saved port status
  - VID:PID tracks USB devices across COM port reassignment
  - Port resolution: -p flag > VID:PID > saved port > auto-detect
  - Uppercase normalization for Windows COM port names

- Update all .bat/.sh templates to read from .anvil.local
- Remove port entries from .anvil.toml (no machine-specific config in git)
- Add .anvil.local to .gitignore template
- Expand 'anvil devices' output with VID:PID, serial number, and
  usage instructions
This commit is contained in:
Eric Ratliff
2026-02-16 08:29:33 -06:00
parent 3298844399
commit 8fe1ef0e27
25 changed files with 2551 additions and 731 deletions

View File

@@ -0,0 +1,78 @@
# _detect_port.ps1 -- Detect the best serial port via arduino-cli
#
# Called by upload.bat and monitor.bat. Outputs a single port name
# (e.g. COM3) or nothing if no port is found.
#
# If .anvil.local contains a vid_pid, resolves the device to its
# current COM port (handles reassignment after replug).
# Falls back to saved port, then auto-detect.
param(
[string]$VidPid = "",
[string]$SavedPort = ""
)
$ErrorActionPreference = 'SilentlyContinue'
$raw = arduino-cli board list --format json 2>$null
if (-not $raw) {
# No arduino-cli or no output; fall back to saved port
if ($SavedPort) { Write-Output $SavedPort }
exit
}
$data = $raw | ConvertFrom-Json
if (-not $data.detected_ports) {
if ($SavedPort) { Write-Output $SavedPort }
exit
}
$serial = $data.detected_ports | Where-Object { $_.port.protocol -eq 'serial' }
if (-not $serial) {
if ($SavedPort) { Write-Output $SavedPort }
exit
}
# -- Try VID:PID resolution first ------------------------------------------
if ($VidPid) {
$parts = $VidPid -split ':'
if ($parts.Count -eq 2) {
$targetVid = $parts[0].ToLower()
$targetPid = $parts[1].ToLower()
foreach ($p in $serial) {
$pVid = ($p.port.properties.vid -replace '^0x','').ToLower()
$pPid = ($p.port.properties.pid -replace '^0x','').ToLower()
if ($pVid -eq $targetVid -and $pPid -eq $targetPid) {
Write-Output $p.port.address
exit
}
}
# VID:PID not found -- device not connected
# Fall through to saved port / auto-detect
}
}
# -- Fall back to saved port if it exists on the system --------------------
if ($SavedPort) {
$found = $serial | Where-Object { $_.port.address -eq $SavedPort } | Select-Object -First 1
if ($found) {
Write-Output $SavedPort
exit
}
# Saved port not present either; fall through to auto-detect
}
# -- Auto-detect: prefer USB serial ports ----------------------------------
$usb = $serial | Where-Object { $_.port.protocol_label -like '*USB*' } | Select-Object -First 1
if ($usb) {
Write-Output $usb.port.address
exit
}
# Fall back to any serial port
$any = $serial | Select-Object -First 1
if ($any) {
Write-Output $any.port.address
}