Commit Graph

8 Commits

Author SHA1 Message Date
wmantly 12d55a4454 feat(icons): clean tray badge set + Start menu/installer icon
New cmd/icon-gen renders the four state badges (Red/Yellow/Green/Blue) as a
rounded-square badge with a subtle vertical gradient and a crisp white theta,
256px with 4x4 supersampling. The tray embeds these (icons.go, generated) and
builds a proper multi-size Windows ICO (16..256) via exact box filtering --
replacing the old flat 48px circle and nearest-neighbour scaling.

The installer now bundles theta-agent.ico (multi-size, Blue badge) and uses it
for the Start menu 'Theta Agent Tray' shortcut, the setup.exe icon
(SetupIconFile), and the uninstaller display icon. Dead duplicate icon arrays
in the root package (tray_icons.go) removed.
2026-08-10 18:49:30 -07:00
wmantly d18de7d109 test(tray): add pngToIco + toWindowsIcon structure tests
Overlooked when the tray dir was gitignored by theta-agent-*; the negation in
.gitignore now lets the test be tracked.
2026-08-09 19:07:12 -07:00
wmantly 016a8fc6b6 fix(tray): Windows tray icon now loads — PNG->ICO with BMP entries
fyne.io/systray requires .ico content on Windows, and LoadImage cannot read
PNG-in-ICO. The embedded icons are PNG, so SetIcon always failed and no tray
icon ever appeared. pngToIco decodes the PNG and re-encodes classic BMP
(XOR + AND mask) entries at 16/32/48px — the format LoadImage has always
supported. Verified: the 'unable to set icon' error is gone and the tray
process stays up.

feat(installer): wizard page, Start Menu icons, silent install params

- Wizard page asks for the SSO Manager URL + join key, with an 'Open SSO
  install-agent page' button (ShellExec); values feed agent.yml
- /SERVER_URL /JOIN_KEY /AUTH_TOKEN /PUBLIC_KEY and /B64_CONFIG (base64 of a
  full agent.yml, decoded by an inline B64Decode) drive the same result in
  /SILENT mode, so the SSO's Install Agent modal can emit one Windows command
- [Icons]: Theta Agent Tray / Open Agent Config / Uninstall in Start Menu
- WireGuard client launches its UI at the end of the MSI; taskkill after the
  msiexec step closes it (the tunnel is agent-managed)
- tray starts right after install (not just at next logon)
- Inno 7 fixes: controls parent to Page.Surface, SaveStringsToUTF8FileWithoutBOM

Adds pngToIco structure tests (valid ICO dir + 32bpp DIBs) and a platform
passthrough test for toWindowsIcon.

Rebuilds all tracked dist binaries + the setup.exe.
2026-08-09 19:06:00 -07:00
wmantly e613874de5 feat(windows): WireGuard client, auto-VPN, IAM, tray enrichment, installer, CI
Second milestone of the Windows parity work (DESIGN-WINDOWS.md §13).

WireGuard mesh client (signed, WSS-delivered):
- wireguard_apply / wireguard_remove commands: Ed25519-verified, gated on a new
  wireguard capability. Linux applies via wg-quick up/down; Windows installs the
  peer config as a WireGuardTunnel service via wireguard.exe
  (/installtunnelservice, /uninstalltunnelservice)
- state polling in the home monitor drives the blue tray icon and auto-VPN:
  connect when away from home + auto_vpn, disconnect on return (2m cooldown)
- tray VPN toggle and the auto-VPN checkbox are now live; the preference
  persists to agent.yml (PersistAutoVPN)

IAM on Windows (iam_windows.go):
- allowed_login_groups -> net localgroup; ssh_keys -> per-profile
  authorized_keys + %ProgramData%\ssh\administrators_authorized_keys;
  revoke_users -> helper logs off all of the user's WTS sessions;
  sudo_rules logged as no direct equivalent

Tray enrichment:
- Open Config (opens agent.yml), Clear enrollment (re-enroll) menu items
- set_auto_vpn persists; vpn_connect/vpn_disconnect/reinit/open_config commands
  handled by the daemon (tray_server.go)

Packaging & release:
- installer/windows/installer.iss: fully-offline Inno Setup bundle (agent,
  tray, helper, vendor-signed WireGuard MSI, OpenCredential CP, VC++ redist),
  /SILENT /SERVER_URL /JOIN_KEY parameters, SYSTEM service + HKLM Run tray
  autostart, Users-writable %ProgramData%\Theta42 for the IPC socket
- .github/workflows/build-windows.yml: build + test, pinned vendor downloads,
  ISCC compile, Azure Trusted Signing (OIDC), SHA256SUMS, GH release attach,
  optional SSO resource publish
- agent.yml.example documents auto_vpn, wireguard, service_name,
  desktop_helper, public_ip_detect

Tests:
- wireguard_apply/remove dispatch (allowed + capability-denied), PersistAutoVPN,
  ClearEnrollment; dispatch tests pin linuxPlatformOps with a temp WireGuard conf
- end-to-end verified against a local mock SSO on Windows: join-key enrollment
  (token persisted, join key blanked), discovery/telemetry pushed, signed
  arbitrary_bash verified + executed via powershell -EncodedCommand; tray IPC
  socket binds %ProgramData%\Theta42; LDAP byte-pump binds 127.0.0.1:389;
  helper update swap verified

Rebuilds all tracked dist binaries (v2.1.0).
2026-08-09 17:49:40 -07:00
wmantly 4a619f7adc feat(windows): platform ops, service wrapper, helper, and air-gap paths
First Windows parity milestone (DESIGN-WINDOWS.md §13 build order item 1).

- Add a PlatformOps abstraction so command dispatch is OS-neutral:
  - linuxPlatformOps keeps today's systemctl/journalctl/bash behavior (deliberately
    untagged so shared dispatch tests run on Windows CI)
  - windowsPlatformOps maps reboot/shutdown to shutdown.exe, service control to
    sc.exe (stop+start for restart), fetch_logs to Get-WinEvent, arbitrary_bash to
    powershell -EncodedCommand (byte-exact under arbitrary quoting), and declines
    configure_ldap (Windows logon goes through OpenCredential)
- Run theta-agent as a Windows service (x/sys/windows/svc): SYSTEM auto-start,
    SCM stop/shutdown handling; CLI install-service/remove-service via svc/mgr
- Add theta-agent-helper (session-0 companion): lock/display_off/logout via
    user32/wtsapi32, and staged self-update (wait for service stop, swap the
    locked exe, sc start)
- Self-update becomes platform-aware: Linux renames over the running binary;
    Windows stages .new and hands the swap to the helper (running exe is locked)
- Platform paths: agent.yml and tray.sock under %ProgramData%\Theta42 (the
    service runs as SYSTEM while the tray runs as the user, so the per-user temp
    dir no longer works for tray IPC); LDAP byte-pump falls back to TCP loopback
- config: service_name, desktop_helper, public_ip_detect (air-gap: skips
    external public-IP lookups in telemetry + home monitor), wireguard block
- cli: platform-aware config path + self-update artifact name + service restart
- tests: dispatch tests pin linuxPlatformOps; 0600 mode assertions gated to
    POSIX so the suite is green on Windows

Rebuilds all tracked dist binaries (v2.1.0).
2026-08-09 17:10:07 -07:00
wmantly 565a171797 fix(tray): support Windows socket paths and always run the tray companion on Windows
The tray IPC socket was hardcoded to /run/theta/tray.sock and /tmp/theta-tray.sock,
which cannot be bound on Windows (they resolve to C:\run\... and C:\tmp\... and need
admin rights). The daemon now binds a Unix socket under the per-user temp dir on
Windows, and the tray companion dials the same path.

The tray also exited immediately on Windows because it checked DISPLAY/WAYLAND_DISPLAY,
which are never set there. That graphical-session guard is now Windows-only; the tray
always runs on Windows.
2026-08-09 16:11:42 -07:00
wmantly 37e7ffd25d fix(tray): render full-color badge disk icons from theta42.svg and fix home LAN detection for local servers 2026-08-08 23:29:44 -04:00
wmantly 16cab898ed feat(tray): update tray icons to use rasterized official theta42.svg asset 2026-08-08 23:27:29 -04:00