Skip to content

Notifications from a Windows machine (from #115) - #120

Merged
makefunstuff merged 14 commits into
mainfrom
puchedev/windows-notifications
Nov 8, 2026
Merged

makefunstuff merged 14 commits into
mainfrom
puchedev/windows-notifications

Conversation

@makefunstuff

Copy link
Copy Markdown
Owner

puchedev's #115 carried on our branch: their commits, plus main merged in now that #108 is in (via #117). The overlap with #108 is resolved by taking #115's newer herdr-push (v13) and READMEs; PushTest keeps the version-independent status check from #117. Core tests pass locally.

The security review (HERD-34) found #115 clean. One thing to know: on Windows, herdr-push now sets itself up to start the way it does with systemd or launchd elsewhere. It adds an HKCU Run value and a per-user scheduled task (InteractiveToken, LeastPrivilege, not hidden), both removed by uninstall. It also tells the phone the PC's last-input time and lock state, inside the existing sealed push.

Closes #115.

🤖 Generated with Claude Code

puchedev and others added 14 commits November 7, 2026 21:09
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tailscale's installer adds its folder to the system PATH, but sshd and every
shell already open keep the old PATH until restarted, so `pair` missed the
Tailscale name and address and the code carried only the local network one.
Fall back to %ProgramFiles%\Tailscale\tailscale.exe on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pairing screen and the README say Windows' interpreter is usually
python, and the README's Windows paragraph names what herdr-core gives
there rather than a list of screens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
HcPipe talks to `herdr-core connect` over its stdin and stdout like HerdrCore does over the
socket, with a 3 s deadline on every answer; core_look uses it on Windows once `server status`
says a core runs. `once` now runs there. Version 13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read_memory uses GlobalMemoryStatusEx (swap from the page files), read_cpu
GetSystemTimes, read_disks each fixed drive as /c, /d, and top_memory the
working set of each process from CIM through PowerShell.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
typed_at reads the session's last keyboard or mouse input (GetLastInputInfo
against GetTickCount64, modulo 2**32), and screen_unlocked is False while
LogonUI.exe runs in this session or the input desktop can't be opened.
Both only mean something in the interactive session. `presence` now runs
on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The watcher runs in the signed-in user's own desktop session: install writes
the HKCU Run value and a per-user scheduled task (/it, no elevation), and
install and ensure start it through that task, never as a child of SSH. Locks
use a byte of the lock file far from the pid (Windows locks are mandatory),
run logs to the log file under pythonw.exe, status says whether a session is
interactive, and tick closes its herdr-core connections in a finally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The scheduled task is created from an XML (schtasks /create /xml) instead of
the bare command line: a task made that way stops after 72 hours and doesn't
run on battery, which would kill a watcher started through it. The XML has no
time limit, no battery rules and no trigger (the Run value starts it at
sign-in, the task only runs on demand), and still runs as the current user
with no elevation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ensure recreates the task (and the Run value, when sign-in autostart is
installed) before starting the watcher; install writes the Run value first
and survives a failed task; write_json retries a busy target on Windows;
install starts the task again if the stopped watcher made it ignore the
first start; a failed temp-file delete no longer fails task creation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…flag

While the PC was locked, presence said it was unlocked: LogonUI.exe is a SYSTEM
process, so ProcessIdToSessionId is refused for it, and the input desktop can
still be opened on the lock screen. The session's lock flag from the terminal
service (WTSSessionInfoEx) is asked first now, and the process list comes from
WTSEnumerateProcessesW, which gives every process its session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s kill can't hang the watcher

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fications

# Conflicts:
#	README.md
#	core/src/test/kotlin/com/makefunstuff/herdr/core/PushTest.kt
#	host/herdr-push/README.md
#	host/herdr-push/herdr-push
@makefunstuff
makefunstuff merged commit 9327e72 into main Nov 8, 2026
12 checks passed
@makefunstuff
makefunstuff deleted the puchedev/windows-notifications branch November 8, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants