# Changelog All notable GoSentry changes are recorded in this file. ## 0.15.0 - 2026-07-26 **Settings points at the jobs file itself, not the folder holding it.** **Settings:** - The **Jobs directory** row is now a **Jobs file** row. Browse opens a file picker filtered to `.json` instead of a folder picker, so the job list can live under any file name — `team-jobs.json`, one file per machine, a file shared over a network drive — rather than a fixed `jobs.json` per folder. The field stays editable, which is how a file that does not exist yet is named. - **Selecting an existing jobs file now loads it.** Previously the current job list was written over whatever was at the new path, which made it impossible to switch to an existing jobs file — its contents were destroyed on Save. Now an existing file wins: its jobs are loaded, normalized, and replace the loaded list, with runtimes, parsed schedules, next-run times, and log-seeded statistics rebuilt around them. A path with no file behind it still receives the current jobs (and its folder is created), which is how the jobs file is renamed or relocated. History records `Jobs loaded — N jobs from `, since the switch happens without a prompt. - Switching to a different jobs file is refused while a job is running: adoption discards every runtime, and a run finishing afterwards would write its result onto whichever job inherited its ID. Settings unrelated to the jobs file still save normally during a run. - Saving a path with no file name (a trailing separator, `.`, `..`) is rejected with "jobs file must include a file name" instead of failing later with an opaque OS error. **Configuration:** - `Config.JobsDir` / `jobs_dir` is replaced by `Config.JobsFile` / `jobs_file`, which holds the full path including the file name; the default is `"jobs.json"`, resolved against the program folder as before. `Paths.JobsDir` is now derived from the configured file so job saves still create the folder. - A `gosentry.json` written by an earlier version is migrated on load: its `jobs_dir` is joined with `jobs.json`, which is the exact file that version used, and the retired key is dropped when the config is rewritten. - New `app.JobsLoaded{Path, Count}` event, emitted when a selected jobs file replaces the job list; the UI turns it into the History entry. New `storage.LoadJobsFile`, which reads and normalizes a jobs file and reports a missing one as "not found" instead of seeding it the way startup does. ## 0.14.0 - 2026-07-26 **Compact job list view, "no timeout" at both timeout levels, and an Open button for the logs folder.** **Compact job list view.** - The Jobs sidebar can now render each job as a single line — name on the left, status on the right — instead of the three-line block. A toggle button beside the Folder filter switches between **Compact** and **Detailed**; it is labelled with the action it performs, like the "Disable auto" button. Compact fits many more jobs on screen without scrolling; selection, the details panel, the folder filter, and live status updates all work unchanged in both modes. - The choice is persisted as a new `Config.JobListView` field (`"detailed"` / `"compact"`, written to `gosentry.json` as `job_list_view`), so it survives a restart. Empty/legacy configs and any unrecognised value normalize to detailed, so existing installs keep the current look. **Jobs sidebar:** - The **Folder** caption moved onto the filter row itself, beside the select and the view toggle, instead of occupying its own line above it — the job list now starts a full label higher. **Settings:** - The **Logs directory** row gained an **Open** button that shows the folder in the desktop file manager (Explorer on Windows, the XDG handler on Linux), so reading a log file no longer means copying the path by hand. It opens the path currently in the field — including an edit that has not been saved yet — resolving a relative directory against the application folder exactly as the store does. A folder that is missing (the logs directory is created on the first run) or cannot be opened is reported in a dialog. - The Save/Cancel/Defaults row sat flush against the separator above it and the tab's left edge; it now uses the same padding as the other vertical gaps in the tab. **Job dialog:** - The **Arguments** placeholder now states the field's rule — one argument per line, no quoting — instead of showing a lone example path that left the line-per-argument convention to guesswork. **Timeouts: 0 now means "no timeout" at both levels.** - The global **Default timeout** in Settings now defaults to `0`, meaning jobs run to completion with no deadline instead of being killed after 30s. - A per-job timeout of `0` now also means "no timeout" and no longer inherits the global default. Leaving the job's timeout **empty** is what inherits. `Job.TimeoutSeconds` became `*int` so the three states — unset, explicit 0, and a positive limit — stay distinguishable in `jobs.json`. - Fixed: a global default of `0` did not survive a restart. `gosentry.json` was loaded with `0` treated as a missing value and silently reset to 30s, so the setting only held for the current session. `default_timeout_seconds` is now written unconditionally and read back as-is. Existing jobs and configs are unaffected: a job with no `timeout_seconds` still inherits, and a saved global default of 30 stays 30. **Internal:** - Job names in the list are truncated through the widget's `Truncation` field; `fyne.TextTruncate` is deprecated in Fyne 2.7.4. Behavior is unchanged. - Docker release builds mount `.gocache/` from the host, so `--rm` container removal no longer wipes `GOCACHE` between runs. - Added `docs/REVIEW.md` (the project-review agenda) and a "Config file compatibility" section in `docs/STANDARDS.md` recording the rule the `Theme`, `JobListView`, and `TimeoutSeconds` fields already follow. Added `CLAUDE.md`. ## 0.13.0 - 2026-07-26 **Branded GoSentry color theme; Cancel/Defaults buttons in Settings.** **Theme:** - Added a custom Fyne theme derived from the logo and app icon (deep teal primary, amber accent, branded job-status colors) with light and dark variants; users can switch between it and Fyne's default theme from Settings. The choice is persisted as a new `Config.Theme` field (`"default"` / `"gosentry"`), applied at startup before the first frame and live-previewed when picked in Settings. Empty/legacy configs normalize to the default theme so existing installs keep the original look. - The light variant is boldly branded: a soft teal window canvas with white inputs, menus, dialogs, and buttons on top, plus teal-tinted separators, input borders, and table headers, so cards and fields lift off the background instead of reading as a plain accent swap on gray. The dark variant uses deep-teal surfaces to echo the app icon. Text stays dark/light per the base foreground for contrast in both variants. **Settings tab:** - Added Cancel and Defaults buttons. Cancel discards unsaved edits by reloading the saved config; Defaults loads built-in default values into the form for review before saving. `domain.DefaultConfig()` is now the single source of truth for default values, shared by storage and the Settings UI. ## 0.12.0 - 2026-07-25 **Per-job command timeout:** - Each job may now set its own run timeout (seconds) in the job dialog; leaving it empty inherits a new **Default timeout** in Settings (default 30s), the same inherit pattern as the overlap policy. The details panel shows the effective value, marking inherited jobs as `(global default)`. - The formerly hard-coded 30s guard in `runner.RunJob` is now the configurable default. `StartOnly` fire-and-forget jobs remain unaffected by the run timeout, continuing to measure launch latency only. ## 0.11.5 - 2026-07-01 **Quality and documentation polish:** - Replaced the interim `docs/FUTURE_WORK.md` with `docs/STANDARDS.md` — a slim, permanent reference for code-quality rules and intentional behavior. - `newMainView` now accepts an injected `*app.Service` for testability; `RunNow` errors are shown in a dialog instead of failing silently. - Empty job lists no longer panic when building the Jobs tab. - Added regression and helper tests for overlap/pause scheduling, UI history helpers, main-view smoke build, and Linux desktop integration. ## 0.11.4 - 2026-06-30 **Statistics:** - `StartOnly` jobs now record launch latency (time to spawn the process) as the run duration instead of a hard-coded `0`, so the Statistics line shows a real last/avg/max for fire-and-forget jobs. Sub-millisecond launches still round to 0 and are excluded from the average, as before. ## 0.11.3 - 2026-06-29 **Reliability fixes from an internal code review: safer runs, a real overlap queue, and more accurate statistics.** **Scheduler / runs:** - Fixed a data race where background runs could read log paths while settings were being saved. - A run no longer starts if persisting the "Running" state fails; the job rolls back to its previous status instead. - Under the `"queue"` overlap policy, every missed occurrence while a run is still in flight is now remembered and executed afterward (not just the last one). - Manual and scheduled runs now advance next-due timing from the scheduler clock consistently. **Application service:** - Create, update, delete, enable/disable, and global pause no longer announce UI changes when the underlying JSON save fails. - Invalid per-job `overlap_policy` values are rejected at save time. - Log file write failures are reported in History instead of failing silently. **Statistics:** - Startup stat seeding matches log files by `job_id`, avoiding collisions when different job names sanitize to the same filename. - Average run duration excludes zero-duration runs (such as StartOnly launches), matching how stats are rebuilt from log files. **Documentation:** - Added `docs/CODE_REVIEW.md` with the full review summary. - Corrected stale YAML references and clarified that global pause stops only scheduled runs while manual "Run now" remains available. ## 0.11.2 - 2026-06-25 **Window state persistence, History sort fix, clearer scheduler toggle, and an appID update.** **Application:** - The window size (width and height) is now persisted in preferences and restored on next launch. When the user closes the window (via Quit menu or window close button), the current dimensions are saved and will be applied when the application starts again. Defaults to 1024×660 if no saved size exists. - Updated appID from `ru.mixdep.gosentry.desktop` to `ru.mixeme.gosentry.desktop` for consistency with the new domain name. **History tab:** - Fixed the Time column sort toggle, which stopped working after Fyne 2.7.4 began rejecting header-cell selections. The plain header label is replaced with a custom tappable header widget that handles the click directly. - The sort direction is now shown with ▲/▼ glyphs instead of the "asc"/"desc" text. **Jobs list:** - Renamed the global scheduler toggle from "Pause all"/"Resume all" to "Disable auto"/"Enable auto", and swapped the stop icon for a pause icon, to make clear that it only stops automatic scheduled runs. ## 0.11.1 - 2026-06-25 **Settings tab refinements: even spacing, full labels, and a smarter Save button.** **Settings tab:** - The Queue selects (Execution mode, Default overlap policy) now use the same default spacing as the Storage fields, so they no longer sit squeezed together. - Widened the caption column so the longest label, "Default overlap policy", is shown in full instead of being truncated. - The Save button now starts disabled and only enables once a field differs from the saved config, re-disabling after a successful save (or if a changed field is reverted to its original value). ## 0.11.0 - 2026-06-25 **Manual runs while paused, two-column Settings/details, and a more compact job list.** **Scheduler:** - "Run now" is now allowed while the scheduler is globally paused. The global pause stops only automatic scheduled runs; an explicit manual run is the user's own one-off action and is no longer blocked (the already-running and sequential-mode guards still apply). **Jobs details panel:** - Metadata captions (Folder, Command, Run mode, …) are pinned to a fixed width instead of an even split, so widening the window now grows the value column rather than the short caption. - Fixed a bug where the "Selected job activity" panel kept showing the previous job's entries when a different job was selected; the list now refreshes on every selection change. **Jobs list:** - List rows (name, schedule/command, status) are condensed with a tight, negative-gap layout so more jobs are visible without scrolling. **Settings tab:** - The form is reorganized into two columns — Application and Queue on the left, Storage and About on the right — with the Save button spanning the full width below. The Autostart status moved onto its own line so the section fits a half-width column. - Removed the blank row that sat between the Save button and the following separator. ## 0.10.2 - 2026-06-25 **Condensed details/settings panels and a window that shrinks to 720p.** **Jobs details panel:** - Job metadata is laid out in two columns (Folder/Schedule, Command/Arguments, Run mode/Overlap policy, Last run/Next run, State/Statistics), roughly halving the block height. - Metadata rows are stacked with a tight, negative-gap layout so the interval between rows is no longer oversized. - The command-output area's minimum height was reduced so the details pane can get shorter; long output still scrolls. - The "Selected job activity" panel is now sized to exactly fit `maxJobActivityRows`, derived from `widget.List`'s own row metrics, so all three rows are visible without a scrollbar regardless of theme or DPI. **Settings tab:** - The form is wrapped in a vertical scroll so it no longer dictates the window's minimum height (tab containers size to the tallest tab); it scrolls on short screens instead. - Label-only sections (Application, Queue, About) are condensed, while separators and the editable Storage fields keep normal spacing so dividers have breathing room and entry boxes stay visibly separated. **Window sizing:** - Together these changes drop the minimum window height from ~891px to ~570px, so the window can be resized noticeably shorter and fits comfortably on 720p screens. ## 0.10.1 - 2026-06-24 **Refactoring:** - Unified icon asset naming from mixed scheme (big/16x16) to consistent size-based names (large/small) for clarity and maintainability. **Build:** - Windows build script now displays informative messages at each build step (version, output path, environment setup, icon embedding, compilation) to improve build transparency and aid troubleshooting. ## 0.10.0 - 2026-06-24 **Compact activity rows; per-job execution-time statistics seeded from log files.** **Activity panel (one-line rows):** - Each entry in the job log list is now a single truncated line using only the base name of the log file (e.g. `20260624-120000_Build.log`) instead of the full path. Long lines are clipped rather than wrapped, keeping the panel compact with many runs. - History table retains the full log path for reference; base-name truncation applies only to the activity rows in the Jobs details panel. **Execution-time statistics:** - Added `DurationMS` field to `RunRecord`; the runner measures wall-clock start-to-finish and writes it to both the record and a `duration:` header line in the log file. `StartOnly` jobs record `0`. - Added aggregate counters to `JobRuntime`: `RunCount`, `FailCount`, `LastDurationMS`, `AvgDurationMS`, `MaxDurationMS`. Updated after every completed run in `executeRun`. - On startup the statistics are seeded from existing log files: the runner parses `state:` and `duration:` headers for each job's newest log files (bounded by `MaxLogFiles`). Legacy logs without a `duration:` line still count toward `RunCount`/`FailCount` but are excluded from duration aggregates so a missing duration cannot appear as a zero-millisecond run. - A **Statistics** row in the Jobs details panel shows a one-line summary (`N runs, M failed, last X ms, avg Y ms, max X ms`) that refreshes after each run and is pre-populated from log files after a restart. **Per-job overlap policy:** - Added an `OverlapPolicy` field to `domain.Job`; a job can now override the global skip/queue default. `RunDue` resolves the effective policy per job (the job's value if set, otherwise `Config.OverlapPolicy`). - The job dialog gains an overlap-policy selector with a "(Use global default)" option that saves empty so the job inherits the global setting. The details panel reflects the effective policy. **Persisted global pause:** - Added `Paused` to the config so the global "Pause all" state survives a restart. `SetGlobalPause` persists the new value, and the service initializes its paused state from config at startup — a paused install now relaunches paused instead of silently resuming the scheduler. - The Pause-all/Resume-all button and scheduler-state label initialize from the persisted state. **Window sizing (720p-safe):** - Lowered the default window size to `1024×660` with a sensible `MinSize` so the window opens fully visible on a 1366×768 / 720p screen. Layout minimums in the Jobs view were tightened to match. **Packaging:** - Added portable-distribution helpers: `scripts\package-windows.bat` builds and bundles `gosentry.exe`, `README.md`, and `CHANGELOG.md` into a versioned `.zip`; `scripts/package-linux.sh` does the same for `linux-amd64` and `linux-arm64` into `.tar.gz` archives. **Internal cleanup:** - Split `ui/jobs_view.go` into focused files (`jobs_view_details.go`, `jobs_view_helpers.go`) to bring it back under the file-size guideline. - Removed the one-time YAML→JSON import path (shadow structs, `importYAML*`, legacy path names) now that the 0.9.0 transition window has passed; `go.yaml.in/yaml/v4` is dropped from `go.mod`. - Post-field-test sweep of stale diagnostics, obsolete autostart-migration code, and noisy README/ignore rules. The startup-timing History event is retained. - Removed the completed release-milestone docs and trimmed `ROADMAP.md` to open items only. ## 0.9.0 - 2026-06-24 **Storage migrated to JSON; queue execution modes; failure notifications; tray left-click; Fyne 2.7.4.** **Storage and data model:** - Settings and jobs now stored as `gosentry.json` and `jobs.json` (2-space indented JSON). On first run after upgrading, existing `gosentry.yaml` / `jobs.yaml` files are imported automatically and rewritten as JSON; the YAML files are not deleted. - Removed `SuccessExitCodes` field. Exit-code handling is now fixed: exit code 0 = success, any nonzero exit code = failure. Jobs relying on nonzero success codes must switch to `StartOnly` mode if the exit code is irrelevant. **Execution modes and overlap policies:** - Added `ExecutionMode` (parallel/sequential) and `OverlapPolicy` (skip/queue) settings in Settings under a new Queue group. - **Parallel mode** (default): all due jobs start simultaneously. - **Sequential mode**: due jobs run one at a time, in order. - **Skip policy** (default): if a job comes due while its previous run is still active, the new run is discarded. - **Queue policy**: if a job comes due while running, the run is held and automatically started when the current run completes. - Both settings are persisted to `gosentry.json` and validated on load; defaults ensure backward compatibility. **Notifications and command input:** - Failed job runs now raise a desktop notification (when enabled in Settings) with the job name and failure detail. Notifications fire for scheduled and manual runs; internal activity events are not notified. - Added a Browse button next to the Command field in the job dialog for file picker selection. **UI and platform integration:** - Removed all PySentry legacy code: registry autostart entries (Windows), systemd and desktop file cleanup (Linux). - Updated `.gitignore` and `.dockerignore` to track `gosentry.json` / `jobs.json` instead of legacy YAML filenames; added `*.yaml` wildcard to ignore legacy files during import. - Moved developer documentation (Requirements, Build, Run From Source, Project Layout, Dependencies) out of README into `docs/DEVELOPMENT.md`. README now focuses on end-user content. **Icons and tray:** - Regenerated all icon assets with feathered color-to-alpha so the rounded-tile boundary is transparent — the opaque white halo visible on dark taskbars and trays is gone. - Rebuilt `gosentry.ico` as a multi-size file (16 hand-tuned + 32/48/256 from the large PNG) and added a dedicated 16×16 icon for the Windows tray. - Per-platform icon wiring: Windows window/taskbar uses the ICO resource so GLFW selects the right frame per slot; Windows tray uses the 16×16 ICO; Linux titlebar uses `IconSmall()` for a crisp ~16 px `_NET_WM_ICON`. - Left-clicking the tray icon now shows and focuses the main window without opening the menu; the explicit "Show" menu item is preserved for right-click access. **Performance:** - Upgraded Fyne 2.6.3 → 2.7.4 (systray 1.11.0 → 1.12.1): startup time drops from ~644 ms to ~414 ms (−36%). - Moved Windows-only runner tests into `runner_windows_test.go` (guarded by `//go:build windows`) to fix Linux test build. ## 0.8.0 - 2026-06-23 **Desktop notifications for failed jobs; Browse button for command paths.** - Failed job runs now raise a desktop notification (title "GoSentry: Job Failed", body shows the job name and failure detail) when the "Show desktop notifications for failed jobs" setting is enabled. Notifications fire for scheduled and manual runs only; internal activity events are not notified. - Added a Browse button next to the Command field in the job dialog so users can pick an executable from a file picker instead of typing the full path. ## 0.7.0 - 2026-06-23 **Execution modes and overlap policies for parallel and sequential job dispatch.** - Added `ExecutionMode` setting (parallel/sequential) and `OverlapPolicy` setting (skip/queue) in Settings under a new Queue group. - **Parallel mode** (default): all due jobs start simultaneously. - **Sequential mode**: due jobs run one at a time, in order; a new job waits for the previous one to finish. - **Skip policy** (default): if a job comes due again while its previous run is still active, the new run is discarded. - **Queue policy**: if a job comes due again while running, the run is held and automatically started when the current run completes. - Both settings are persisted to `gosentry.json` and validated on load; defaults ensure backward compatibility with existing installations. - Added comprehensive unit tests verifying parallel start, sequential serialization, skip drops, and queue re-runs. - Manual runs (`RunNow`) respect sequential mode: refused while any other job is running. - No observable behavior changes with default (parallel/skip) settings; installations upgrading from earlier versions continue unchanged. ## 0.6.0 - 2026-06-22 **PySentry legacy code removed.** - Removed all PySentry registry autostart entries (Windows), systemd and desktop file cleanup (Linux), and associated legacy code paths. - Updated `.gitignore` and `.dockerignore` to ignore `gosentry.json` / `jobs.json` instead of the old YAML filenames; added `*.yaml` wildcard to ignore legacy files during the import window. - No observable behavior changes; codebase cleanup after migration from PySentry naming. ## 0.5.0 - 2026-06-22 **Storage migrated from YAML to JSON; exit-code flexibility removed.** - Settings and jobs are now stored as `gosentry.json` and `jobs.json` (2-space indented JSON). On first run after upgrading, existing `gosentry.yaml` / `jobs.yaml` files are imported automatically and the JSON files are written; the YAML files are not deleted and can be removed manually. - Removed `SuccessExitCodes` field from jobs. Exit-code handling is now fixed: exit code 0 is success, any nonzero exit code is failure. Jobs that relied on nonzero success codes will now show "Failed"; update those jobs to use `StartOnly` mode if the exit code is irrelevant. - Deleted `runner/exitcodes.go`; simplified `runStateDetail` accordingly. - Tests updated: JSON round-trip tests, YAML-import tests for both config and jobs, exit-code flexibility tests removed. ## 0.4.0 - 2026-06-22 **Architectural milestone: completed refactoring and reached target architecture.** - Completed Phase 5 refactoring: hardening, testing, and documentation. - Surface all save/cleanup errors from service and storage; no more silently swallowed `_ = ...` on persistence. - Introduced `platform/autostart.Manager` interface with per-platform implementations (Windows, Linux, other); inject into service instead of calling package functions. - Filled test gaps: folder filtering, log cleanup (count and age), settings persistence and migration, concurrent run prevention. - Verified `go test -race ./...` passes on Windows; no data races in the refactored codebase. - Updated `docs/ARCHITECTURE.md`, `docs/TESTS.md`, and README with final package structure and build/test instructions. - **Refactoring target reached:** Service layer owns all state and is the sole writer; UI is a thin view marshaling updates via `fyne.Do`; core engines are stateless and injectable; domain layer is pure with no test noise. - Known follow-ups recorded in `ROADMAP.md`: - Linux test build is currently broken (Windows-only test symbols need `//go:build windows`); will fix separately. - File-size soft limits exceeded in a few places; revisit when next editing those files. - No observable behavior changes. ## 0.3.6 - 2026-06-22 - Completed Phase 4 refactoring: carved up the GUI into focused, testable components. - Renamed `src/gui` → `src/ui` and split monolithic `app.go` into `run.go` (lifecycle) and `mainwindow.go` (view construction). - Extracted view components into separate files: `jobs_view.go`, `job_dialog.go`, `history_view.go`, `settings_view.go`. - Extracted platform wiring into separate files: `tray.go`, `singleinstance.go`, `layout.go`. - Removed forbidden platform imports (autostart, desktop, paths) from `src/ui`; all platform concerns now flow through `app.Service`. - Upgraded Fyne from v2.5.3 to v2.6.3 to enable `fyne.Do` for cross-thread widget marshaling (resolves concurrency issue #4). - Added `docs/PERFORMANCE.md` with measured startup-time analysis: the ~290ms increase from Phase 4 is entirely the Fyne 2.6.3 upgrade's `w.Show()` cost, not the restructuring. - Added `docs/PERFORMANCE.md` and wired post-Fyne-2.7.x re-check into `ROADMAP.md`. - No observable behavior changes; continued internal refactoring toward separated concerns and testability. ## 0.3.5 - 2026-06-19 - Completed Phase 3 refactoring: application service and state management. - Added `app.Service` as the single owner of application state (job registry, settings, run history). - Implemented event-driven observer dispatch: Services can emit events (JobAdded, JobChanged, etc.) to decouple state changes from UI updates. - Added `app.Clock` interface for testable time-dependent behavior in scheduler and run tracking. - Converted scheduler to drive app.Service instead of directly managing domain state. - Created `app.Format` helpers for display rendering (job names, schedule summaries, run times). - Added comprehensive unit tests for app.Service and supporting types. - No observable behavior changes; continued internal refactoring toward separated concerns and testability. ## 0.3.4 - 2026-06-19 - Completed Phase 2 refactoring: domain cleanup and value object extraction. - Split durable job configuration (`domain.Job`) from transient execution state (`domain.JobRuntime`), keyed by job ID. - Added `domain.Schedule` value object with `Parse`, `Validate`, and `Next(time.Time)` methods for cron/interval parsing. - Migrated scheduler to parse schedules once at load/edit instead of per tick, removing duplicated parsing. - Made `RunJob` pure: runner no longer mutates jobs, returning only `RunRecord` for the caller to fold into runtime state. - Simplified `storage.normalizeJobs` to touch only durable configuration; runtime initialization moved to `domain.NewRuntime`. - No observable behavior changes; continued internal refactoring toward separated concerns. ## 0.3.3 - 2026-06-18 - Completed Phase 1 refactoring: split the flat `src/core` package into specialized, focused packages: - `src/domain` for pure types (Job, RunRecord, Config) - `src/storage` for persistence (Load/Save, Paths, YAML helpers) - `src/runner` for job execution (RunJob orchestration, logging, exit codes) - `src/scheduler` for timing loop - `src/platform/winproc` for cross-platform hidden window configuration - `src/platform/autostart` for system autostart integration - `src/platform/desktop` for desktop environment integration - `src/app` for application-level code (Version, future Service layer) - No observable behavior changes; internal structure improvements only. ## 0.3.1 - 2026-06-17 - Changed startup timing in History to measure until the main window is actually shown instead of stopping during UI construction. - Added a separate startup History message for autostart launches that begin hidden in the tray. ## 0.3.0 - 2026-06-17 - Renamed the project from PySentry to GoSentry across the GUI, module path, build scripts, generated artifacts, desktop integration, and documentation. - Renamed the command package to `cmd/gosentry` and Windows resource script to `packaging/windows/gosentry.rc`. - Renamed portable application settings from `pysentry.yaml` to `gosentry.yaml`, while keeping one-time read compatibility for existing `pysentry.yaml` files. - Renamed build artifacts from `pysentry-*` to `gosentry-*`. - Updated autostart and Linux desktop integration to use GoSentry names while cleaning up older PySentry autostart entries. ## 0.2.5 - 2026-06-16 - Stabilized the Jobs details panel so long selected-job fields do not resize the right pane or application window. - Switched Windows autostart from `HKCU Run` entries to a Startup folder shortcut, fixing executable paths that contain spaces. - Added `--start-in-tray` autostart launches for Windows and Linux so sign-in startup does not open the main window. - Added Windows shortcut tests and Linux autostart desktop-entry tests for the new startup-in-tray behavior. - Updated autostart documentation and architecture notes for the Startup shortcut and XDG desktop-entry behavior. - Documented the Windows VirtualBox/RDP OpenGL startup failure and the Mesa software OpenGL workaround. ## 0.2.4 - 2026-06-16 - Prevented repeated application launches by forwarding a second start attempt to the already running instance. - A second instance now asks the first instance to show and focus the existing window, then exits. ## 0.2.3 - 2026-06-15 - Changed History to use chronological ordering with new records appended at the bottom. - Replaced the History list with a compact table. - Added Time column sorting in both ascending and descending directions. - Made History table columns user-resizable through the native Fyne table header. - Shortened the Log column display to file names instead of full paths. - Unified UI event timestamps with command run timestamps. ## 0.2.2 - 2026-06-15 - Added Linux desktop integration that installs a user-level `.desktop` file and icon so taskbars can match the running window to the GoSentry icon. - Added the installed icon path to Linux autostart desktop entries when available. - Added `ARCHITECTURE.md` with a component interaction diagram and moved project documentation under `docs/`. - Adjusted the Mermaid architecture diagram to avoid line-break syntax that breaks rendering in Gitea. - Stabilized the Jobs tab pane layout so switching jobs does not move the divider. - Added startup timing to the History tab. ## 0.2.1 - 2026-06-15 - Fixed Docker release scripts so container builds keep Go in `PATH`. - Disabled Go VCS stamping for Docker release builds to avoid failures when `.git` metadata is unavailable inside the container. - Made Docker release builds write `dist/` artifacts with the current user's UID/GID instead of root ownership. - Added `ROADMAP.md` with planned delivery formats and packaging priorities. - Cleaned `.gitignore` for the current Go/Fyne project and kept the local `_gsdata_/` rule. - Added README links to official Go/Fyne sites and source repositories useful for dependency mirroring. - Documented Windows dependency installation steps for Go and MSYS2 UCRT64 GCC. ## 0.2.0 - 2026-06-15 - Added working autostart support with status diagnostics in Settings. - Switched Linux autostart to XDG Autostart `.desktop` files and clean up the legacy user systemd unit. - Fixed Windows autostart status detection by parsing `HKCU Run` values and comparing executable paths reliably. - Added background job execution so the GUI does not block while commands run. - Suppressed Windows console windows for scheduled and manual command runs. - Added application version display in the window title, Settings, and build artifact names. - Moved release artifact commands from `Dockerfile` into `scripts/build-release-linux.sh` with interactive target selection. - Added release build targets for Linux amd64, Linux arm64, and Windows amd64. - Added README dependency installation notes and official Go/Fyne links. ## 0.1.0 - 2026-06-14 - Added the initial Fyne desktop GUI. - Added YAML settings and single-file YAML job storage. - Added `@every` and standard 5-field cron schedules. - Added manual and scheduled command runs with per-run log files. - Added job folders, history, global pause, and Windows tray support. - Added Windows and Linux build helpers.