24 Commit-ok

Szerző SHA1 Üzenet Dátum
hariel1985
14ced8d11d Bump version to 1.1 (2)
First version change since v1.0.0: adds the RAM and Compressed memory
columns and ships the memory-leak, pause-while-hidden and zero-value
flicker fixes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
v1.1.0
2026-09-16 14:00:49 +02:00
hariel1985
c9cd87f221 Show RAM and compressed memory per process
Adds two columns to the Processes table (and rows to the inspector) next
to Memory, which is the physical footprint:

- RAM: pages currently in physical memory (ri_resident_size, from the
  proc_pid_rusage call that was already being made).
- Compressed: the original size of the process's pages held by the
  compressor, via task_name_for_pid + TASK_VM_INFO. This is also the
  closest per-process swap figure: macOS pages out compressor segments,
  not processes, and those stay counted here. Activity Monitor's
  "Compressed Memory" and top's CMPRS report the same value.

Both need no privileges for the user's own processes; other users' and
system processes report 0, as the Memory column already did. Values match
top/ps within sampling noise; a full refresh of ~650 processes including
the extra call takes ~5 ms.

Memory, RAM and Compressed live in one @TableColumnBuilder property:
Table takes at most 10 columns per block, and inlining them also
exceeded the type checker's time limit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 13:53:47 +02:00
hariel1985
6f60dd7ad8 Pause view updates while no window is visible; fix zero-value flicker
The window left open all day grew the app by ~360 MB in 24 h even after
the .tabItem fix. Isolating each piece in lab builds showed the growth is
the sum of several small framework leaks on macOS 26.6 that fire on every
view update: SwiftUI Table cell updates, AppKit text-cell KVO
dependencies (NSKeyValueDependency) and an ObservationRegistrar created
inside DesignLibrary. With the window closed every counter stayed flat;
minimized or fully covered, SwiftUI kept updating and kept leaking.

- WindowVisibility tracks whether any TopManager window is on screen
  (occlusion state; the status item's host window is ignored).
- SystemMonitor records into an always-current LiveState and only
  mirrors it into the @Published properties while something is visible.
  Resuming publishes everything at once, so views catch up immediately.
  Metrics history, alerts and the menu bar keep running while paused.
- MenuBarStatus carries the pre-formatted menu-bar strings, republished
  only when the visible text changes.
- AlertCenter assigns healthScore/diagnosis only when they change.
- Monitoring now starts in applicationDidFinishLaunching instead of the
  main window's onAppear, so it also runs when the app launches with no
  window (state restoration after the window was closed).

Also fixes a visible bug: ProcessMonitor's lightweight refresh (2 of
every 3 fetches) emitted 0 for memory, CPU and threads instead of the
last known values, so ~90% of rows showed "Zero KB" most of the time.

Verified in an isolated lab instance: minimized or covered, all leak
counters stay flat while the menu-bar title keeps updating; a partially
visible window updates every tick. Growth while the window is actually
visible (~190 KB/min) is unchanged — those leaks are in Apple's
frameworks. 58/58 tests pass, including a regression test that fails on
the old code (472 of 487 own processes reported 0 memory).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 13:53:10 +02:00
hariel1985
6a72c7ba64 Ignore the root build/ directory
The existing */build/* pattern only matches build/ inside a subdirectory,
so the xcodebuild -derivedDataPath output at the repo root kept showing
up as untracked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 10:25:42 +02:00
hariel1985
eb52891a8c Fix 440 MB leak from re-evaluated .tabItem labels
ContentView declared an @EnvironmentObject it never read, so every
SystemMonitor publish (3 s by default) re-evaluated its body. On macOS
the AppKit tab bridge permanently retains the AnyView(Label(...)) behind
each .tabItem, leaking ~6 KB per tick — 519 MB after three days of
uptime, >90% of the process footprint.

Keep the TabView shells free of observable dependencies:

- ContentView: drop the unused @EnvironmentObject, so the body is
  evaluated exactly once.
- SettingsView: split the shell from its two tabs, which now own the
  AppSettings observation (dragging a threshold slider leaked 2 labels
  per step).
- PerformanceView: drop the write-only selection binding (3 labels per
  sub-tab switch).

Two smaller wins while in here:

- GPUMonitor leaked one io_object per GPU poll: leaving a
  `defer { release; IOIteratorNext }` loop via break/return hands back an
  object nobody releases. Replaced with firstMatch(in:), and removed a
  never-released iterator in getAppleSiliconChipName.
- MetricsStore re-encoded the whole 20k-sample history to JSON every
  30 s; saveEvery 10 -> 40 (~2 min). flush() on quit and on background
  is unchanged.

Measured over 10 minutes (~200 refresh cycles): footprint 86-123 MB with
no upward trend, leaked Label views pinned at 4 — the tab items
themselves. Was 519 MB and climbing ~170 MB/day. 55/55 unit tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 10:45:51 +02:00
hariel1985
05139408a7 docs: update screenshots with new-feature UI (Energy/Disk I/O, health, trends)
Refresh processes, performance-cpu, performance-memory and power-storage shots to
show the new columns, System Health score, battery panel and time-range trends.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 21:17:48 +02:00
hariel1985
50480c2a97 docs: add Download section with v1.0.0 release link
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 21:11:12 +02:00
hariel1985
186ae31d01 Fix: show alert banners while TopManager is foreground
macOS suppresses an app's own notifications while it is the frontmost app unless
the UNUserNotificationCenter delegate opts in. Set the delegate in AppDelegate and
return [.banner, .sound, .list] from willPresent so High-CPU/health alerts pop as
banners even with the window focused. (Also confirmed notifications require a real
code signature, not the ad-hoc CODE_SIGNING_ALLOWED=NO test build.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 21:00:57 +02:00
hariel1985
d4db0a7972 Increment 6: final verification + docs
- Full XCTest suite green (55 tests)
- Visual verification of all tabs (screenshots): Processes (Energy/Disk columns +
  live data), Performance (range picker + P/E core charts), Power & Storage
  (Health score 55/Fair + battery 97%/114 cycles + preserved System/GPU)
- Ground-truth cross-checks: memory 12.31GB vs 12.53GB reported (16KB pages),
  battery vs ioreg/pmset, per-process CPU vs ps, disk vs df — all consistent
- README updated to document new capabilities; testing docs referenced

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:35:09 +02:00
hariel1985
2e3574f6e3 Increment 5: Settings, launch-at-login & rich menu-bar HUD
- AppSettings (@MainActor, UserDefaults-persisted): refresh interval, menu-bar
  metric, notifications toggle, CPU/disk/low-battery alert thresholds,
  launch-at-login; pushes changes into live services; nonisolated clampInterval
- LoginItem via SMAppService (macOS 13+), register/unregister with error catch
- SystemMonitor: runtime-configurable refresh cadence (was hardcoded 3s)
- SettingsView (⌘,): General (login, interval, menu-bar metric) + Alerts
  (notifications + thresholds) tabs
- MenuBarLabel: user-selectable menu-bar metric (CPU/Memory/Health/Download)
- Menu-bar dropdown: Top CPU Consumers with one-click quit
- 3 new tests (55 total); smoke: runs clean, Settings… menu registered

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:25:43 +02:00
hariel1985
bc494af363 Increment 4: alerts engine, notifications & System Health score
- HealthModel (pure): 0-100 score + plain-language diagnosis + rating
- SystemAlert/AlertKind/AlertThresholds + pure AlertEvaluator (sustained-breach)
- AlertCenter (@MainActor): per-cycle health + alert evaluation, de-dup by kind,
  inbox (capped), native UserNotifications on transition into a condition
- Covers: sustained high CPU, critical memory pressure, disk full, thermal,
  runaway process, low battery
- Wire evaluate() into SystemMonitor; request notif auth on launch
- HealthCardView (score ring + diagnosis) + AlertsInboxView in Power & Storage;
  health score + alert badge in menu bar
- Renamed model Alert->SystemAlert to avoid SwiftUI.Alert shadowing
- 10 new tests incl. AlertCenter de-dup integration (52 total green)
- Visual smoke: Energy + Disk I/O columns render with live data under load

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:20:24 +02:00
hariel1985
9b92fb715a Increment 3: battery health + power monitoring (IOKit)
- PowerInfo model + BatteryMath (health %, condition, watts, time fmt) — unit-tested
- PowerMonitor reads AppleSmartBattery via IORegistry (no root/entitlements):
  charge, cycles, design/raw-max capacity, temperature, voltage, amperage,
  time-to-empty/full, adapter watts; graceful no-battery (desktop) path
- Wire powerInfo into SystemMonitor (every 3rd cycle)
- Battery & Power section in Power & Storage tab; battery in menu-bar dropdown
- 10 new tests (42 total); cross-checked vs pmset/ioreg: health 96.9%, 114 cycles,
  30.8C, matches ground truth exactly

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:12:20 +02:00
hariel1985
1390eda468 Increment 2: deep per-process data + process inspector
- ProcessItem: disk read/write rate + cumulative bytes, energy-impact score,
  executable path; equality now tracks energy/disk so the table refreshes
- ProcessMonitor: disk I/O + idle-wakeup rates from rusage_info_v4; full path
  capture; on-demand KERN_PROCARGS2 args + PROC_PIDLISTFDS open-file count
- EnergyModel heuristic + pure ProcArgs parser (both unit-tested)
- ProcessView: sortable Energy + Disk I/O columns (icon folded into Name to stay
  within SwiftUI's 10-column limit); Get Info (double-click / ⌘I) opens inspector
- ProcessInspectorSheet: live stats, path, args, open files, Reveal/Copy Path
- 10 new tests (32 total green); smoke: stable under CPU+disk load

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:08:15 +02:00
hariel1985
222638fc98 Increment 1: persistent metric history + extended time-range charts
- MetricsStore: thread-safe on-disk ring buffer (Application Support), throttled
  background saves, flush on quit/background, 24h/20k cap
- MetricsMath: pure trim + downsample (unit-tested)
- HistoryRange (Live/5m/30m/1h/24h) + HistoryRangePicker + MetricTrendChart
- Wire recording into SystemMonitor; range picker in CPU/Memory/Network tabs
- Fix durability: flush history on applicationWillTerminate + scenePhase.background
- 8 new tests (30 total green); runtime smoke: no crash, 7 samples persisted

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 19:59:05 +02:00
hariel1985
d59bf2b7b0 Increment 0: add XCTest target, testing process & 10x value plan
- Add TopManagerTests unit-test target (hosted, @testable import)
- 14 baseline tests for formatters and model math (all green)
- scripts/test.sh build+test loop driver
- docs/TESTING.md (5-gate process), docs/VALUE_PLAN.md (10x rubric)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 19:51:47 +02:00
hariel1985
5ec09d9279 Aláírás: céges Apple Team ID (P3663392R2) + entitlements javítás
- DEVELOPMENT_TEAM beállítva a céges fiókra (InstaSoft, P3663392R2).
- A project.yml-ből kivéve a target `entitlements:` blokk, amely
  `properties` nélkül üres entitlements fájlt generált és felülírta a
  kézzel karbantartott TopManager.entitlements-et (app-sandbox=false).
  A CODE_SIGN_ENTITLEMENTS beállítás marad. Release build ellenőrizve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 19:26:29 +02:00
hariel1985
9292166223 Add safety guardrails for Force Kill and protected system processes
Security improvements:
- Force Kill (SIGKILL) now always requires confirmation - removed "Don't ask
  again" option for this destructive operation
- Added protection for critical system processes (kernel_task, launchd,
  WindowServer, loginwindow) - UI prevents force-killing these
- Terminate (SIGTERM) retains the "Don't ask again" option as it's a gentler
  operation that allows processes to save data

UX improvements:
- Clear error message when attempting to force-kill protected processes
- ConfirmationSheet now supports optional "Don't ask again" toggle via
  nullable skipPreferenceKey parameter

This prevents accidental system crashes from force-killing critical processes
while maintaining power-user convenience for regular termination.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:26:46 +01:00
hariel1985
02a08d23cc Harden unsafe pointer code against malicious process names
Defensive coding improvements to mitigate "kernel as messenger" attack vector
where a local malicious process could craft extreme process names/paths:

- fetchProcessName: Create string from explicit length instead of relying
  on null terminator. Protects against edge cases where path buffer might
  not be null-terminated at exactly maxPathSize.

- BSD name extraction: Copy to safe buffer with guaranteed null termination
  before converting to String. Protects against pbi_name being exactly
  MAXCOMLEN bytes without null terminator.

- fetchBasicProcessInfo: Same safe pattern for p_comm field extraction.

- Strip control characters and whitespace from process names to prevent
  display/injection issues from maliciously crafted names.

Security: Addresses potential buffer over-read in unsafe Swift pointer
operations when parsing attacker-influenced kernel data structures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 23:20:51 +01:00
hariel1985
201c7737a6 Add PID validation to prevent TOCTOU race condition in process control
Security improvements:
- Validate process still exists before sending signals
- Verify process start time matches to detect PID reuse
- Add ProcessControlError enum with descriptive error messages
- Show error alerts when operations fail (permission denied, process not found, PID reused)
- Pass expectedStartTime to all process control operations

This prevents accidentally terminating the wrong process when a PID
gets reused between user selection and confirmation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:49:40 +01:00
hariel1985
8fee51a4dd Update processes screenshot with CPU/Core and CPU/Total columns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:40:04 +01:00
hariel1985
5e8343dea8 Add CPU/Total column showing normalized system-wide CPU usage
- Add cpuUsageTotal property to ProcessItem (100% = all cores)
- Keep cpuUsage as per-core percentage (100% = 1 core)
- Display both columns: CPU/Core and CPU/Total
- CPU/Total values now sum to match the total system CPU

This clarifies the difference between per-core and system-wide CPU
measurements that was causing confusion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:37:38 +01:00
hariel1985
ca8cde3e2c Optimize CPU usage: background threading and smart refresh cycles
Major performance improvements to reduce CPU usage from 25-30% to ~0.5%:

- Move all data fetching to dedicated background queue
- Prime CPU and process monitors at startup with 1-second delay for accurate delta calculation
- Implement smart refresh cycles: processes fetched every other cycle after initial warmup
- Add lightweight refresh that skips expensive calls for idle processes (CPU < 0.1%)
- Increase refresh interval from 2s to 3s
- Add caching for processes with no icons to avoid repeated lookups
- Use sysctl fallback to get correct user ownership for system processes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 16:29:04 +01:00
hariel1985
5b3a7f92e5 Add screenshots to README
- Processes tab
- Apps tab
- Performance (CPU, Memory, Network)
- Power & Storage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:00:32 +01:00
hariel1985
41010541a7 Initial commit: TopManager macOS system monitor
A native SwiftUI app for monitoring macOS system resources:
- Processes tab with sorting, filtering, and process control
- Apps tab for running applications
- Performance tab with CPU, memory, and network charts
- Power & Storage tab with system info, GPU, storage, and network

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:56:51 +01:00