Skip to content
 
 

Repository files navigation

opencode-wakatime

npm version npm downloads CI License: MIT

WakaTime plugin for OpenCode V2 - Track your AI coding activity, lines of code, and time spent.

Inspired by claude-code-wakatime.

Tip

Also check out codex-wakatime for OpenAI Codex CLI!

Important

This version of the plugin targets the V2 plugin API (Plugin.define from @opencode-ai/plugin@next). For the V1 plugin API, use opencode-wakatime@1.x.

Features

  • Automatic CLI management - Downloads and updates wakatime-cli automatically
  • Detailed file tracking - Tracks file reads and modifications (edit, write, apply_patch)
  • AI coding metrics - Sends --ai-line-changes for WakaTime AI coding analytics
  • Rate-limited heartbeats - 1 per minute per project to avoid API spam
  • Session lifecycle - Sends final heartbeat on session idle/end

Prerequisites

WakaTime API Key

Ensure you have a WakaTime API key configured in ~/.wakatime.cfg (or $WAKATIME_HOME/.wakatime.cfg when WAKATIME_HOME is set):

[settings]
api_key = waka_your_api_key_here

You can get your API key from WakaTime Settings.

WakaTime CLI (Optional)

In case of manual install, the plugin will automatically download wakatime-cli if not found. However, you can also install it yourself:

macOS:

brew install wakatime-cli

Other platforms: Download from WakaTime releases.

Installation

Via opencode config (recommended)

opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "plugins": ["opencode-wakatime"]
}

Note the V2 config key is plugins (the V1 key was plugin).

Manually via npm

npm i -g opencode-wakatime
opencode-wakatime --install

This installs the plugin to ~/.config/opencode/plugins/wakatime.js.

To update, run the same commands again.

From source

git clone https://github.com/angristan/opencode-wakatime
cd opencode-wakatime
npm install && npm run build
node bin/cli.js --install

The plugin will be automatically loaded by OpenCode - no configuration needed.

How It Works

The plugin hooks into OpenCode V2's plugin API:

flowchart TB
    subgraph OpenCode["OpenCode V2"]
        A[Tool Execution<br/>read, edit, write, apply_patch] --> H1[tool.execute.after hook]
        B[Session Events<br/>idle, deleted] --> H2[event stream]
    end

    subgraph Plugin["opencode-wakatime Plugin"]
        H1 --> P1[Extract File Changes<br/>path, additions, deletions]
        P1 --> Q[Heartbeat Queue]

        Q --> P2[Process Queue]
        P2 --> R[Rate Limiter<br/>1 per minute per project]

        H2 --> P3[Flush Final<br/>Heartbeat]
        P3 --> R
    end

    subgraph WakaTime["WakaTime"]
        R --> CLI[wakatime-cli]
        CLI --> API[WakaTime API]
        API --> D[Dashboard<br/>AI Coding Metrics]
    end

Loading

Hooks Used

Hook Purpose
tool.execute.after Tracks completed tool executions (edit, write, read, apply_patch)
event stream Tracks session.idle / session.deleted for final heartbeats

Tool Tracking

Tool Data Extracted
read File path (from input path or result display.path)
edit File path, additions, deletions (from result files metadata or input path)
write File path (from input path; new-file flag when exists metadata is present)
apply_patch File paths and additions/deletions per file (files metadata)

Tool paths are read from the tool input (path/filePath) because current V2 builds return minimal result metadata for read and write. Line counts are taken from result metadata when available (files entries for edit/apply_patch).

See Migration notes and limitations for tools that were removed in V2 and can no longer be tracked.

Heartbeat Data

Each heartbeat includes:

  • Entity: File path being worked on
  • Project folder: Session working directory
  • AI line changes: Net lines added/removed (additions - deletions)
  • Category: "ai coding"
  • Plugin identifier: opencode-<client>/<version> opencode-wakatime/<version> (e.g. opencode-cli/0.0.0-next-17394 opencode-wakatime/2.0.0)

Files

By default, plugin files are stored in ~/.wakatime/. When WAKATIME_HOME is set, the same files are stored in $WAKATIME_HOME/.

File Purpose
opencode.log Debug logs (enabled via debug=true in ~/.wakatime.cfg)
opencode-{hash}.json Per-project state (last heartbeat timestamp)
opencode-cli-state.json CLI version tracking
wakatime-cli-* Auto-downloaded CLI binary

Migration notes and limitations

This section documents what changed when porting the plugin from the V1 to the V2 plugin API, and which V1 features could not be carried over.

V2 API changes

V1 V2
export default (ctx) => hooks Plugin.define({ id, setup })
event hook (message.part.updated) ctx.tool.hook("execute.after") for tools, ctx.event.subscribe() for the event stream
chat.message hook Removed from the V2 plugin API; heartbeat processing now runs directly on tool completion
ctx.project.worktree / ctx.worktree Removed from the context; the session directory is fetched via ctx.session.get()
OpenCode version via internal HTTP client (/global/health) Provided by the context as ctx.app.version (no more version cache file)
plugin config key plugins config key
~/.config/opencode/plugin/ ~/.config/opencode/plugins/ (auto-discovered)

Features that could not be ported

  • batch tool tracking - The V1 batch tool executed child tools in parallel and each child emitted message.part.updated events that the plugin tracked. In V2 the batch tool was replaced by the CodeMode execute tool, which only runs MCP tools and reports child calls as { tool, status, input } in its result metadata — no file paths or diffs. File-level tracking is therefore not possible for execute; it is skipped.

  • multiedit tool tracking - The multiedit tool no longer exists in V2; multi-file edits go through apply_patch, which is fully tracked.

  • patch tool tracking - Renamed to apply_patch in V2; it now returns per-file additions/deletions in result metadata, which is tracked.

  • chat.message activity trigger - The V1 chat.message hook fired on chat activity to flush queued heartbeats. The V2 plugin API has no equivalent hook, so heartbeats are flushed directly after each tracked tool execution and on session.idle / session.deleted. Behavior is equivalent: heartbeats are sent at most once per minute per project, and always flushed when a session ends.

  • Blocking hooks - Tool hooks run inside the server's tool execution path. The plugin therefore keeps execute.after fully synchronous and runs all async work (session lookup, heartbeat CLI spawns) in background tasks, so a slow wakatime-cli or unreachable session API can never stall tool execution or freeze the client (especially when the server is embedded in the TUI process).

Development

# Install dependencies
npm install

# Type check
npm run typecheck

# Build
npm run build

Troubleshooting

Plugin not loading

  1. Check your config file syntax (opencode.jsonc)
  2. Verify the plugin path is correct
  3. Check logs at ~/.wakatime/opencode.log

Heartbeats not sending

  1. Verify API key in ~/.wakatime.cfg
  2. Check if wakatime-cli is working: wakatime-cli --version
  3. Enable debug logging and check ~/.wakatime/opencode.log (or $WAKATIME_HOME/opencode.log when set)

CLI not downloading

  1. Check network connectivity
  2. Verify write permissions to ~/.wakatime/ (or $WAKATIME_HOME/ when set)
  3. Manually install: brew install wakatime-cli

License

MIT

About

Track Opencode v2 usage with Wakatime

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages