DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-working-activity

Working Activity

实时模型工作状态行:俏皮文案、正在运行的工具、回合耗时——适用于 TUI、Web UI 和桌面 GUI

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-working-activity@0.6.0
README兼容性版本

兼容性与来源证明

Working Activity 以 dsh-working-activity 发布,当前版本为 0.6.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/11/4

版本

0.6.0stable
2026/10/18
0.5.1stable
2026/9/26
0.5.0stable
2026/9/26
查看其余 6 个版本收起版本
0.4.0stable
2026/8/30
0.3.3stable
2026/8/20
0.3.2stable
2026/8/19
0.3.0stable
2026/8/19
0.2.6stable
2026/8/16
0.2.5stable
2026/8/16
最新版
0.6.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
584.7 kB
文件数
82
Surface
web
许可证
BSD-3-Clause
发布源
npm
GitHub
★ 0
周下载
14,766
安全扫描
✓ v0.6.0 扫描通过
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

README

dsh-working-activity

English | 中文

A live working-status line for DeepSeek Harness (DSH). While an agent works, the plugin folds the session's durable event stream and live model output into one line: the current phase copy, the tool that is actually running, elapsed time, and a turn-end summary.

The same line is rendered on every surface that composes the plugin: the terminal UI (dsh-tui), the browser Web UI, and the desktop GUI. The browser and desktop surfaces read a session projection; nothing is appended to the session log for them.

Packagedsh-working-activity
HostDSH 0.1.0-rc.6 through 0.2.1-rc.2 (see Compatibility)
SurfacesTUI · Web UI · desktop GUI
Wire transportSession projection workingActivity; optional ignorable plugin:working-activity/status records
RuntimeNode ^22.19 || >=24
LicenseBSD-3-Clause

Contents

  • Features
  • How it works
  • Requirements
  • Installation
    • TUI
    • Web UI
    • Desktop GUI
  • Configuration
  • Projection contract
  • Session-record contract
  • Compatibility
  • Architecture
  • Development
  • Troubleshooting
  • Privacy and security
  • License

Features

  • Phase-aware status line. The line moves through waiting → thinking → tool → done. Each phase has its own copy, its own rotation cadence, and its own elapsed formatting; settled phases carry a fixed summary rather than a counter.
  • Real tool activity. A running tool is rendered as verb + argument detail + elapsed (跑个命令 npm test · 12s). Results are paired with calls by exact call id; failed tools get the failure copy and a ✗ marker.
  • Turn summary. On turn/end the line becomes 搞定 ✓ · 4 工具 · 想12s 干11s — tools completed, thinking time, and working time — and pins the last tool fragment briefly.
  • Live self-narration. With narrate on (the default), the plugin adds one short system-prompt contract asking the model to write a ⏵ … line at the start of each step. The line is surfaced live in the status line while the durable message keeps it in the transcript.
  • Bilingual, feature-flagged copy. Chinese and English pools, day/night variants, long-thinking tiers, weekend and holiday copy, rare eggs, tool combos, model-switch quips, and failure copy are each switchable. phrases: false or mode: minimal renders plain functional labels.
  • Non-invasive by construction. The plugin registers no tools, appends no surface events, and never enters derived model history. Its only prompt contribution is the optional narration contract.
  • Optional invariant companion. ./invariant validates this package's own activity snapshots — both the legacy activity/status event and the current plugin:working-activity/status record — checking the phase vocabulary, non-empty line, and finite non-negative metrics for loaded sessions and every append thereafter.
  • One fold, three surfaces. The node half owns the state machine; the TUI, Web UI, and GUI only render the projected value. No surface re-implements phase logic.

How it works

The node half keeps one ActivityTracker per session. It is fed from three inputs:

  1. Durable session events — turn/start, step/start, assistant/message, tool/call, tool/result, turn/end, assistant/attempt, model/selection, compaction and approval/retry signals.
  2. Live assistant-stream frames — agent/assistant-stream (start / chunk / end), which carry streamed deltas, the first-token instant, and the ⏵ narration on the current host line.
  3. Agent status — agent/status (idle / running).

The tracker renders a plain-text line and exposes the same value in two directions:

  • Projection — a workingActivity session projection folds the durable log and is shipped to clients. This is the transport for the TUI, Web UI, and GUI.
  • Durable records — with publish: true, the rendered snapshot is also appended as a log-only record for consumers that replay the session log. On DSH 0.2.x this is an ignorable plugin:working-activity/status record; older corridors use the legacy activity/status event.
PhaseEntered whenExample line
waitingA turn is open and the model has not produced a token yet等待模型响应 · 总3s
thinkingA live token or reasoning delta arrived嗯…让我捋捋 · 总12s
toolA tool/call is pending its result跑个命令 npm test · 12s
doneThe turn closed搞定 ✓ · 4 工具 · 想12s 干11s
idleNo turn is active(nothing rendered)

Requirements

  • A DSH profile that composes the agent loop and a surface (TUI, Web UI, or GUI).
  • Node ^22.19 || >=24.
  • pnpm is used by the official CLI when installing profile plugins.

Installation

The package is a self-mounting bundle. It declares dsh.bundle.patch (cordis.patch.yml), and the official CLI both installs it and appends it to the profile's bundle layer stack. At boot, the bundle patch inserts the working-activity row into the composition tree; no manual mount is required.

dsh plugin --profile <profile> add dsh-working-activity

To change a value, override the row's config by id in the profile's user layer ($DSH_HOME/profiles/<profile>/cordis.patch.yml). Do not insert a second row with the same id.

- id: working-activity
  config:
    tickMs: 250
    publishIntervalMs: 500

Check the composed tree:

dsh --profile <profile> --dump-config

TUI

TUI support ships with dsh-tui. dsh-tui depends on this package, and its profile mounts it through @deepseek-harness-tui/dsh-tui/working-activity (a re-export that pins publish: false); the working line is rendered from the workingActivity projection. dsh-tui also reuses the package's ./frames presets and ./config parser for its frame picker and ~/.dsh-tui/working-activity.json settings.

Install dsh-tui into the profile; this plugin arrives as its dependency and must not be added a second time to the same profile:

dsh plugin --profile <profile> add @deepseek-harness-tui/dsh-tui
dsh --profile <profile>

A host that composes this package directly can still use it standalone; when it provides ctx.tuiPrompt, the ${activity} template value is registered and can be opted into with:

- id: tui
  config:
    theme:
      leftPrompt: '${cwd}${git/worktree}${activity}${model}${context}'

The current DSH line does not compose tuiPrompt; on that line the projection is the only TUI transport, and this template value is inert.

Web UI

Install into a profile that composes the Web client, then boot that profile (the shipped web profile can also be booted directly with dsh web):

dsh plugin --profile <profile> add dsh-working-activity
dsh --profile <profile>

The browser half is a client bundle (lib/client.js, published in the package). The host's client-module loader scans loader entries for dsh.client declarations and serves the bundle to the shell. The bundle registers one entry on conversation.input.dock — id activity, order 15 — as a single dim row above the composer:

  • phase-colored breathing marker, the host-composed line, and the turn's tool count;
  • nothing rendered before the first value or while the phase is idle;
  • the elapsed segment re-ticks locally every second while the value is live, because the projection itself changes only when a committed event folds.

The package declares the client cohort it uses:

"dsh": {
  "bundle": { "patch": "./cordis.patch.yml" },
  "client": {
    "platform": "web",
    "inject": [
      "@deepseek-ai/dsh-client-ui-conversation",
      "@deepseek-ai/dsh-client-ui-renderer",
      "@deepseek-ai/dsh-client-ui-session"
    ]
  }
}

dsh.client.inject lists boot rows (package dependencies that must arrive first), not Cordis services. The client plugin's own inject export is ['slots']. @deepseek-ai/dsh-client-ui-slots is a shell seed, not a boot row, so it is not listed in dsh.client.inject.

Desktop GUI

The desktop GUI (deepseek-harness-desktop, Tauri) shares the Web client entry: the same platform: "web" declaration, the same conversation.input.dock seat, the same useProjection('workingActivity') read, and the same session projection on the host. The plugin runs inside the kernel Web client (React 18.3.1 on the current line), not the GUI host's React tree; the react peer range (^18.2.0 || ^19.0.0) covers both, so a React 19 host does not force a second React copy into the bundle.

Requirements on the GUI side are the same as the Web UI: compose the three boot rows above and expose react/jsx-runtime in the shell's module seed table. See docs/gui-compatibility.md for the verified contract, evidence, and known limits.

Configuration

All keys are optional; the schema defaults below apply. Override them on the working-activity row in the profile's user layer.

KeyTypeDefaultMeaning
phrasesbooleantruePlayful copy pool. false renders plain functional labels. mode: minimal turns it off unless set explicitly.
publishbooleanfalseAppend a log-only working-activity record for consumers that replay the session log. On DSH 0.2.x the record is ignorable (plugin:working-activity/status) and does not affect resume; older corridors fall back to the legacy activity/status event. The first-party surfaces read the projection and do not need it. See Session-record contract.
tickMsnumber500Status render tick, in ms (100–5000, step 50). Live phases wake on their own schedule, capped by this value.
publishIntervalMsnumber2000Minimum interval between published events while the line is stable (500–30000, step 500).
detailLimitnumber40Maximum displayed detail length for paths, commands, and patterns (8–120).
customActionsobject{}Tool-name → action-copy pools, matched case-insensitively. Example: {"my_deploy": ["部署一下", "上线中"]}.
narratebooleantrueInject the ⏵ self-narration contract into the system prompt and surface the extracted line. Set false for a purely event-derived line.
lang'auto' | 'zh' | 'en''auto'Copy language. auto resolves DSH_TUI_LANG → ~/.dsh-tui/lang.json → OS locale → zh.
framesstring'moon8'Frame preset name. Informational for UI consumers; resolves the persisted frame choice itself.

Feature flags accepted by features and honoured by the tracker:

phrases, rareEggs, nightPhrases, weekend, holidays, combo, failPhrases, modelQuips, continuePhrases.

Projection contract

The projection key is workingActivity. It is registered when the host composes the sessionProjections service; a profile without a projection registry skips it without error.

The DSH 0.2.x definition contract:

FieldMeaning
key'workingActivity'
stateSchemaValidates the persisted fold state before it seeds a fold.
stateVersionPersisted-cache invalidation version; bump when the snapshot shape or fold semantics change.
init(header, inheritedEventCount)Initial state for the empty log.
apply(state, event)Pure transition. Returns the same reference for events this unit does not model, so the host performs no downstream work.
wire.viewSchemaValidates the client-facing value before it leaves the host.
wire.view(state)Renders the whole client value.

The same definition object also carries the older registry spellings — top-level schema, viewSchema, view, and a zero-argument init — so one object registers on the 0.1.0-rc.6, 0.1.2-alpha.2, 0.1.7-rc.2, and 0.2.x registries without a version probe. stateOf(session, key) is used on hosts that expose it to overlay live-only facts (the current ⏵ narration and the first-token instant) onto the folded value; hosts without it fall back to the narration carried by settled messages.

The client-facing value:

interface WorkingActivityView {
  phase: 'idle' | 'waiting' | 'thinking' | 'tool' | 'done'
  line: string            // the line as the host rendered it
  live: boolean           // a live phase whose elapsed text should tick
  label?: string          // current tool action or stage label
  detail?: string         // path / command / pattern fragment
  phrase?: string         // current playful phrase or ⏵ narration
  toolCount: number       // tools completed this turn
  phaseStartedAt: number  // epoch ms the current phase began
  turnStartedAt: number   // epoch ms the current turn began (0 when idle)
  updatedAt: number       // timestamp of the last folded event
  lang: 'zh' | 'en'       // language `line` was rendered in
}

Because the projection is event-driven, line can be older than the wall clock between folds. The wire value carries the timestamps so a client can re-tick the one moving segment; the Web and GUI halves do exactly that, and fall back to the host's text when the segment shape is unknown.

Read the value from a client plugin with the session standard kit:

const activity = useProjection('workingActivity')

Session-record contract

publish: true appends a log-only working-activity record for consumers that replay the session log. It is off by default: the first-party TUI, Web UI, and GUI read the projection, and appending to the shared log is only useful to a replaying consumer.

DSH 0.2.x (0.2.0-rc.2 / 0.2.1-rc.2). The write uses session.appendPluginRecord() with the record type plugin:working-activity/status. The host marks the record ignorable: true; an unrecognized record is retained and skipped, so it does not make the session unresumable.

Older corridors (0.1.0-rc.6 through 0.1.7-rc.2). appendPluginRecord does not exist there, so the plugin falls back to the legacy activity/status session event appended through session.append(). That generation has no ignorable marker, so at load the plugin registers the type in every reachable dsh-session copy — including the copy the persistence validator resolves — to keep resume and persistence reads working. Registration is unconditional and idempotent, and also covers logs written by an earlier publish: true configuration. A residual risk remains if a reader resolves a dsh-session copy the plugin cannot reach from its anchors; the first-party surfaces do not need publishing.

The payload is identical for both spellings:

{
  phase: 'idle' | 'waiting' | 'thinking' | 'tool' | 'done'
  line: string            // plain-text status line, no ANSI
  label?: string          // current work label (tool action / stage)
  detail?: string         // path / command / pattern fragment
  phrase?: string         // current playful phrase
  toolCount: number       // tools completed this turn
  turnElapsedMs: number   // ms since turn start
  phaseStartedAt: number  // epoch ms the phase started (animation anchor)
}

Neither spelling carries a surfaceOp; neither enters derived model history.

Publishing rules: a line change publishes immediately; a stable line republishes at most every publishIntervalMs, so a long tool's elapsed time stays live without flooding the log. Optional fields are omitted when absent; the payload is lossless JSON.

The optional invariant companion validates both spellings: the legacy activity/status event and the current plugin:working-activity/status record.

Compatibility

The node half supports the host lines below. The surface columns describe which rendering transports are available on that line; the transport is always the workingActivity projection, except for the opt-in log-record consumer noted in the last column.

DSH host lineTUI (dsh-tui)Web UIDesktop GUIVerification
0.1.0-rc.6Maintained¹Not supportedNot supportedLegacy projection-shape test; runtime registration fixture
0.1.2-alpha.2Maintained¹Not supportedNot supportedpnpm run test:alpha2 (published host graph fixture)
0.1.7-rc.2SupportedSupportedNot applicable²pnpm run test:rc2 (published host graph fixture)
0.2.0-rc.2SupportedSupportedSupported³Main suite + RC2 host fixture + client-bundle gate + GUI contract gate
0.2.1-rc.2SupportedSupportedSupported³Main suite + RC2 host fixture + client-bundle gate + GUI contract gate

¹ Maintained for compatibility and exercised by isolated fixtures / shape assertions; the main development tree is no longer compiled against this line. ² The desktop GUI ships the 0.2.x kernel line; 0.1.7-rc.2 is not a GUI target. ³ The desktop GUI reuses the Web client entry. GUI 0.22.4 recommends DSH 0.2.0-rc.2, which the peer range covers. docs/gui-compatibility.md records the verified contract, evidence, and remaining limits.

Notes:

  • TUI requires a dsh-tui release whose DSH adapter supports the same host line. The current dsh-tui line targets 0.2.x and maintains its own activity-line/projection consumption; it mounts this package with publish: false. The ${activity} prompt slot is registered only when the host composes tuiPrompt, which the current DSH line does not.
  • Web UI requires the 0.1.7-rc.2, 0.2.0-rc.2, or 0.2.1-rc.2 client cohort. The browser bundle is built against the RC2 shell seed table (react, react/jsx-runtime, react-dom, @deepseek-ai/cordis, zod, @tanstack/react-virtual, @deepseek-ai/dsh-client-store, -ui-slots, -ui-primitives, -ui-dockkit); the 0.1.7-rc.2 shell is a subset that also resolves the bundle's only value import, react/jsx-runtime.
  • Desktop GUI shares the Web entry: platform: "web", the same dock seat, and the same projection. React 19 is covered by the peer range; the plugin itself runs inside the kernel Web client (React 18.3.1 on the current line), not the GUI host's React tree. The GUI must seed react/jsx-runtime and compose the three boot rows listed above. Run pnpm run verify:gui to check the GUI contract (the gate skips when the GUI checkout is absent).
  • Legacy record consumers (for example terminal UIs that replay the session log) can set publish: true on any supported line. On 0.2.x this is an ignorable plugin record; on older lines it is the legacy activity/status event backed by the registration shim.

Architecture

src/
  index.ts                 plugin entry: row config, per-session runtimes,
                           TUI prompt slot, narration section, publish sink
  status.ts                pure ActivityTracker state machine and renderer
  phrases.ts               bilingual copy pools and selection
  frames.ts                frame presets (shared with dsh-tui)
  lang.ts                  language resolution and copy dictionary
  config.ts                file-based working-activity config parser
  projection.ts            workingActivity session projection (all corridors)
  events.ts                activity/status event + plugin-record type merge
  registration.ts          legacy-corridor session-event type registration shim
  invariant.ts             optional dsh-invariants companion
  compat/
    session-events.ts      durable SessionEvent → ActivityEvent
    assistant-stream.ts    live agent/assistant-stream frame → ActivityEvent
    tool-result.ts         tool/result call-id and failure readers
  client/
    index.ts               client entry: dock registration
    WorkingLine.tsx        dock component
    elapsed.ts             local elapsed re-tick
    activity.ts            projection-key type merge
    WorkingLine.module.css
cordis.patch.yml           self-mounting bundle patch

The split is intentional: status.ts, phrases.ts, frames.ts, and lang.ts are pure and clock-injected; every host-shape guess lives in src/compat/; the client half imports types only and contains no domain folding.

Model impact

  • Tools: none registered.
  • Surface events: none appended by default. Published snapshots are log-only: an ignorable plugin record on 0.2.x, or a legacy activity/status event on older lines. Neither can reach the model.
  • Prompt: one fixed system-prompt section when narrate: true (the ⏵ contract). Set narrate: false for no prompt contribution.
  • Tokens per request: zero, except that fixed narration section.
  • KV cache: the narration section is static per language and does not vary per turn.

Development

cd packages/activity/working-activity
pnpm install --frozen-lockfile
pnpm run build              # host tsc + client tsc into lib/types/
pnpm run build:client       # browser bundle into lib/client.js
pnpm test                   # unit + host integration tests (vitest)
pnpm run verify:deps        # manifest dependency gate
pnpm run verify:lockfiles   # lockfile agreement gate
pnpm run verify:host-vocabulary
pnpm run verify:client-bundle
pnpm run verify:gui         # desktop GUI contract (skips when the GUI checkout is absent)
pnpm run prepublishOnly     # all publish gates
pnpm run test:alpha2        # isolated 0.1.2-alpha.2 host fixture
pnpm run test:rc2           # isolated 0.2.1-rc.2 host fixture

The main development graph is pinned to DSH 0.2.1-rc.2 (Cordis 4.0.5). The test:alpha2 and test:rc2 fixtures each carry their own lockfile and published host graph, so mutually exclusive peer sets never mix. A parent rebuild must be followed by a fixture reinstall (pnpm run test:rc2 does both).

The client bundle is a closure-factory artifact loaded with window.__ModuleLoader__.load({ id, factory }). It is checked without a browser: loader contract, module-specifier purity against the RC2 seed table, declared client row, and the dock registration + render branches.

Troubleshooting

No line in the TUI. Confirm the plugin is present in the composed profile (dsh --profile <profile> --dump-config) and that the dsh-tui release supports the host line. The TUI reads the projection; publish does not affect it.

No line in the Web UI. Confirm that the installed package contains lib/client.js, that the profile composes the three boot rows, and that the browser console has no MissingClientBundleError. For a packaging change, run pnpm run verify:client-bundle.

Tool count stays at 0 and the line freezes on the first tool. This is the pre-0.1.7-rc.2 tool/result correlation break. Upgrade to the current package release; the fix reads the call id from message.source.callId / message.toolCallId and the failure flag from message.isError.

A session fails to resume after enabling publish. On DSH 0.2.0-rc.2 / 0.2.1-rc.2, published snapshots are ignorable plugin records and cannot block resume. On older corridors the plugin registers the legacy type in every reachable dsh-session copy; if a reader resolves a copy the plugin cannot reach, disable publish. The first-party surfaces do not need it.

The invariant companion does not run. The bundle patch mounts only the working-activity row. Add the registry and companion rows explicitly in the profile's user layer:

- insert:
    - id: invariants
      name: '@deepseek-ai/dsh-invariants'
    - id: working-activity-invariant
      name: 'dsh-working-activity/invariant'

Skip the invariants row where the composition already mounts the registry.

Copy appears in the wrong language. Set lang: zh or lang: en on the row, or control the shared chain (DSH_TUI_LANG, ~/.dsh-tui/lang.json, OS locale). The resolved language is also carried on the projection so clients tick in the same language.

The line says something unexpected. Set debugLog: true; each distinct rendered line is appended as JSON with the derivation inputs (phase, copy pool, slot) to ~/.dsh-tui/working-activity-debug.log. Use DSH_WORKING_ACTIVITY_DEBUG_LOG to redirect the trace.

Privacy and security

The plugin collects no data, makes no network requests, and has no telemetry. Status values are derived locally from the session stream. With publish: true, snapshots are written only to the local session log — as an ignorable plugin record on 0.2.x, or a log-only activity/status event on older corridors — and never enter model history. customActions, copy pools, and language preference stay in local configuration.

License

BSD-3-Clause. See LICENSE.

The pi-working-activity extension in the repository root is a separate package under the MIT license; see the repository README.

dsh-tui
mode'lively' | 'minimal''lively'minimal keeps functional information only (plain labels, no playful pools).
featuresobject{}Per-feature switches; explicit values override mode defaults.
customPhrasesstring[][]Extra thinking phrases appended to the base pool.
showTokPerSecbooleanfalseShow an estimated ~tok/s prefix while streaming. The value is derived from delta text, not provider usage.
workRemindAtnumber0After this many hours of accumulated work, surface a break reminder (0–24; 0 disables).
debugLogbooleanfalseAppend a JSON trace of each distinct rendered line to ~/.dsh-tui/working-activity-debug.log (or DSH_WORKING_ACTIVITY_DEBUG_LOG).