Pin current behavior at the three seams that will move during refactoring:
Store (store_test.go):
- TestJobsRoundTrip: all durable Job fields survive a writeYAML→loadOrCreateJobs
cycle; runtime fields (LastRun, LastState, Logs) do not.
- TestConfigRoundTrip: all Config fields survive a writeYAML→loadOrCreateConfig
cycle, including non-default booleans and custom dirs.
- TestNormalizeJobsFillsDefaults: blank jobs get default name/schedule/exitcodes
and the correct LastState/NextRun for enabled vs disabled.
Scheduler (scheduler_test.go):
- TestNextRunTimeRejectsInvalidSchedules: empty, whitespace, bare @every,
invalid/negative/zero durations, invalid cron, out-of-range minute all return false.
- TestPrepareNextRunSetsDisplayString: valid schedule writes NextRun as
"YYYY-MM-DD HH:MM:SS" and sets nextDue to the matching time.Time.
- TestPrepareNextRunSetsInvalidScheduleLabel: bad schedule writes "Invalid
schedule" and zeroes nextDue.
Runner (runner_test.go):
- TestRunJobLogFileAllHeaders: all log header fields are present (job_id,
job_name, trigger, state, detail, command, arguments, success_exit_codes,
start_only, stdout, stderr) and time parses as 2006-01-02 15:04:05.
- TestRunJobRecordFields: RunRecord matches the job and trigger; Time parses;
Output contains stdout/stderr sections.
- TestFormatOutput / TestFormatOutputEmptyStreams: stdout/stderr sections are
separated by a blank line; empty streams show "<empty>".
- TestLogArguments: empty/whitespace → "<empty>"; CRLF → LF normalised.
- TestSanitizeFileName: special chars → "_"; empty or all-special → "job".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add scripts/test.sh and scripts/test.bat to run go vet and go test -race.
Update docs/TESTS.md with test script usage and reorganized manual test commands.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Track the 30 tasks across 5 phases with checkboxes. Each checkbox can be
marked complete as tasks land and pass review.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Document a phased plan to restructure GoSentry into focused packages
under src/ (domain, storage, runner, scheduler, platform, app, ui) with
an application-service layer that owns state, and link it from the README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
readShortcut read the shortcut TargetPath via [Console]::Out.Write, which
uses the system OEM code page by default. On Russian Windows (CP866) this
encoded Cyrillic characters differently from UTF-8, so Go's string(output)
produced a garbled path that never matched os.Executable, causing
AutostartStatus to always report "shortcut points to another executable"
for any install directory that contained non-ASCII characters.
Fix: prepend [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding($false)
to the readShortcut PowerShell script so the output is always UTF-8.
Also harden sameWindowsPath against NTFS 8.3 short names: when a directory
name contains spaces Windows assigns a short name (e.g. LOCALG~1 for
"Local Git"), and the OS may use that form when launching from a
Startup-folder shortcut. Add an os.SameFile fallback that compares paths
by volume serial number and file index, which is immune to 8.3 vs long
name differences as well as directory junction points.
Add normalizeWindowsPath helper that strips quotes and the \?\ extended-
length prefix before filepath.Clean so those variants compare equal to
the plain path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Created docs/TESTS.md documenting all 25 tests across 5 test files:
- store_test.go: YAML serialization tests
- scheduler_test.go: Schedule parsing and invocation output tests
- runner_test.go: Command execution, exit codes, and Windows process tests
- autostart_windows_test.go: Windows startup folder shortcut creation tests
- autostart_linux_test.go: Linux XDG Desktop Entry autostart tests
Includes test descriptions, platform requirements, and usage instructions.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Update the OpenGL workaround to suggest the mingw release of Mesa instead of
msvc, as it matches the MSYS2 GCC toolchain used to build GoSentry. Both
variants work at runtime, but mingw is the more consistent choice.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add explanatory comments around startup timing, single-instance focus handoff, config migration, and Windows/Linux autostart choices.
The new comments capture why these implementations were chosen, what alternatives were intentionally avoided, and which user-facing problems those tradeoffs solve.
Bump the version to 0.3.1 and record startup timing after the main window is actually shown.
Keep autostart launches distinct in History by recording a separate tray-start message when the UI intentionally starts hidden.
Rename the application, Go module path, command package, build artifacts, resource script, and embedded icon assets from PySentry/pysentry to GoSentry/gosentry.
Move portable settings to gosentry.yaml while reading legacy pysentry.yaml during the transition, then rewrite settings under the new name.
Update Windows and Linux autostart integration to use GoSentry names while cleaning up legacy PySentry registry, desktop-entry, and systemd artifacts.
Refresh README, architecture notes, roadmap, changelog, and release examples for version 0.3.0.
Bump the application version to 0.2.5 and update documented artifact names.
Document the Windows VirtualBox/RDP OpenGL startup failure and the Mesa software OpenGL workaround.
Record the tray-icon double-click limitation in the roadmap for future Fyne or platform-specific tray work.
Add a shared --start-in-tray argument that lets autostart start the scheduler and tray integration without opening the main window.
Write the argument into Windows Startup shortcuts and Linux XDG Autostart desktop entries, and verify existing autostart entries include it.
Keep manual launches unchanged and let a manual second launch reveal an already-running instance while duplicate autostart launches stay hidden.
Replace the HKCU Run autostart entry with a per-user Startup folder shortcut. A .lnk stores TargetPath separately, which avoids fragile quoting when the executable path contains spaces.
Remove legacy PySentry and GoSentry Run entries when saving autostart settings, and report shortcut status from the actual shortcut target.
Add Windows tests that create and read a temporary shortcut with spaces in the path so the PowerShell/COM invocation remains covered.
Wrap dynamic job detail labels so long names, schedules, commands, and status values no longer change the right panel minimum width when the selected job changes.
Point embedded and Windows resource icons at the current asset filenames so tests and Windows builds continue to work after the asset cleanup.
Switch direct YAML usage from gopkg.in/yaml.v3 to go.yaml.in/yaml/v4, the maintained YAML org fork of the archived go-yaml repository.
Update README dependency and mirroring links so the documented source repository matches the module used by the application.
Prevent repeated application launches by using a local single-instance control channel. A second process forwards a show command to the already running instance and exits.
Bump the application version to 0.2.4 and update README artifact examples plus docs/CHANGELOG.md.
Add a Settings-specific row layout with a narrower label column so Storage and About no longer waste half the width on captions.
Format the Application section with the same row layout and reserve a third column for the autostart status. The checkbox column is sized to fit the longest Application checkbox so the section reads like a table.
Remove the duplicated application version row from the Settings Application block now that version details live in About.
Keep the autostart control inline and shorten its checkbox text to Start on login.
Tag Docker builder images with the current application version in both Linux Docker build scripts so different release environments do not overwrite each other with one floating builder tag.
Replace the Settings Scheduler note with an About block that shows the GoSentry version, Go runtime version, Fyne module version, and the project repository link.
Improve the History tab by keeping records in chronological order, rendering them as a compact table, and allowing the Time column to toggle ascending or descending order.
Use the native Fyne table header so users can resize columns, including Detail and Log, and show only the log file name instead of the full log path.
Bump the application version to 0.2.3 and update README artifact examples plus docs/CHANGELOG.md.
Append new History events at the end instead of prepending them so the tab reads from oldest to newest.
Replace the loose widget.List rendering with a table that exposes Time, Trigger, Job, State, Detail, and Log columns. This removes the large visual gaps between rows and makes the activity log easier to scan.
Use full timestamps for UI-generated events so startup, UI actions, manual runs, and scheduled runs share the same time format.
Add Linux desktop integration that installs a user-level .desktop file and icon under XDG data directories so taskbars can match the PySentry window to the application icon.
Pass the installed icon path into Linux autostart desktop entries when available, while keeping the Windows and fallback autostart APIs compatible.
Bump the application version to 0.2.2, update README artifact examples, and record the release notes in docs/CHANGELOG.md. Also adjust the Mermaid architecture diagram so Gitea can render it without invalid SVG line-break tags.
Add ARCHITECTURE.md with a Mermaid component interaction diagram and short descriptions of the main runtime flows.
Move CHANGELOG.md and ROADMAP.md under docs/ so project documentation lives in one place, and update README links plus the project layout description.
Measure GUI startup from the beginning of Run until the main view has loaded its store and is ready to build the History model.
Insert the measurement as the first in-memory History event using the existing RunRecord display path: Application / Started / Startup completed in <duration>. This keeps startup diagnostics visible in the UI without creating a separate application log file.
No scheduler, storage, or command log behavior is changed.
Replace the resizable HSplit on the Jobs tab with a border layout that keeps the job list pane at a stable minimum width.
The left pane now uses a small custom layout that asks Fyne for the content minimum size and applies at least 480 logical pixels. This prevents the divider from moving when the selected job changes while still allowing the toolbar buttons, including Delete, to fit when their calculated minimum width is larger.
Only the Jobs tab layout is changed; settings, storage, scheduler behavior, and documentation are intentionally left untouched.