Commit Graph
20 Commits
Author SHA1 Message Date
mika kuns 45bc324402 feat(installer): add Git, GitIdentity, Port, and WriteAccess preflight checks
Implements IEnvironmentCheck for the four checks derivable without a
Claude CLI probe:
- GitCheck (Error) - resolves git via ExecutableResolver (handles .cmd
  shims), parses `git --version`.
- GitIdentityCheck (Warning) - user.name/user.email presence; Unknown
  (not Failed) if git itself is missing, so it doesn't duplicate GitCheck's
  failure.
- PortCheck (Warning) - loopback bind probe for SignalRPort/ExternalMcpPort;
  resolves the owning process via a new NetstatPortOwnerResolver and treats
  a port held by the running ClaudeDo.Worker (update/repair case) as Ok.
  Both ports are configurable, hence a warning.
- WriteAccessCheck (Error) - create+delete a probe file in InstallDirectory
  and ~/.todo-app (walking up to the first existing parent), not an ACL
  read (ACLs lie on virtualized paths).

Process calls go through a new IProcessRunner wrapping the existing static
ProcessRunner, so checks are fakeable in tests instead of spawning real
processes.

DotnetRuntimeCheck was intentionally not added: per
docs/explore-notes/installer-preflight.md, App/Worker publish
self-contained (no preinstalled runtime needed), and the Installer's own
.NET 8 Desktop Runtime requirement is self-proving - a framework-dependent
apphost can't reach managed code at all if that runtime is missing, so a
check running from inside the process can never observe a failure.

Brings in two prerequisite commits this task builds on that hadn't reached
this branch yet: the IEnvironmentCheck/EnvironmentCheckService scaffolding
and the installer-preflight.md research note.
2026-08-05 19:25:02 +02:00
mika kuns 8b26e23d73 feat(installer): add check abstraction and EnvironmentCheckService
Scaffolding for environment checks: IEnvironmentCheck, CheckResult/
CheckSeverity/CheckStatus, and EnvironmentCheckService that runs checks
in parallel while preserving input order, never throws (a failing
check becomes Unknown), and reports HasBlockingError only for
Error+Failed.
2026-08-05 19:11:28 +02:00
Mika Kuns 63d8b5c28d fix(installer): unbreak the update path and cache the download
Changelog / changelog (push) Successful in 2s
Release / release (push) Successful in 40s
Every update failed at "Could not replace the existing files": the app
relaunches the installer via ShellExecute without a working directory, so
it inherited the app's CWD - which the Start Menu shortcut sets to
<InstallDir>\app. A process's current directory is locked by Windows, so
the installer blocked its own `app` -> `app.bak` rename. Retries and
reboots could not help.

- installer moves its CWD to %TEMP% at startup, and both relaunch sites
  in the UI pass an explicit WorkingDirectory
- cache the release zip in %TEMP%\ClaudeDo-download-cache and reuse it on
  a retry while its SHA-256 still matches, so a failed attempt no longer
  costs another full download; drop it after a successful install, delete
  a mismatching one, prune zips of other versions
- roll back a half-done stash: a leftover app.bak was deleted as a stale
  stash on the next attempt, and that copy was the only one left
- name the blocked path in the error message
2026-08-04 17:09:10 +02:00
mika kunsandClaude Sonnet 4.6 133f2d2f1d feat(installer): register autostart via Startup shortcut, drop scheduled task
Replaces schtasks /Create with AutostartShortcut.Install; migrates away
legacy scheduled task and Windows service on upgrade. Removes ScheduledTaskXml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 12:09:07 +02:00
mika kunsandClaude Sonnet 4.6 e2bb43ad6d feat(installer): add AutostartShortcut helper for Startup-folder lnk
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 12:07:32 +02:00
mika kunsandClaude Sonnet 4.6 867dc37228 refactor(installer): extract ShortcutFactory COM helper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 12:05:54 +02:00
mika kunsandClaude Opus 4.7 26c4e5771b feat(worker): run worker as per-user logon task instead of Windows service
A LocalSystem Windows service can't see the logged-in user's Claude CLI
authentication, so the worker now runs as the current user via a hidden
per-user logon Scheduled Task with restart-on-failure.

- Worker is WinExe (no console window) with a Serilog rolling file sink and
  a single-instance mutex so the logon task, app ensure-running, and Restart
  button can't fight over the SignalR port.
- Installer replaces the service steps (register/start/stop) with autostart
  task steps, migrates the legacy ClaudeDoWorker service away on update, and
  removes the task on uninstall. ServicePage drops the service-account UI.
- UI gains a WorkerLocator; the app ensures the worker is running at startup
  and the Restart button kills+relaunches this install's worker process.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 09:39:41 +02:00
mika kunsandClaude Sonnet 4.6 5346737e2b test(releases): port ReleaseClient + ChecksumVerifier tests to new project
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 14:18:17 +02:00
Mika KunsandClaude Opus 4.6 9b928c6217 fix(installer): set EnableWindowsTargeting so Linux Gitea runners can publish
Release / release (push) Successful in 40s
The release workflow runs on a Linux container; building net8.0-windows +
UseWPF=true requires this opt-in property since .NET 8. No-op on Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:39:23 +02:00
Mika KunsandClaude Sonnet 4.6 548251841f feat(installer): add WriteInstallManifestStep
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 09:48:29 +02:00
Mika Kuns ea32a74baa fix(installer): harden DownloadAndExtractStep per review 2026-04-15 09:43:27 +02:00
Mika KunsandClaude Sonnet 4.6 c1e330164e feat(installer): add DownloadAndExtractStep with SHA256 verify
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 09:37:04 +02:00
Mika Kuns b4dc9509cb test(installer): pin 'unparseable version = Config' behavior + document IsNewer limits 2026-04-15 09:26:18 +02:00
Mika KunsandClaude Sonnet 4.6 97fb215ce6 feat(installer): replace sync ModeDetector with async InstallModeDetector
Placeholder edit to App.xaml.cs to keep the project building until Task 11
wires the new async detector.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 09:19:16 +02:00
Mika Kuns 5603fd458d feat(installer): add IReleaseClient + Gitea ReleaseClient 2026-04-15 09:10:02 +02:00
Mika Kuns d0c0e2ce1f feat(installer): add ChecksumVerifier (SHA256 + checksums.txt parser) 2026-04-15 09:03:08 +02:00
Mika KunsandClaude Sonnet 4.6 2fc6924dcb test(installer): add InstallManifest wrong-shape json test
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 08:59:51 +02:00
Mika Kuns 921e626208 feat(installer): add InstallManifest + json-backed store 2026-04-15 08:53:52 +02:00
Mika Kuns c23ed94817 test(installer): address review — drop UseWPF, thread-safe FakeHttpMessageHandler 2026-04-15 08:51:12 +02:00
Mika Kuns 2d34afb2e5 test(installer): scaffold ClaudeDo.Installer.Tests project 2026-04-15 08:46:17 +02:00