id = "wakatime" name = "WakaTime" homepage = "https://wakatime.com" description = "Command line interface used by all WakaTime text editor plugins." icon = "SimpleIcons:wakatime" # wakatime-cli is the binary every editor plugin downloads and runs; `wakatime` # is the name the older Python package installed and the one still typed by # hand. Both are listed. executables = ["wakatime-cli", "wakatime"] [dotfiles] # USAGE.md in wakatime/wakatime-cli: "$WAKATIME_HOME/.wakatime.cfg", with # $WAKATIME_HOME defaulting to the user's home directory. It is an INI file # whose main section is [settings]; the same page documents [projectmap], # [project_api_key], [api_urls] and [git] beside it. # # A literal dotfile in the home directory — the docs give no XDG or %APPDATA% # spelling — so it is written as such. paths = ["~/.wakatime.cfg"] # The heartbeat database, the offline queue and the log wakatime-cli writes # beside the config are state, not configuration. exclude = [ "~/.wakatime/", "~/.wakatime.bdb", "~/.wakatime.db", "~/.wakatime.log", ] # .wakatime.cfg is not a whole-file secret: the exclusions, the project map and # the privacy switches in it are worth carrying. Only the key is lifted out. secret = [] # A one-shot process: each heartbeat is a fresh run that reads the file and # exits. side_effect = false # USAGE.md's settings table: "api_key | Your wakatime api key". One prefix # covers both spellings an INI file has for it, `api_key = …` and `api_key=…`. # It also reaches api_key_vault_cmd, the alternative that names a shell command # to fetch the key instead of storing it — that line is not a credential, but # over-reaching a prefix costs a consumer nothing while missing one would sync # the key in the clear. # # The [project_api_key] section, from the same page, maps a directory to a # second key. Its left-hand sides are arbitrary paths, so no prefix can name # those lines, and a consumer that scans content is the only thing that catches # them. Said here rather than papered over with a rule that would not run. [[dotfiles.secret_paths]] file = "~/.wakatime.cfg" match = { prefix = ["api_key"] } # Same table: "hostname | Optional name of local machine. By default, # auto-detects the local machine's hostname". It names this machine and nothing # else, and wakatime.com groups a user's coding time by it, so the value is # worth keeping for the device it belongs to rather than carried to the next # one. [[dotfiles.machine_lines]] file = "~/.wakatime.cfg" match = { prefix = ["hostname"] } scope = "backup" [commands] format = 1 label = "Send a heartbeat" description = "Log one heartbeat for a file, domain, URL or app, or print today's total. Config-file editing, extra-heartbeats on stdin and the deprecated flag spellings are left out." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = false, short_bundles = false } [[commands.source]] id = "source" kind = "help" url = "https://raw.githubusercontent.com/wakatime/wakatime-cli/HEAD/cmd/root.go" revision = "HEAD 2026-10-27" evidence = """ Flags (cobra names, used as --entity --entity-type --project --language --category --write --plugin --config --disable-offline --verbose --today): flags.String("alternate-project", "", "Optional alternate project name. Auto-detected project takes priority.") "category", "Category of this heartbeat activity. Can be \\"coding\\", \\"ai coding\\","+ "entity", "Absolute path to file for the heartbeat. Can also be a url, domain or app when --entity-type is not file.", "entity-type", "Entity type for this heartbeat. Can be \\"file\\", \\"domain\\", \\"url\\", or \\"app\\". Defaults to \\"file\\".", flags.String("language", "", "Optional language name. If valid, takes priority over auto-detected language.") flags.String("plugin", "", "Optional text editor plugin name and version for User-Agent header.") flags.String("project", "", "Override auto-detected project."+ flags.Float64("time", 0, "Optional floating-point unix epoch timestamp. Uses current time by default.") flags.Bool("today", false, "Prints dashboard time for today, then exits.") flags.Bool("verbose", false, "Turns on debug messages in log file, and sends diagnostics if a crash occurs.") flags.Bool("version", false, "Prints the wakatime-cli version number, then exits.") flags.Bool("write", false, "When set, tells api this heartbeat was triggered from writing to a file.") flags.String("key", "", "Your wakatime api key; uses api_key from the config file by default.") flags.String("config", "", "Optional config file. flags.Bool("disable-offline", false, "Disables offline time logging instead of queuing logged time.") """ [[commands.field]] id = "entity" label = "Entity" description = "Absolute path to a file, or a URL, domain or app when the type is not file." type = "string" option = ["--entity"] sources = ["source"] [[commands.field]] id = "entity_type" label = "Entity type" type = "enum" choices = [{ value = "file", label = "File" }, { value = "domain", label = "Domain" }, { value = "url", label = "URL" }, { value = "app", label = "App" }] option = ["--entity-type"] sources = ["source"] [[commands.field]] id = "project" label = "Project" description = "Override the auto-detected project." type = "string" option = ["--project"] sources = ["source"] [[commands.field]] id = "language" label = "Language" type = "string" option = ["--language"] sources = ["source"] [[commands.field]] id = "category" label = "Category" type = "string" option = ["--category"] suggestions = [{ value = "coding", label = "Coding" }, { value = "debugging", label = "Debugging" }, { value = "building", label = "Building" }, { value = "code reviewing", label = "Code reviewing" }, { value = "writing docs", label = "Writing docs" }] sources = ["source"] [[commands.field]] id = "write" label = "Triggered by a write" type = "boolean" option = ["--write"] sources = ["source"] [[commands.field]] id = "plugin" label = "Plugin name and version" type = "string" option = ["--plugin"] sources = ["source"] [[commands.field]] id = "config" label = "Config file" type = "path" path = { kind = "file", role = "input" } option = ["--config"] sources = ["source"] [[commands.field]] id = "disable_offline" label = "Disable offline queue" type = "boolean" option = ["--disable-offline"] sources = ["source"] [[commands.field]] id = "verbose" label = "Verbose logging" type = "boolean" option = ["--verbose"] sources = ["source"] [[commands.field]] id = "today" label = "Print today's time" type = "boolean" option = ["--today"] sources = ["source"] [[commands.task]] id = "heartbeat" label = "Send a file heartbeat" fields = ["entity", "project", "language", "write", "plugin"] required = ["entity"] [[commands.task]] id = "today" label = "Show today's time" fields = ["today"] required = ["today"] set = { today = [true] } [[commands.group]] id = "basic" label = "Basic" fields = ["entity", "entity_type", "project", "language", "category", "write", "today"] [[commands.group]] id = "advanced" label = "Advanced" fields = ["plugin", "config", "disable_offline", "verbose"]