awake-cli
v1.2.1
Published
Lightweight cross-platform CLI that broadcasts subtle simulated activity to keep apps like Microsoft Teams from going idle/away.
Downloads
515
Maintainers
Readme
awake-cli
A lightweight, cross-platform CLI that broadcasts subtle simulated system activity so presence apps (Microsoft Teams, Slack, etc.) stay in your chosen state instead of flipping to Away when you step back.
- npm: https://www.npmjs.com/package/awake-cli
- GitHub: https://github.com/YRACHEK101/awake-cli
- Tiny & dependency-free — pure Node.js (ESM), zero npm dependencies, no
compiled binaries. The "pulse" is a single harmless
F15key tap delivered through each platform's own built-in tooling. - Cross-platform — Windows, macOS, Linux (X11).
- KISS — five short, single-responsibility files.
Quick start
npm install -g awake-cli # install once
awake-cli # then just run it — stays active until Ctrl+CThat's it. The command is awake-cli (or the shorter alias awake).
Most common real-world use — only stay active during work hours:
awake-cli --start 09:00 --end 18:00How it works
Presence apps mark you Away when the OS idle timer (time since last input)
elapses. awake-cli periodically injects an F15 keystroke — a key that exists
in the protocol but that no physical keyboard sends and no app reacts to — which
resets that idle timer without disturbing anything on screen. The interval is
randomly jittered (default 30–75s) so it never forms a mechanical pattern.
awake-clicannot set your status string. Choose Available or Busy/Do-Not-Disturb in the app yourself;awake-clikeeps that choice from decaying to Away.
Install
npm install -g awake-cli # installs the `awake-cli` (and `awake`) commandOr from source:
git clone https://github.com/YRACHEK101/awake-cli && cd awake-cli
npm install -g . # links the global command
node index.js --help # or run without installingRequires Node.js >= 16.
Platform prerequisites
| OS | Requirement |
|----|-------------|
| Windows | PowerShell (ships with Windows). Nothing to install. |
| macOS | Grant your terminal Accessibility access: System Settings → Privacy & Security → Accessibility. |
| Linux | X11 session with xdotool installed (sudo apt install xdotool). Wayland is not supported. |
If a pulse can't be delivered, awake-cli prints a one-time hint and keeps running.
Usage
awake-cli [--mode forever] [--status available|busy]
awake-cli --start HH:MM --end HH:MM
awake-cli --from DD/MM --to DD/MM --start HH:MM --end HH:MMModes
1. Forever (default) — runs until you press Ctrl+C.
awake-cli
awake-cli --mode forever --status busy2. Managed by time — active only inside daily working hours; sleeps efficiently (near-zero CPU) outside them.
awake-cli --start 09:00 --end 18:003. Vacation / date-range — active only on the given calendar days, inside the daily hours, then auto-exits once the end day/time passes.
awake-cli --from 24/02 --to 26/02 --start 09:00 --end 17:00Options
| Flag | Description | Default |
|------|-------------|---------|
| --mode forever | Run indefinitely | (default) |
| --status | available or busy | available |
| --start HH:MM | Daily window start | — |
| --end HH:MM | Daily window end | — |
| --from DD/MM | Range start day | — |
| --to DD/MM | Range end day | — |
| --min <sec> | Min seconds between pulses | 30 |
| --max <sec> | Max seconds between pulses | 75 |
| --lunch HH:MM-HH:MM | Stop pulsing during this window (go Away) | — |
| --stealth | Gaussian jitter + random 5–10 min human pauses | off |
| --tg-token <token> | Telegram bot token (or AWAKE_TG_TOKEN env) | — |
| --tg-chat <id> | Only chat id allowed to command (or AWAKE_TG_CHAT) | — |
| -h, --help | Show help | — |
| -v, --version | Show version | — |
Stealth & lunch breaks
Lunch break — --lunch HH:MM-HH:MM suspends pulses during that window so
the OS idle timer decays naturally and your presence flips to Away (a real
lunch), then resumes automatically:
awake-cli --start 09:00 --end 17:00 --lunch 12:30-13:15Stealth — --stealth replaces the flat random interval with a Gaussian one
(delays cluster around the midpoint, like a human) and sprinkles in occasional
5–10 minute pauses through the day:
awake-cli --start 09:00 --end 17:00 --stealthTelegram remote control (optional)
Drive a running instance from your phone with /status, /pause, /resume.
Security: you supply your own bot token — it is never hardcoded or bundled. Keep it in an environment variable, not in scripts you commit. Commands are accepted only from the single
--tg-chatid; every other chat is ignored.
- Create a bot with @BotFather and copy its token.
- Find your chat id (message @userinfobot).
- Run it:
export AWAKE_TG_TOKEN=123456:your-token-here
awake-cli --start 09:00 --end 17:00 --tg-chat 987654321| Command | Effect |
|---------|--------|
| /status | Current mode, state, last pulse, and next-action countdown |
| /pause | Freeze pulses immediately |
| /resume | Unfreeze and send a fresh pulse right away |
Run automatically every day (9am–5pm)
You don't schedule the hours in the OS — awake-cli already does that with
--start/--end (it sleeps at near-zero CPU outside the window). You only need
the OS to launch it once at login/boot, and it will manage the daily window
itself (and survive across days).
In every example below the tool runs --start 09:00 --end 17:00. Adjust the
times as you like. First find the full path to the installed command:
# macOS / Linux
which awake-cli
# Windows (PowerShell)
where.exe awake-cliWindows — Task Scheduler
Run once in a terminal (Command Prompt or PowerShell) to register a task that starts at every logon:
schtasks /create /tn "awake-cli" /sc onlogon /tr "cmd /c awake-cli --start 09:00 --end 17:00"Start it now without logging out: schtasks /run /tn "awake-cli"
Remove it later: schtasks /delete /tn "awake-cli" /f
If the task can't find
awake-cli, use the full path fromwhere.exe(e.g.cmd /c "%AppData%\npm\awake-cli.cmd" --start 09:00 --end 17:00).
macOS — launchd (LaunchAgent)
Create ~/Library/LaunchAgents/com.awake.cli.plist (replace the program path
with your which awake-cli result — Homebrew is usually /opt/homebrew/bin):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.awake.cli</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/awake-cli</string>
<string>--start</string><string>09:00</string>
<string>--end</string><string>17:00</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict>
</plist>Load it (starts now and at every login):
launchctl load -w ~/Library/LaunchAgents/com.awake.cli.plistStop/remove it: launchctl unload -w ~/Library/LaunchAgents/com.awake.cli.plist
macOS still needs Accessibility permission granted to whatever runs it (your terminal, or
node) for the keystroke to land.
Linux — systemd user service
Create ~/.config/systemd/user/awake.service (set ExecStart to your
which awake-cli path):
[Unit]
Description=awake-cli presence keeper
[Service]
ExecStart=%h/.npm-global/bin/awake-cli --start 09:00 --end 17:00
Environment=DISPLAY=:0
Restart=on-failure
[Install]
WantedBy=default.targetEnable it (starts now and at every login):
systemctl --user daemon-reload
systemctl --user enable --now awake.serviceStop/remove it: systemctl --user disable --now awake.service
Requires an X11 session;
xdotoolneedsDISPLAY(and sometimesXAUTHORITY) set, as shown above.
Example output
[09:00:01][awake-cli] v1.2.0 starting - pulse: F15 tap, every 30-75s (jittered).
[09:00:01][awake-cli] Mode: scheduled. Active daily 09:00-18:00. Status: Available.
[09:00:01][awake-cli] System Pulse Sent. Status: Available.
[09:01:04][awake-cli] System Pulse Sent. Status: Available.
[18:00:05][awake-cli] Outside operational window. Standby Mode... resuming 09:00 (in 15h 0m).Exit
Ctrl+C (SIGINT) or SIGTERM triggers a clean shutdown that cancels timers and
prints a goodbye line. Date-range mode also auto-exits when its window passes.
Development & testing
Zero-dependency test suite using the native Node.js test runner:
npm testIt covers scheduling state transitions, date-range math, arg parsing/validation, stealth jitter (with a deterministic injected RNG), and Telegram command parsing
- strict chat-id filtering (against a mocked
httpslayer — no network, no token). The OS pulse layer is verified by asserting the per-platform command (pulseCommand(platform)) rather than executing it, so tests never inject real input on your machine.
Release pipeline (continuous deployment)
A single command runs the whole release sequentially and aborts on the first test failure:
npm run release # or: bash release.sh [branch]It performs:
- Test —
npm test; if anything fails, the pipeline stops. - Git — stage all changes, commit
(
feat: upgrade presence profiles and remote control framework), push tomainon GitHub. - npm —
npm version patch, push the tag, thennpm publishto npmjs.com/package/awake-cli.
Prerequisites: bash, an authenticated git, and a logged-in npm
(npm whoami). On Windows, run it from Git Bash.
License
MIT
