- HTML 40.5%
- TypeScript 40%
- Rust 8.6%
- JavaScript 6.5%
- CSS 2.5%
- Other 1.9%
| client | ||
| server | ||
| .gitignore | ||
| .woodpecker.yml | ||
| install.sh | ||
| README.md | ||
| TODO.md | ||
TimeLens
TimeLens records the foreground application on a computer and presents usage totals in a web dashboard. This repository is a rewrite of the supplied archives with a Deno server and one cross-platform Rust client.
Structure
server/ Deno HTTP/WebSocket server and dashboard
src/ server, SQLite persistence, and API tests
public/ browser UI and API playground
client/ one Rust client crate
src/platform/ Linux, macOS, Windows, and BSD detectors
Cross.toml cross-rs configuration
The server preserves the original /v2/event collector protocol and dashboard endpoints. It stores data in SQLite, so local development needs no MySQL service.
Run the server
Requirements: Deno 2.2 or newer.
cd server
deno task test
deno task start
The dashboard is then available at http://localhost:4722. The default database is server/data/timelens.sqlite. For persistent deployments, set a stable admin secret:
ADMIN_TOKEN='replace-with-a-long-random-value' deno task start
New accounts use a chosen username, email, and password. Passwords must have at least eight characters with an uppercase letter, lowercase letter, number, and special character; common passwords are rejected. Users can enable authenticator app codes and register passkeys from the Account tab.
Account settings are split into General, 2FA, and Data tabs. Mutating settings requires a five-minute unlock: a fresh authenticator code when 2FA is enabled, or the current password otherwise. Account deletion requires two confirmations and removes the user's usage history and authentication credentials.
Supported environment variables are HOST, PORT, DATABASE_PATH,
ADMIN_TOKEN, WEBAUTHN_ORIGIN, and WEBAUTHN_RP_ID; see
server/.env.example. For a public deployment, serve TimeLens over HTTPS and set
the two WebAuthn values to the public origin and hostname. Passkeys also work on
plain HTTP when using localhost, as browsers treat it as a secure local context.
Run the client
Create an account in the dashboard, copy its API token, and place it in the platform's default token file:
- Linux/BSD:
~/.config/timelens/token - macOS:
~/Library/Application Support/Timelens/token - Windows:
%APPDATA%\Timelens\token
Then build and start the collector:
cd client
cargo run --release
To install a downloaded or locally built Unix binary for the current user:
./install.sh /path/to/timelens-client
This installs it as ~/.local/bin/timelens-client without root privileges and
starts it automatically for the current user. Linux uses a systemd user service
when available, macOS uses a LaunchAgent, and other Unix desktops use session
autostart. Set TIMELENS_INSTALL_DIR to use a different destination directory.
The client defaults to ws://127.0.0.1:4722/v2/event. Use TIMELENS_SERVER_URL=wss://example.com/v2/event for a deployed server. TIMELENS_API_TOKEN and TIMELENS_TOKEN_FILE can replace the token file defaults.
Application changes are reported immediately, with a checkpoint at least once per minute while the foreground application stays unchanged. To stop the daemon and remove its service, autostart entry, binary, local token, configuration, and logs:
./install.sh --remove
For a one-shot connection check in a headless environment:
TIMELENS_API_TOKEN='your-token' cargo run -- --once --app integration-test
Platform notes:
- Linux supports X11 through
xdotool. Wayland detection supports Hyprland (hyprctl), Sway (swaymsg), KDE Plasma 6 (kdotool), and modern GNOME via the standard AT-SPI accessibility bus. If GNOME's Focused Window D-Bus extension is installed, the client uses its more direct window-class API before AT-SPI. AT-SPI is also the fallback for other Wayland compositors. - macOS uses System Events and may request Accessibility permission.
- Windows uses the native foreground-window/process APIs and needs no helper program.
- BSD uses
xdotoolpluspsunder X11.
Cross-compile
Install cross and ensure Docker or Podman is available:
cargo install cross --git https://github.com/cross-rs/cross
cd client
./scripts/build-cross.sh
That script builds x86-64 Linux, ARM64 Linux, Windows GNU, and x86-64 FreeBSD targets. Apple does not permit its SDK to be redistributed in a cross image, so macOS artifacts must be built on macOS:
rustup target add x86_64-apple-darwin aarch64-apple-darwin
cargo build --locked --release --target x86_64-apple-darwin
cargo build --locked --release --target aarch64-apple-darwin
Checks
cd server && deno fmt --check deno.json src && deno task check && deno task test
cd client && cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test
Old archive inputs and extracted Python clients are intentionally excluded from Git.