Skip to content

Releases: Kanevry/DevWatchdog

DevWatchdog v3.3.0

Choose a tag to compare

@github-actions github-actions released this 22 Apr 14:02

Installation

  1. Download DevWatchdog-3.3.0.zip below
  2. Unzip and move DevWatchdog.app to /Applications
  3. First launch: right-click → Open (ad-hoc signed; Gatekeeper requires one-time approval)

Added

  • cwd-basierte Projekterkennung (G2) — hinter neuem Feature-Flag
    useCwdProjectDetection (Default: aus). Liest das Arbeitsverzeichnis via
    proc_pidinfo(PROC_PIDVNODEPATHINFO) und löst es über einen
    Projekt-Root-Walker (.git, package.json, Cargo.toml, go.mod,
    pyproject.toml, Podfile, Package.swift) zum korrekten Projektnamen auf
    (leaf-wins für Monorepos). Behebt die Regressionsgrenze, dass
    ~/Projects/Archiv/DevWatchdog/ den Marker "Archiv" statt "DevWatchdog"
    liefert. Wirkt nur im libproc-Pfad. DevProcess hat neue Felder
    workingDirectory und detectedProject; das bestehende projectName
    bevorzugt detectedProject, wenn gesetzt. Closes GitLab #35.
  • Signal-basierter Dev-Klassifier (G1) — hinter neuem Feature-Flag
    useSignalClassifier (Default: aus). Vier orthogonale Heuristiken
    (Executable-Pfad, cwd, Parent-Prozess, Bundle-Identifier) ersetzen die
    Wortlisten-Erstklassifikation. Harter Ausschluss für Nicht-Dev-Bundles
    (z. B. com.slack., com.notion., Browser) wird von einer
    Dev-Allowlist überschrieben (VSCode, Cursor, iTerm2, Terminal, Warp).
    .unknown-Urteile fallen zur Wortliste zurück — existierende
    defaultInclusionPatterns / defaultExcludedApps bleiben unverändert.
    Wirkt nur im libproc-Pfad. Closes #36.
  • Zwei neue Settings-Toggles unter „Entwickler" für die oben genannten
    Flags, im gleichen „Experimentell —" Muster wie der libproc-Scanner.
  • 46 neue Unit-/Integrationstests (ProcPIDInfoCwdTests,
    ProjectRootResolverTests, DevProcessClassifierTests,
    LibProcSignalClassifierTests). Test-Baseline 335 → 381.
  • libproc-basierter Prozess-Enumerator (opt-in, Feature-Flag) — neuer
    LibProcProcessEnumerator nutzt proc_listpids + proc_pidinfo direkt
    und ersetzt den /bin/ps-Subprocess-Pfad, wenn useLibprocEnumerator
    unter Einstellungen → Entwickler aktiviert ist. Default false; gleiche
    DevProcess-Ausgabe wie PSParser; identische Filter-Semantik
    (Inclusion-Patterns, Excluded-Apps, Playwright-Ausnahme,
    /Applications/-Heuristik). Scan-Dauer wird auf beiden Backends für
    Vorher/Nachher-Vergleich geloggt. Bekannte MVP-Divergenzen:
    command ist nur Exec-Pfad (nicht volles argv); CPU% ist kumulativ seit
    Start (Delta-Sampling deferred). Closes GitLab #34 (G5).

Fixed

  • GitHub-Actions-CI grün auf Xcode 16.2 / Swift 6.0 strict concurrency — drei
    non-sendable type-Fehler in SystemPressureMonitor.swift wurden durch zwei
    neue @unchecked Sendable-Wrapper beseitigt: SendableCurrentValueSubject
    kapselt Combines CurrentValueSubject (nicht formal Sendable in 6.0) und
    SendableDispatchSource kapselt any DispatchSourceMemoryPressure für den
    @Sendable-Handler-Closure. Lokal unter Xcode 26 / Swift 6.2 unverändert grün;
    CI-Runner zieht jetzt auf Xcode 16.4 (war 16.2) für konsistente Swift-6.0-GA-Baseline.
  • Popover bleibt offen, Buttons reagieren nicht (Regression seit v3.2.0,
    NSStatusItem-Umbau). LSUIElement-App braucht explizites
    NSApp.activate(ignoringOtherApps: true) bevor das Popover gezeigt wird —
    sonst kann das Popover-Window nicht key werden, SwiftUI-Buttons (Beenden,
    Einstellungen, Protokoll, Kill-CTAs) feuern nicht, und .transient-Dismissal
    bleibt aus. Zusätzlich verhinderte NSHostingView über dem Status-Button
    durch eigenes Hit-Testing das Toggle-Verhalten; Label-Host ist jetzt eine
    PassthroughHostingView, die Klicks an den darunter liegenden NSButton
    durchreicht. Closes GitLab #38.
  • ActionBar ohne Inhalt bei einem einzelnen aktiven Suspect — 16 px leeres
    Padding + Divider, wenn genau ein aktiver Suspect ohne Zombies/Idle vorlag,
    weil die CTA-Logik nur bei count > 1 einen Button rendert. Gate prüft jetzt
    via hasActionBarContent die tatsächlichen CTA-Conditions. Closes #39.
  • Header-Pill abgeschnitten bei hohen CPU-Werten — Popover-Breite
    380 → 400 px, Pill + Timestamp-VStack hat minWidth: 90. Closes #40.
  • Swap-Zeile zeigte Compression-Rate — die ↑ x/s-Rate ist ausschließlich
    Compression-Rate; wird jetzt nur im "Compressed"-Modus gerendert, nicht wenn
    die Zeile auf "Swap" flippt. Closes #41.

Changed

  • Pause/Fortsetzen jetzt auch für gruppierte ProzesseProcessGroupRowView
    reicht onThrottle/onResume an expandierte Kind-Rows durch. Im bun (4)-
    Menü stehen damit Pausieren und Fortsetzen zur Verfügung. Closes #42.
  • Panic-Button visuell sekundär — im Header nur noch Bolt-Icon; ab 10+
    Targets erscheint der Count als kleines Badge daneben. Tooltip enthält den
    aktuellen Count. Hotkey ⌘⇧⌥P unverändert. Closes #43.
  • Empty-State kontextsensitiv — Copy unterscheidet jetzt zwischen normal
    ("Alles sauber"), elevated ("Vorerst sauber") und emergency ("Keine
    Targets mehr · System-Druck noch hoch, Scanner greift sofort zu"). Behebt den
    visuellen Widerspruch zwischen pulsierendem Emergency-Banner und grünem
    "Alles sauber"-Check. Closes #44.
  • Footer: "Log" → "Protokoll" — einheitlich deutsch. SessionLogView-Titel
    entsprechend angepasst ("Session-Protokoll"). Closes #45.
  • CPU-Farbskala skaliert jetzt mit ncpu — 100 % CPU auf einer 12-Kern-
    Maschine ist keine Warnfarbe mehr wert; rot ab ≥ 15 % Gesamt-Kapazität,
    orange ab ≥ 5 %. Gilt für Einzel- und Gruppenzeilen. Closes #46.
  • CI-Infrastruktur modernisiert.github/workflows/build.yml pinnt jetzt
    Xcode 16.4 (letzte Stable-16-Serie mit Swift-6.0-GA-Korrekturen) und unterstützt
    manuelles workflow_dispatch. Neuer Release-Workflow (release.yml) triggert
    auf v*-Tags, baut Release-Konfiguration, packt .app via ditto als ZIP
    und erstellt GitHub Release mit CHANGELOG-Auszug + --generate-notes.
    .gitlab-ci.yml spiegelt Build+Release. Beide Workflows mit minimalen Token-
    Scopes (contents: read für Build, contents: write für Release) und
    env-var-Indirection für user-supplied Tag-Inputs (Injection-Schutz).

Security

  • Release-Workflow-Härtung${{ inputs.tag }} (workflow_dispatch) wird
    jetzt über env: in Shell-Variablen gemappt, nie direkt in run:-Blöcke
    inline-interpoliert. Gleiches Pattern für alle ${{ steps.*.outputs.* }}-
    Referenzen. Zusätzliche Tag-Format-Validierung (^v[0-9]+\.[0-9]+\.[0-9]+$)
    verhindert freie-Text-Injection. build.yml bekommt explizites
    permissions: contents: read (minimal-privilege).

Full Changelog: v3.2.0...v3.3.0

v3.2.0 — Why-Badges, Smart Kill Split, Menu-Bar Live Refresh

Choose a tag to compare

@Kanevry Kanevry released this 21 Apr 10:06

Triage follow-up release. User-facing UX clarity (why-badges, smart kill split, hardware-aware recommendations), new infrastructure (disk-persisted session log + newly-orphaned detection), Apple-Silicon-correct memory-pressure signal, and the migration off MenuBarExtra that finally makes the menu-bar icon refresh without hovering.

Highlights

  • "Why?" signal badges per row — NEW ORPHAN, IDLE 7m, LEAK 842MB, ACTIVE 121%, RULE …, KILL … — with German tooltips and a KillConfidence-driven row tint so real zombies jump out in a crowded list.
  • Smart-split kill buttons — idle (safe, green) vs. active (risky, red/orange) render as two separate buttons; you never accidentally terminate the vitest run you're still watching.
  • Hardware-aware recommendations next to every timing slider (scales with RAM / core count), plus per-section reset.
  • Session log persists to disk (~/Library/Application Support/DevWatchdog/sessions/YYYY-MM-DD.jsonl) — Insights finally accrues across restarts.
  • Menu-bar icon refreshes without hovering — dropped MenuBarExtra for NSStatusItem + NSHostingView, fixing FB11857447.
  • Compressor-based memory signal — Apple Silicon's always-zero vm.swapusage stops hiding real pressure; Emergency mode now triggers on compressor_page_count.
  • UI language unified to German across every surface.

Full changelog: CHANGELOG.md

Install

  1. Download DevWatchdog-3.2.0.dmg below
  2. Open it and drag DevWatchdog to /Applications
  3. On first launch you may need to right-click → Open (signed Developer ID, not yet notarized)

Verify

  • SHA-256: 4efbd8f620fb71439d7955449fff38b926824d06ba51d213be7983b7030bc3ea
  • Size: 2.03 MB
  • Signed: Developer ID Application: Bernhard Goetzendorfer (G3QZ66475M), hardened runtime
  • Notarized: no (tracked for a future release)

Known gaps

Welle C is scoped for the next session: libproc migration (#34), project detection via PROC_PIDVNODEPATHINFO (#35), signal-based dev detection (#36), proper i18n (#37).

DevWatchdog 3.1.0 — Emergency Mode + Observability

Choose a tag to compare

@Kanevry Kanevry released this 21 Apr 06:24

First Developer ID signed release. Two feature waves shipped since v2.1.0.

Install

  1. Download DevWatchdog-3.1.0.dmg below
  2. Open the DMG, drag DevWatchdog into Applications
  3. First launch: right-click the app → Open → confirm (or run xattr -d com.apple.quarantine /Applications/DevWatchdog.app)

The DMG is signed with a Developer ID but is not yet notarized, so Gatekeeper will warn once on first launch. Verify with codesign -dv --verbose=4 /Applications/DevWatchdog.app — you should see Developer ID Application: Bernhard Goetzendorfer (G3QZ66475M).

SHA-256: 40603766b6ca3ab12655f35d23c9791619c9cbefd2de0ef4fbf2f5b64ffb907b

What's new since v2.1.0

Emergency Mode (v3.0 — previously unreleased)

When 5-min load average crosses emergencyLoadFactor × CPU-count (default 1.5×), grace periods shrink and maxRuntime thresholds compress until load returns to normal. emergencyMinAgeSeconds protects freshly-spawned processes. Rule-level maxCPUPercent / maxRSSMB enable resource-aware killing. Migration-safe: old rules decode with 0 defaults.

Observability (v3.1)

  • Structured logger — all SessionLog calls flow through DWLogger with category tagging and level filtering
  • Insights tab — weekly summary of kills, top projects / process types, reclaimed CPU-hours and RSS-MB
  • Dev Filter — narrow the watch surface to specific path patterns (inclusionPatterns) for single-project focus
  • Kill-reason audit — every kill carries KillTrigger + KillReason (orphan, maxRuntime, emergency-cpu, emergency-rss, manual, rule-override)
  • Match modes — rule patterns now support glob, regex, substring, exact
  • Log export — JSON export (with secret redaction) via pasteboard or save panel
  • Hardening — Mach-backed ProcPIDInfo fallback, ps timeout watchdog, PID-reuse guard

Quality

  • 288 tests passing, zero Swift 6 warnings, strict-concurrency clean
  • +136 new tests across 10 new test files
  • First release with hardened runtime + Developer ID signing

Known gaps

  • Not notarized yet — tracked for the next release
  • Screenshots are still from v2.x — Insights tab + Dev Filter not yet captured

See the full CHANGELOG.