Fixed
- Windows: the config permissions warning no longer re-fires on every launch (issue #173 follow-up reported by @rutexd). On Windows, Node can only report file modes 0666 (writable) or 0444 (read-only), so the old "is it 600?" check could never pass: the app warned, you answered yes, it said "fixed!", and the next launch warned again in an endless loop.
- The Windows security verdict now comes from the real NTFS ACL, read with
icacls <file>and parsed by a new pure helper (parseIcaclsOutput). The file counts as protected when NTFS inheritance is disabled and only your user (plus trusted SYSTEM/Administrators entries, matched by name or well-known SID, locale-proof) has access. - Fixing on Windows now runs
icacls "<file>" /inheritance:r /grant:r "<user>:F"(no shell, injection-safe) instead of the no-op chmod, and the fix is verified by re-reading the ACL before the app claims success. No more fake "✅ Permissions fixed!". - The warning now explains what is wrong on NTFS (inherited access, or which other principals have a grant) instead of showing a meaningless octal mode.
- The Windows security verdict now comes from the real NTFS ACL, read with
- Anti-nag guard (all platforms): when the fix genuinely cannot be applied or verified (rare), the app now writes a small ack marker next to the config file and stays quiet about the same warning for 30 days, instead of nagging on every single launch. Passing
--fix-permissions/--yes/-yalways bypasses the marker and retries. The marker is cleaned up as soon as a fix succeeds. - The manual fix hint on Windows now shows the exact
icaclscommand with your real username, and the POSIX path (chmod 600) additionally re-checks the mode after chmod so success messages are always truthful.
Changed
--fix-permissionsdocumentation now mentions it applies NTFS ACLs on Windows (README flags table).
For contributors
- New pure helpers in
src/core/utils.js, fully unit-tested:parseIcaclsOutput(icacls output parser, handles the echoed path glued to the first ACE,(I)inheritance markers, SIDs and localized group names) andshouldSkipSecurityWarn(30-day anti-nag gate, ISO string or epoch input, clock-skew safe). checkConfigSecurity()gained an integration test covering the full lifecycle: warn once, ack, stay silent on relaunch, auto-fix bypasses the ack, marker cleanup after a successful fix.