Tracks online, active and task time in DSH, with a day/week/month dashboard, per-workspace and per-session breakdowns, and a read-only `timespan_stats` tool for agents.
Install
# from npm (prebuilt)
dsh plugin --profile web add @qwayo/dsh-timespan
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:qwayo/dsh-timespan
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
dsh-timespan is a DSH plugin that records and shows your online, active and task time in DSH.
Three kinds of time
- Online: all the time from when DSH starts until it exits, including time away from the computer.
- Active: time when the page is visible and focused, and you have interacted within the idle threshold — or the foreground session is running a task.
- Task: time from
turn/starttoturn/endfor one task, split into model requests, tool execution, waiting for the user, and other.
Scope: there is no separate "idle time" metric, and task time is not part of active time. When you first enable the plugin, only task time is backfilled; it never makes up online or active history.
What you see
- A permanent sidebar entry shows the duration you select (online by default) and today's ring; hovering for about 200 ms shows a tooltip.
- The day / week / month dashboard has four views: Overview, Trend, Details and Settings. The active headline, trend chart and heatmap can each expand into a full page (focus view); the trend page also shows time distribution and trend analysis.
- Workspace → session details shows active time, task time, last activity and the current timing state. You can switch the range between today, last 3 days, last week, last 30 days and all time; with all time, sessions load in batches.
- The read-only agent tool
timespan_stats: query by day, week, month or a custom date range in a conversation, using the same data as the dashboard. - Settings: interface language (Chinese by default, English available; affects this plugin's wording only), idle threshold (1–15 min), week start (Monday / Sunday), appearance and color palette (follows the system by default), number format (compact units by default, e.g.
2h 48m), whether to show subagent detail, and whether the sidebar shows status text and a permanent duration (online by default). - Export JSON / CSV, and import backups de-duplicated by ID. New exports use the
dsh-timespan-exportformat; olderchronoscope-exportbackups still import. Destructive actions such as clearing data ask for a second confirmation. - On first enable, task time is backfilled for existing historical sessions.
How it works
dsh-timespan is split in two: the Host runs in the background alongside DSH, and the Client is what you see on the page. The page only tells the Host what happened: whether the interface is open, whether the window is visible, and when a session starts and stops running a task. How long today counts, how long a week counts, how active time is decided — the Host computes all of it and writes the result to local storage. Nothing is uploaded.
After you refresh the page, it reads the results back from the Host. So the numbers in the dashboard and the answer timespan_stats gives in a conversation are always the same.
Install
Prerequisites: DSH installed (DSH Desktop, or any environment with a Web profile) and the plugin_manager tool available in the session. The Standard and Creator presets turn it on by default. The plugin has no third-party runtime dependencies and no build step; this repository is developed and tested on Node.js 24.16.0.
Install, update and uninstall all go through
plugin_manager. Do not edit the profile'spackage.jsonby hand and do not run pnpm yourself — it handles both and restores the previous state if anything fails.
Option 1: install from npm
The package is published to npm; this is the easiest route. Say this in a session:
Install the plugin @qwayo/dsh-timespan
plugin_manager fetches the latest version from the registry, installs and enables it. To pin a version, use @qwayo/dsh-timespan@0.1.1 instead. Restart DSH when it says a restart is needed.
Option 2: install from GitHub
The repository is hosted on GitHub; use this route when you want a specific branch or tag. Say this in a session:
Install the plugin github:qwayo/dsh-timespan
plugin_manager probes the repository first, then fetches, installs and enables it. Restart DSH when it says a restart is needed.
Option 3: install from a local directory
To change the source or develop locally, link the local directory into the current profile with link:; after a code change a restart is enough and no reinstall is needed:
Put this repository at a fixed local path, written
<repo-path>below (for exampleC:\path\to\dsh-timespanon Windows).Say this in a session:
Use plugin_manager to install
<repo-path>as a bundle in the current profile.Act on the return value:
application: appliedmeans it is live;restart-requiredor a restart hint means restart DSH and open the page again;failedreturns the error for the agent to investigate further.
Check the install
- A dsh-timespan entry appears in the left sidebar and shows today's online time by default; you can switch it to active or task time in Settings. Status text is off by default — turn on "Show sidebar status" in Settings to show idle, active or in task.
- A dsh-timespan section appears on the settings page.
- Ask the agent "use timespan_stats to check today's time" and it returns statistics.
- When needed, verify with
plugin_manager'slist_bundles/list_plugins: the bundle@qwayo/dsh-timespanand the plugin rowdsh-timespanare enabled. - Upgrading from the old
chrono-scopename: remove the old@local/chrono-scopebundle first, then install this directory as above. The storage domain is stillchrono_scope, so existing statistics and settings survive.
The agent can also call
plugin_managerdirectly:action: install_bundle target: <repo-path> or github:qwayo/dsh-timespanIf the agent asks for authorization during install, confirm once.
Installing is a pnpm run underneath. If the error says pnpm is unavailable, install pnpm first or point
pnpmCommandat it in the configuration.With HMR the plugin is live immediately; without it you get
restart-requiredand it takes effect after a restart.When an install fails,
plugin_managerrestores the profile'spackage.jsonandpnpm-lock.yamland leaves the error for the agent.Changes limited to this repository's source need no reinstall: restart DSH (or reload the plugin) to load the new modules.
Development and testing
npm test # Node's built-in test runner: domain statistics, period clipping, concurrent union/sum, backfill, restart recovery, settings/export/clear, client composition, the timespan_stats tool
npm run check # syntax check across all source and tests
npm run audit # quality gate: bundle manifest, identity strings, bilingual README, RPC contract table, ADR list and README assets
Tests use node:test and need no external framework. The repo has no dependencies and no build step, so CI never runs npm install; pushes to master and every pull request run all three commands above.
Project structure
dsh-timespan/
├─ package.json # npm package and DSH bundle manifest
├─ cordis.patch.yml # bundle Loader patch: inserts the dsh-timespan row
├─ index.js # Host entry: storage domain, heartbeat, session events, RPC, tool
├─ client.js # Client entry: sidebar, pages, presence, settings page
├─ icon.svg # plugin icon
├─ DESIGN.md # page design spec
├─ GLOSSARY.md # domain vocabulary
├─ README.md # Chinese README (default)
├─ README.en.md # this English README
├─ assets/readme/ # README artwork: *.svg sources and 2x *.png exports (the plugin market only takes raster)
├─ locale/
│ ├─ zh.json # Chinese display metadata
│ └─ en.json # English display metadata
├─ src/
│ ├─ domain/ # domain layer: no DSH runtime dependency, testable with a fake clock
│ │ ├─ domain-spec.js # chrono_scope v1 shape of the storageDomain (legacy key, keep)
│ │ ├─ dsh-timespan-domain.js # core service for online/active/task records and queries
│ │ ├─ periods.js # local day/week/month boundaries and trend buckets
│ │ ├─ duration-format.js # five number formats (incl. Chinese "2 小时 48 分")
│ │ ├─ settings.js # setting defaults and normalization
│ │ ├─ export.js # JSON/CSV serialization
│ │ └─ backfill.js # historical session backfill planning
│ └─ host/ # Host adapter layer
│ ├─ rpc.js # /api/dsh-timespan in-package private RPC
│ └─ tool.js # timespan_stats agent tool
├─ test/ # Node built-in test runner tests
├─ docs/adr/ # architecture decision records
└─ .scratch/ # archived tickets, not shipped with the plugin
Core files:
| File | Purpose |
|---|---|
index.js |
Host entry: opens the chrono_scope v1 storage domain (legacy key, kept compatible), registers the 30-second heartbeat, the session/event listener, the in-package RPC and the timespan_stats tool. |
client.js |
Client entry: the sidebar.panellist sidebar entry, the shell.overlay presence heartbeat, the main dashboard and the settings.section settings page. |
src/domain/dsh-timespan-domain.js |
The core of every business rule: online/active/task intervals, the four-part task breakdown, attribution, union/sum, queries and data operations. |
src/host/rpc.js |
The private channel between Client and Host: presence, queryStats, queryDailySeries, getSettings, setSettings, resetSettings, exportData, importData, clearData, getBackfillStatus, markBackfillRead, retryBackfill. |
src/host/tool.js |
Turns timespan_stats arguments into a queryStats query; it never computes a second set of numbers. |
package.json |
Declares the package name, version, exports and the published file list; dsh.bundle.patch points at cordis.patch.yml and dsh.client declares how the Web client loads it. |
The storage domain still uses
chrono_scopeas its persistent key so existing statistics and settings are not lost; it is a legacy name — the public project name is dsh-timespan.
The plugin market only accepts PNG / WebP / JPG screenshots and discards SVG, so a set of 2x raster copies lives here for it to pick up; the artwork in the body still uses SVG. Re-export the same-named PNG after editing an SVG.
Related documents
- README.md: the Chinese original of this page, kept in step section by section.
- DESIGN.md: page design spec (Chinese).
- GLOSSARY.md: domain vocabulary — online, active, task, actual occupied, accumulated time (Chinese).
- Architecture decision records (docs/adr/), all in Chinese:
- 0001 Recording architecture: how online, active and task time are recorded.
- 0002 Period clipping and concurrency: period clipping and concurrency semantics.
- 0003 Historical backfill: backfilling task time from history.
- 0004 The timespan_stats tool: the
timespan_statsagent tool. - 0005 Heatmap week grid: the year heatmap turned into a week grid, plus Chinese interface wording.
- 0006 Info overlay: the info overlay moved back to hover, triggered by focus.
- 0007 Rename to dsh-timespan: the rename scope and the compatibility decisions for the storage domain and backup format.
- 0008 Interface language: interface language as a plugin setting, Chinese by default with English available.
- 0009 Quality gates and release flow: the scope and limits of CI, the audit invariants, and the manual release flow.
- 0010 Package renamed to @qwayo/dsh-timespan: the package-name migration before going public and publishing to npm, and what installed users must do.
Links
More in this category
bowenliang123/dsh-context★ 4797
DSH context insight panel: Context dashboard + /context command + Context browser — one-stop context lifecycle management with categorized composition, content details, evolution trends, compaction/injection events, and stats.
Han-1413141/dsh-cost-meter★ 661
Per-session and daily API cost, budget with usage %, official balance, history dashboard, and one-click official price sync with peak/off-peak pricing.
wssfk12138/dsh-damage-pulse★ 289
Tracks DeepSeek token usage, per-call and session costs, and account balance with cache-aware charge animations in the DSH Web UI.
zh667/TokenLedger★ 203
Sidebar usage panel that attributes tokens to the relay site that served each request, read from your existing provider config: today/month/all-time totals, per-site and per-model breakdowns, a year activity heatmap, and New API / Sub2API / DeepSeek balances.
Ychris12138/dsh-usage-stats★ 188
Multi-provider usage dashboard with provider/model token breakdowns, calendar drill-downs, account balances, and OpenCode Go / Z.ai subscription quota tracking.
PolinniZhong/dsh-personal-center★ 115
Personal center for DeepSeek Harness: cross-session usage statistics with per-provider and per-model breakdown (auto-discovers configured models), per-model cost estimation, global custom instructions, a data-driven desktop pet with bitmap & vector skins, and a conversation status overview, all local and offline.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.