deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:dingyi222666/dsh-wakatime
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
English | 中文
WakaTime plugin for DeepSeek Harness (dsh) — track your AI coding activity, lines of code, and time spent. Adapted from opencode-wakatime to dsh's plugin model.
# Install from npm (requires dsh >= 0.1.3-alpha.2)
dsh plugin --profile web add @dingyi222666/dsh-wakatime
# Restart dsh web for it to take effect
dsh web
The plugin works in any profile that runs the agent loop — web, headless, acp, sdk, and the Desktop app's desktop profile — install it into each profile you use:
dsh plugin --profile headless add @dingyi222666/dsh-wakatime
The DeepSeek Harness Desktop application is an Electron shell around the same Web
host, but it exclusively owns a separate profile ($DSH_HOME/profiles/desktop)
and its own package state. Install the plugin there with the CLI bundled inside
the app — an npm-installed dsh cannot mutate the Desktop profile:
# 1. Launch Desktop once so it initializes profiles/desktop, then fully quit it.
# 2. Run the bundled CLI (macOS path shown; Windows uses resources\runtime\cli\bin\dsh.cmd):
"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" \
plugin --profile desktop add @dingyi222666/dsh-wakatime
# 3. Reopen Desktop; the bundle patch applies on the next boot.
The same command manages updates (add @dingyi222666/dsh-wakatime@latest),
list, and remove <package>, and it keeps the shared Desktop profile lock and
compatibility checks intact. Because both the Desktop host and its plugins run in
the same Electron Node process, the tracked events and heartbeats are identical to
the Web profile.
git clone https://github.com/dingyi222666/dsh-wakatime
cd dsh-wakatime
pnpm install && pnpm run build
dsh plugin --profile web add .
dsh web
Notes:
dsh plugin behaves like adding a dependency to your profile. A bundle plugin is loaded once its full package name appears in the profile's dsh.profile.bundles list (added automatically); the bundle patch (cordis.patch.yml) applies on the next boot.node --import tsx/esm apps/cli/src/bin.ts plugin --profile web add @dingyi222666/dsh-wakatime).The plugin works out of the box. To override behavior, add a row with the
same id (wakatime) in your profile's user patch layer
($DSH_HOME/profiles/<name>/cordis.patch.yml) or via --patch:
- id: wakatime
config:
heartbeatIntervalMs: 120000 # rate limit per project (default 60000)
debug: true # force DEBUG logging (default: ~/.wakatime.cfg debug=true)
client: web # client qualifier in the --plugin string (default "dsh")
timeoutMs: 45000 # heartbeat CLI timeout (default 30000)
All fields are optional and validated by a schemastery schema at load.
wakatime-cli automatically, or uses a global install (brew install wakatime-cli)edit, write, read, read_image, and str_replace_editor (view/create/str_replace/insert)tool/result meta: resolved (sandbox-aware) entity paths and exact diff hunks win over raw call arguments when presentwrite result's operation stamp (create/update) distinguishes a created file (content lines charged) from an unchanged overwrite (zero line changes, heartbeat only)--ai-line-changes for WakaTime's AI coding analytics, computed exactly from the fs tools' diff hunks (context lines excluded)agent/status transitions and the agent/assistant-stream firehose heartbeat the current file in near real time while a long turn streams, instead of waiting for the durable settlementdsh --profile headless runs still report their activitywakatime-cli invocation via --extra-heartbeats@deepseek-ai/* peers the host already providesEnsure 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
Get your API key from WakaTime Settings.
The plugin downloads wakatime-cli automatically when missing. To install it yourself:
brew install wakatime-cli
or download from WakaTime releases.
The plugin subscribes to dsh's session event firehose (session/event):
flowchart TB
subgraph dsh["DeepSeek Harness"]
A[Agent Loop] --> B[tool/call + tool/result events<br/>(meta: resolved path + diff hunks)]
C[Live agent events<br/>agent/status, agent/assistant-stream] --> D[Activity]
C2[Chat Activity<br/>user/message, assistant/message, assistant/attempt] --> D
B --> D
D --> E[Session Events<br/>turn/end, session/disposed]
end
subgraph Plugin["dsh-wakatime"]
B --> F[Join callId: extract file<br/>path + line changes from<br/>meta and fs diff hunks]
F --> G[Per-project pending<br/>changes + last entity]
C --> H[Rate-limited<br/>heartbeat batch]
G --> H
E --> I[Final force flush]
H --> J[wakatime-cli<br/>--ai-line-changes<br/>--extra-heartbeats]
I --> J
end
tool/call records the tool name and parsed arguments by callId; tool/result
matches it back and reads the fs tools' durable meta payload — resolved
entity paths (read, read_image), diff hunks (edit, write), and the
write outcome stamp (dsh 0.1.7-alpha.1) — for exact per-hunk line counts,
falling back to the call arguments when a host attaches no meta (write
content, str_replace_editor strings). A write update with an empty hunk
list is charged zero lines; a create is charged its content lines. Failed
results — including the synthetic recovery closers agent-loop records for
skipped calls when a step fails (dsh 0.2.0) — are never charged.~/.wakatime/dsh-wakatime/), on chat activity, tool results, committed model
settlements (including message-less assistant/attempt records in dsh
0.1.3-alpha.1), live agent activity (agent/status, agent/assistant-stream),
turn boundaries, session disposal, and plugin teardown.--plugin tag reports Deepseek Harness[-<client>]/<dsh version> dsh-wakatime/<version>.pnpm install
pnpm run typecheck # tsc --noEmit
pnpm run build # declarations into lib/types + tsdown bundle lib/index.js
pnpm test # vitest: changes, state, heartbeat, plugin wiring
Layout:
src/index.ts — plugin entry (name / Config / apply) and event wiringsrc/config.ts — schemastery Config schema, defaults, --plugin tagsrc/changes.ts — tool events → file changes, diff line countingsrc/state.ts — per-project rate limitingsrc/heartbeat.ts — wakatime-cli invocation, batching, flushingsrc/cli.ts — wakatime-cli discovery/download/updatesrc/paths.ts, src/logger.ts — WakaTime paths and file loggingtests/ — unit tests plus an integration test that drives the plugin over a
real cordis Contextfile_path arguments unless the tool/result meta carries a
resolved absolute path (dsh 0.1.3-alpha.1 fs tools do); paths the sandbox
resolves differently may land as project-relative entities.bash commands are not attributed to files (they can touch anything).--plugin tag is unknown when the
@deepseek-ai/dsh package cannot be resolved from the plugin's location
(e.g. an npm install without the dev dependency present).@deepseek-ai/dsh-session/@deepseek-ai/dsh-agent peer ranges start at
0.1.3-alpha.1; older hosts run the tracking paths but get no live agent
activity heartbeats.MIT — ported logic from opencode-wakatime (MIT).
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。