Desktop task scheduler (Python + tkinter, no pip dependencies) that fires an action at a given time. It merges two tools:
- Alarm — fires at a random time within a range, runs a program or opens a file/URL, with a sound and a pop-up.
- Resume terminals — at a given time, types a text + Enter into every open terminal whose title matches a filter (to resume Claude Code when the usage limit resets).
The Check for updates button fetches new versions from GitHub. It is the app's only network connection, and it is made only when you press it (details).
Each task in the list combines when it fires with what it does:
- Fixed time
HH:MM. - Random within a range
[from, to]: picks a random moment inside the window. - Repeat every day: once it fires, it is rescheduled for the next day (drawing a new random time if the time is random).
- Type into terminals: finds the windows that match the filter (by default
WindowsTerminal), focuses them one by one and types the text (by defaultcontinua) followed by Enter. The filter looks at the window title and, on Windows, also at the process name: that wayWindowsTerminalfinds the terminals even when their title changes. Empty filter = every window. Optional: keys before (e.g.escorctrl+cbefore the text), number of Enters to press (0= send without Enter), and which windows to act on (all / only the first / only the focused one). - Run program / open: launches a program or opens a file/URL in its default application. Optional: arguments (command-line style), working folder and window mode (normal / minimised / hidden / elevated with UAC).
- Sound when it fires.
- Pop-up with a message.
The random time within a range option is not just a convenience: it is an anti-tracking feature.
When a task always opens a website or runs a program at exactly the same time, that schedule is predictable: anyone watching the traffic or the system can anticipate when you are going to connect to a given service or when a given program will start, and link that activity to you.
By picking the firing time at random within a range (e.g. "sometime between 02:00 and 06:00"), the exact moment is no longer predictable on each run. So:
- There is no fixed time signature giving away the connection or the program start.
- The link between a known time and the action is broken, making it harder to infer from the clock which website or program is going to be used.
- Every day (with Repeat every day) the random time is drawn again, so it does not even stay the same from one day to the next.
It is especially useful for the Run program / open action: scheduling a service to open at an unpredictable time within a wide window.
Clone it with git, or download the zip of the latest release and unpack it. Either copy can be updated later with the Check for updates button. Then start it from its folder:
git clone https://github.com/javimentallab/TaskTriggerAntitrack.git
cd TaskTriggerAntitrack
python tasktriggerantitrack.pyOn Windows you can also double-click tasktriggerantitrack.cmd (opens the window
without a console).
- Fill in a name, choose a fixed time or a range, and the action type.
Times are picked on a clock-style picker: click the hour on the ring (outer
0–11, inner12–23) and then the minutes. - Save task (it shows up in the list). Test now to see it fire straight away.
- Leave the window open: every second it checks and fires whatever is due.
In the list: ● active / ⏸ paused · ✎ terminal / ▷ program · ↻ repeats daily ·
next HH:MM:SS the next firing (or next DD/MM HH:MM if not today). Select a task to
edit, pause or delete it.
Shortcuts: Ctrl+S save · Ctrl+T test · Esc clear · Del delete.
- Single instance: if it is already open, launching it again just brings the existing window to the front (no duplicate firings).
- Autostart:
--minstarts it minimised; meant for a shortcut in the Windows Startup folder (shell:startup) or in the desktop's autostart. - Tasks are saved atomically (they are not corrupted if interrupted halfway) and a
task with invalid data is disabled instead of stopping the app from starting. An
unreadable
alarms.jsonis copied aside (alarms.json.corrupto-<date>) with a warning, and is not touched until you save a task. Any failure goes toerror.log(withpythonwthere is no console).
The Check for updates button (top right) asks GitHub for the latest published version. It is
the app's only internet connection, and it is made only when you press it: nothing is checked at
start-up or in the background. It sends one HTTPS request to api.github.com with a generic
User-Agent (TaskTriggerAntitrack-updater/<version>) and no personal data, and it only accepts
answers and redirects from GitHub's domains. If there is a new version, it asks before changing
anything.
- Git clone (a
git clone): if it is clean and has no commits of its own, git fetches that version's tag from the official repository (https://github.com/javimentallab/TaskTriggerAntitrack, not whateveroriginis set to) and moves the clone forward to it, fast-forward only. Git checks what it downloads by its hashes. If there are local changes or commits of its own, or git is missing, nothing is touched: it explains why and offers the release page. - Any other copy in a folder that can be written to: it downloads that version's zip, checks its
SHA-256 checksum when the release publishes one (and says so when it does not), replaces the files
and keeps the previous ones in
.tta-backup-<version>-<date>. - A folder that cannot be written to: the zip is saved in Downloads and the release page opens.
It never touches alarms.json, error.log or your alarm_sound.wav. After updating, close the app
and open it again.
The interface is in English, Spanish, Portuguese, French, German, Italian, Dutch, Polish, Russian,
Ukrainian, Chinese, Japanese, Korean, Thai and Hindi. It follows the system's language; to pick one,
start it with --lang xx (e.g. --lang de) or set the TTA_LANG environment variable. The texts live
in tta_lang.py.
- Python 3.8+ with tkinter (included by default on Windows and most distros).
- Windows: nothing else. Focusing and typing into windows uses Win32 through
ctypes, and the sound useswinsound(both in the standard library). - Linux (X11):
xdotoolto focus/type into windows, andaplay/paplayfor the sound. (On Wayland, typing into other apps' windows may be restricted.)
Tasks are saved in alarms.json next to the script. It is not versioned (it holds your
personal setup), and neither are error.log and the copies left by the Check for updates button
(.tta-backup-*).
Scanning with Trivy on every push (.github/workflows/trivy.yml): vulnerabilities,
secrets and misconfigurations. CodeQL analyses the code and the tests run on every push too.
See CONTRIBUTING. To report a security problem privately, see SECURITY.
