-
Notifications
You must be signed in to change notification settings - Fork 0
Releases: pratikwayal01/kim
Title: v4.5.9 β Security & bug fixes
Security fixes
- Import data loss:
_sanitize_remindernow preservesatandtimezonefields β daily-at reminders previously had their schedule silently stripped onkim import - Export file permissions:
kim export --output filenow creates the file with0o600β previously world-readable, leaking Slack tokens/webhook URLs on multi-user systems - Slack webhook HTTPS enforcement: webhook notifier refuses to send over plain
http:// - Self-update integrity: CI generates a
.sha256checksum per binary;kim self-updatefetches and verifies before replacing the binary (supply chain mitigation) - Magic bytes check tightened: script update check now matches
b"from "/b"import "instead ofb"fr"/b"im"
Bug fixes
kim remindcrash:oneshots.jsonvalidated aslistbefore.append()β corrupt non-array file causedAttributeErrorcrash (4 call sites)- Daemon start with only one-shots:
kim startno longer refuses to start when recurring reminders are all disabled but one-shots are pending - Uninstall drops pending one-shots: kills sleeping fork children, reports count cancelled, wipes
oneshots.jsonbefore removing files
Stability
- Threading race:
_get_utc_offsetTZ env mutation guarded bythreading.Lock+finallyβ scheduler and config-reload threads no longer race onos.environ - Process kill safety:
_kill_remind_fire_orphanson Linux now resolves exe path against the actual kim binary before sending SIGTERM β previously could kill unrelated processes
Assets 10
v4.5.8 fix uninstall
Fix unisntall
kim uninstall
If kim is broken or the above doesn't work, use the standalone uninstaller:
curl -fsSL https://raw.githubusercontent.com/pratikwayal01/kim/main/uninstall.sh | bashLast resort β manually remove all kim files:
# Stop daemon [ -f ~/.kim/kim.pid ] && kill $(cat ~/.kim/kim.pid) 2>/dev/null; true # Remove binary, package, and data rm -f ~/.local/bin/kim rm -rf ~/.kim # Remove autostart (Linux) systemctl --user disable --now kim.service 2>/dev/null; true rm -f ~/.config/systemd/user/kim.service # Remove pip metadata if installed via pip pip uninstall kim-reminder -y 2>/dev/null; true
Assets 6
v4.5.7
v4.5.7 - 2026εΉ΄04ζ07ζ₯
Added
kim remove <N>β remove a recurring reminder by 1-based index as shown inkim list. Existing name-based removal still works unchanged.kim listshows#index column β recurring reminders now display a 1-based index so users know what number to pass tokim remove.
Upgrade
pip install --upgrade kim-reminder
Assets 6
v4.5.6
v4.5.6 - 2026εΉ΄04ζ07ζ₯
Added
kim export --oneshotsβ include pending one-shot reminders in the export (JSON:"oneshots"array; CSV: appended section). Use with-o fileto save to a file.kim import --oneshotsβ restore pending one-shot reminders from a file produced bykim export --oneshots. Only future fire times are imported; duplicates are skipped.- Help footer now shows
oneshots: ~/.kim/oneshots.jsonalongside the config and log paths.
Fixed
kim uninstallnow kills orphanedkim remindfork children β on Linux the uninstall reads/procdirectly to find and SIGTERM every sleepingkim remindchild process. On macOS/other Unix it falls back topkill -f. This prevents a one-shot reminder from firing after kim has been uninstalled.kim uninstallclearsoneshots.jsonbefore removing~/.kim/β even if a fork child survives the SIGTERM (e.g. already woken), the cleared file means it cannot write back or be replayed on any futurekim start.
Assets 6
v4.5.5 β 19 issues fixed
High severity (4)
- scheduler.py: _wakeup.clear() moved inside the lock β eliminates missed-wakeup race condition
- scheduler.py: Notifier now runs in a daemon Thread β blocking Slack calls no longer stall the scheduler
- misc.py: Unix fork child now calls remove_oneshot() after firing β prevents double-fire on daemon restart
- misc.py + others: all oneshots.json tmp writes now get chmod 0o600 on Unix
Medium severity (8) - scheduler.py: Fired one-shots removed from _live dict β memory leak fixed
- misc.py: sleep_seconds clamped to max(0.0, ...) β no crash on clock jump
- management.py: cmd_update --interval validates the value before saving
- config.py: cmd_validate now checks at field is valid HH:MM
- notifications.py: Slack webhook/bot check response body for ok: false
- interactive.py: edit_reminder now removes at/timezone when switching to interval
- interactive.py: add_oneshot prompts for urgency instead of hardcoding "critical"
- core.py: load_config prints a stderr warning on JSON corruption
Low severity (7) - cli.py: bare kim now exits 0
- cli.py: import re moved to module level
- scheduler.py: dead update_reminder/disable_reminder wrappers removed
- core.py: parse_interval deprecated (kept for test compat)
- misc.py: import datetime moved to module level
- sound.py: validate_sound_file checks os.access(path, os.R_OK)
- management.py: except Exception narrowed to (json.JSONDecodeError, OSError)
Assets 6
v4.5.0
What's Changed
Bug Fixes
- Daemon detection fixed β kim start now correctly detaches to the background on all Linux distros. Previously, systemd's INVOCATION_ID environment variable was inherited by child shells, causing kim start to block the terminal instead of spawning a background process. Detection now uses a TTY check (/dev/tty) which is reliable across Linux and macOS.
- kim start / kim stop now show PID β all start/stop messages include the process ID:
- kim started. (PID 1234)
- kim is already running. (PID 1234)
- kim stopped. (PID 1234)
- kim is already stopped.
- kim remind output consistent with kim add β confirmation now uses the β prefix:
- Before: watch set: 'standup' in 10m
- After: β Reminder set: 'standup' in 10m
- Internal _remind-fire command hidden β no longer leaks into the kim usage line.
- Urgency persisted correctly for one-shot reminders β if the daemon restarts while a kim remind is pending, it now restores the original urgency instead of always upgrading to critical.
New Features - kim remind --urgency β one-shot reminders now accept --urgency low|normal|critical (default: normal), matching kim add.
Installation / Updates - --break-system-packages added to all pip calls β kim self-update and kim uninstall now work correctly on Arch Linux, Debian 12+, Ubuntu 23.04+, and other distros with externally managed Python environments.
Shell Completions - --urgency added to kim remind completions for bash, zsh, and fish.
Upgrade
kim self-update
Or reinstall from scratch:
curl -fsSL https://raw.githubusercontent.com/pratikwayal01/kim/main/install.sh | bash
Assets 6
v4.4.0
What changed:
On Windows, pip hits the exact same WinError 32 we did β it tries to os.rename(kim.exe β temp) before deletion, which fails because kim.exe is the running process. The fix is the same pattern we already use for kim.log: exit first, delete after.
The deferred PowerShell script now does three things in sequence after this process exits:
pip uninstall kim-reminder -y β removes kim.exe, kim.bat, all package files
Delete kim.log (retry loop, up to Γγ°γ€)
Remove ~/.kim/ (retry loop, up to Γγ°γ€)
Assets 6
v4.3.0 β pip uninstall overhaul
What's changed
Bug fix β kim uninstall on pip installs
The root cause of all Windows uninstall errors was that kim uninstall was
trying to delete its own running files (kim.exe, kim.bat) instead of
delegating to pip, which owns them.
Problems fixed
- WinError 5 on
kim.exeβ eliminated entirely; pip removes it cleanly - "The batch file cannot be found." β eliminated entirely; pip removes
kim.batcleanly - Simpler, more reliable uninstall path: one
pip uninstall kim-reminder -ycall handles all binaries
~/.kim/ user data (not owned by pip) is still removed by kim itself.
On Windows, kim.log is still removed via the deferred PowerShell retry script
after the process exits and releases the file handle.
Refactor
cmd_uninstall was a 260-line monolith. It has been decomposed into focused helpers:
| Helper | Responsibility |
|---|---|
_remove_os_service |
systemd / launchd / Task Scheduler cleanup |
_kill_remind_fire_orphans |
kill sleeping _remind-fire subprocesses |
_close_log_handles |
flush and close Python log file handles |
_remove_kimdir |
remove ~/.kim/ user data |
_remove_kimdir_deferred_windows |
background PowerShell retry script |
_uninstall_pip |
pip path: pip uninstall + remove ~/.kim/ |
_uninstall_script_or_binary |
script/binary path: existing file-deletion logic |
Test suite
- Regression test classes updated to inspect the correct helper functions
- 7 new tests in
TestPipUninstallDelegatesToPip - 238 tests, all passing
Upgrade
pip install --upgrade kim-reminder
Assets 6
v4.2.0
What's changed
Bug fixes β kim uninstall on Windows
This release is a focused overhaul of kim uninstall on Windows. Every failure mode encountered in real-world testing has been identified and fixed.
Problems fixed
- WinError 32 on
shutil.rmtreeβ~/.kim/kim.logwas locked by this process's ownRotatingFileHandleropened at import time - WinError 5 on
kim.exeβ pip entry-point.exeis the running process itself; directunlink()yields Access Denied - "The batch file cannot be found." β
kim.batwas deleted immediately whilecmd.exewas still mid-execution of it ~/.kim/kim.logleft on disk β orphaned_remind-firesubprocesses (sleeping one-shot reminders) held their own handle onkim.log~/.kim/directory left on disk β single-attemptRemove-Item -Recursesilently failed whilekim.logwas still lockedkimstill resolves 1-2 times after uninstall β PowerShell per-session command cache; a note is now printed to open a new terminal
How each is fixed
- Orphaned
_remind-firesubprocesses are now killed synchronously before touching~/.kim(PowerShellStop-Processon Windows,pkillon Unix) kim.batis never deleted immediately β always deferred to after process exit via a hidden background PowerShell subprocesskim.exeis collected asdeferred_exeand deleted by the same deferred PS subprocess- Deferred PS script uses a two-stage retry: delete
kim.logfirst (up to 10 attempts, 1 s apart), then remove the now-empty~/.kim/(up to 5 attempts) - Log handlers are closed on the
"kim"named logger, not just the root logger - A hint is printed after uninstall on Windows:
(Open a new terminal for the change to take effect.)
Test suite
- Consolidated
test_basic.py+test_features.pyinto a single canonicaltests/test_kim.py - 10 new regression test classes added to
tests/test_regression.pycovering every uninstall fix - 231 tests, all passing
Upgrade
pip install --upgrade kim-reminder
Assets 6
v4.1.1
What's new in v4.1.0
Features
--everyalias for-I/--intervalonkim add--at HH:MMfor daily fixed-time reminders (kim add standup --at 09:30)kim remindnow supports absolute datetime (at tomorrow 14:00,at 2026εΉ΄04ζ07ζ₯ 14:30 --tz ...)- One-shot reminders are persisted to
~/.kim/oneshots.jsonand survive daemon restarts
Improvements
kim startno longer blocks the terminal β spawns a detached background process and returns immediatelykim start/kim stopoutput clean status messages with PID (kim started. (PID 1234))kim startwhen already running showskim is already running. (PID 1234)instead of an errorkim stopwhen not running showskim is already stopped.kim statusrunning line showsβγγγΎγ kim running (PID 1234)
Fixes
- Repaired
release.ymlCI workflow - PyPI install instructions added to README and docs
- fix: auto-add pip Scripts dir to Windows PATH on first run β users no longer need to manually update PATH after pip install kim-reminder
Added
kim remind "msg" in 10m/at tomorrow 9amβ one-shot reminders with relative and absolute datetime parsing--every <interval>alias for--interval;--at HH:MMfor daily at-time reminders- Live config reload β
kim add/remove/enable/disable/updatetake effect in the running daemon within 1 second, no restart needed (~/.kim/kim.reloadflag file + SIGHUP on Unix)