{"_id":"@dsh-blue/herdr-agent-state","_rev":"4-fcda23ee865c70c8b31b5a6c80c542f3","name":"@dsh-blue/herdr-agent-state","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@dsh-blue/herdr-agent-state","version":"0.1.0","keywords":["dsh","deepseek-harness","cordis","plugin","herdr","agent-state","pane","integration"],"license":"MIT","_id":"@dsh-blue/herdr-agent-state@0.1.0","maintainers":[{"name":"geekcmore","email":"geekcmore@163.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"21baa2882fd194ac305aaa7b0f7e1ac744c33077","tarball":"https://registry.npmjs.org/@dsh-blue/herdr-agent-state/-/herdr-agent-state-0.1.0.tgz","fileCount":7,"integrity":"sha512-xxWV2i27Phvs+lLncSycVneilxGyFeQu77JuCGHrTUD7B/l7sT+jgZ0Drvpd2DVnzJ78C6E+44yT0sgdYXbO8A==","signatures":[{"sig":"MEQCIAsdYot3nxz9DzuhllmAPpIQcSSAHsCcgxUNSwzMLUikAiBc0khO01KHVXKPxQcMtjZNCVJ7BmDwWo+6HE9S3naSIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19056},"main":"src/index.js","type":"module","engines":{"node":"^22.19 || >=24"},"exports":{".":"./src/index.js"},"gitHead":"9113888de5d00ba1e818e2ec16813363080a862b","scripts":{"test":"vitest run","test:watch":"vitest"},"_npmUser":{"name":"geekcmore","email":"geekcmore@163.com"},"_npmVersion":"11.17.0","description":"dsh plugin: report agent state (working/blocked/idle) and session reference to Herdr via its pane socket integration. Works in any dsh profile — TUIs, web, headless.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0"},"peerDependencies":{"@deepseek-ai/schemastery":"^3.18.2"},"_npmOperationalInternal":{"tmp":"tmp/herdr-agent-state_0.1.0_1788256482381_0.1726970378298882","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@dsh-blue/herdr-agent-state","version":"0.2.0","keywords":["dsh","deepseek-harness","cordis","plugin","herdr","agent-state","pane","integration"],"license":"MIT","_id":"@dsh-blue/herdr-agent-state@0.2.0","maintainers":[{"name":"geekcmore","email":"geekcmore@163.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"dist":{"shasum":"e8f79ce586b61ba938558f285caa3571cc292dd4","tarball":"https://registry.npmjs.org/@dsh-blue/herdr-agent-state/-/herdr-agent-state-0.2.0.tgz","fileCount":7,"integrity":"sha512-wTPIV2H4ZzPYhxxQbv0vBSY2A21VUiqubGrRcNzDYZatml34mT+IrUpExoK3RtutxHQT+KzAAPrqTIsSnwvMcQ==","signatures":[{"sig":"MEUCIQChs730YK5P7V7DXqn0/rzct6Tut708aHLvB2o4wL1jXgIgUqZX5lJoQPYvHUTMxJ4+kwY7lBBzdHyP+MkAAxjhaSM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":29120},"main":"src/index.js","type":"module","engines":{"node":"^22.19 || >=24"},"exports":{".":"./src/index.js"},"gitHead":"ab621fb35a7df0e324936fa80bba11c28954b8a9","scripts":{"test":"vitest run","test:watch":"vitest"},"_npmUser":{"name":"geekcmore","email":"geekcmore@163.com"},"_npmVersion":"11.17.0","description":"dsh plugin: report agent state (working/blocked/idle) and session reference to Herdr via its pane socket integration. Works in any dsh profile — TUIs, web, headless.","directories":{},"_nodeVersion":"24.19.0","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.0.0"},"peerDependencies":{"@deepseek-ai/schemastery":"^3.18.2"},"_npmOperationalInternal":{"tmp":"tmp/herdr-agent-state_0.2.0_1788283821703_0.843409538075415","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@dsh-blue/herdr-agent-state","version":"0.3.0","description":"dsh plugin: report agent state (working/blocked/idle, labeled with the current tool), session reference and log path, and session metadata (title, model, context-usage tokens, state labels) to Herdr via its pane socket integration. Works in any dsh profil","type":"module","main":"src/index.js","exports":{".":"./src/index.js"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"}},"engines":{"node":"^22.19 || >=24"},"keywords":["dsh","deepseek-harness","cordis","plugin","herdr","agent-state","pane","integration"],"license":"MIT","peerDependencies":{"@deepseek-ai/schemastery":"^3.18.2"},"devDependencies":{"vitest":"^3.0.0"},"scripts":{"test":"vitest run","test:watch":"vitest"},"gitHead":"c9d840e7d0a167e03233c35fcc5de40da819922d","_id":"@dsh-blue/herdr-agent-state@0.3.0","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-xnlcurB2lT4/5S7PjMo4SNOwirEaSUelomUK15iE6BtvC39sGykXIeE47mDon1Pb7NgbdAV0P3CjET8owYvnWQ==","shasum":"f478f70643052bb9d8ac9a3c2f87c4f2e7c68faa","tarball":"https://registry.npmjs.org/@dsh-blue/herdr-agent-state/-/herdr-agent-state-0.3.0.tgz","fileCount":7,"unpackedSize":44853,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCPEabzacxSdrxUobWK/CM8FTk4vwgyFny+PeLESr1MWQIgFei382AAJdFbRV3nkjapgAKQZHNamFLfywu1betXT9A="}]},"_npmUser":{"name":"geekcmore","email":"geekcmore@163.com"},"directories":{},"maintainers":[{"name":"geekcmore","email":"geekcmore@163.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/herdr-agent-state_0.3.0_1788309103117_0.9713197557279474"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-01T09:54:42.141Z","modified":"2026-09-02T00:31:43.628Z","0.1.0":"2026-09-01T09:54:42.518Z","0.2.0":"2026-09-01T17:30:21.863Z","0.3.0":"2026-09-02T00:31:43.240Z"},"license":"MIT","keywords":["dsh","deepseek-harness","cordis","plugin","herdr","agent-state","pane","integration"],"description":"dsh plugin: report agent state (working/blocked/idle, labeled with the current tool), session reference and log path, and session metadata (title, model, context-usage tokens, state labels) to Herdr via its pane socket integration. Works in any dsh profil","maintainers":[{"name":"geekcmore","email":"geekcmore@163.com"}],"readme":"# @dsh-blue/herdr-agent-state\n\nA DeepSeek Harness (`dsh`) plugin that reports a pane's agent state — `working`,\n`blocked`, `idle`, labeled with the currently-executing tool while working — its\nsession reference and log path, and its session display facts (title, model,\nand context usage as pane metadata) to [Herdr](https://herdr.dev/) through\nHerdr's pane socket integration. It lets Herdr's sidebar show where the agent\nactually is, surface waiting agents, name panes after the conversation, and\nexpose the session for restore, **without any change to Herdr** (Herdr's\n[custom integration](https://herdr.dev/docs/integrations/#integrate-your-own-agent)\npath).\n\nIt works in **any dsh frontend** — TUIs, the web app, and headless — because it\nsubscribes only to documented dsh extension points (agent lifecycle events, the\napproval and user-question waterfalls) and carries no UI or renderer dependency.\n\n## Install\n\nThe plugin is a **dsh bundle** (`dsh.bundle.patch` → `cordis.patch.yml`), so\n`dsh plugin add` activates it automatically — no manual `cordis.patch.yml` edit:\n\n```sh\ndsh plugin --profile <profile> add @dsh-blue/herdr-agent-state\n```\n\nIt inserts a row labelled `herdr-agent-state`. To change the Herdr agent label\na frontend reports, patch the same row id in the profile's `cordis.patch.yml`\n(an id-targeted patch replaces that row's whole `config`; the schema defaults\nfill any field you omit):\n\n```yaml\n# ~/.dsh/profiles/<profile>/cordis.patch.yml\n- id: herdr-agent-state\n  config:\n    agent: blue        # default dsh; this frontend's own label\n```\n\nThe plugin is a strict no-op outside a Herdr pane (`HERDR_ENV=1` plus\n`HERDR_SOCKET_PATH` and `HERDR_PANE_ID` absent), so it never adds side effects\nto a normal terminal session.\n\n### Install straight from GitHub (before publishing to npm)\n\n`dsh plugin` is a thin [pnpm](https://pnpm.io/) forwarder, so it accepts any\npnpm dependency spec — including a GitHub repo. The plugin ships plain ESM\nJavaScript with no build step, so `dsh plugin add` installs and auto-activates\nthe bundle in one command with no `prepare`/`lib` and no `allowBuilds` entry:\n\n```sh\n# master branch; pin the exact commit when you want reproducibility\ndsh plugin --profile <profile> add github:dsh-blue/herdr-agent-state\n# or pinned to a commit (the pattern Blue marketplace installs use):\ndsh plugin --profile <profile> add dsh-blue/herdr-agent-state#<40-char-sha>\n```\n\n## How it reports state\n\n| Herdr state | dsh signal |\n|---|---|\n| `working` | any agent reports `agent/status = running` |\n| `blocked` | an `approval/request` or `user-questions/request` waterfall is awaiting an answer |\n| `idle` | no agent running and nothing pending |\n\nWhile working, the pane report carries a `message` naming the\ncurrently-executing tool (observed on the `tools/execute` waterfall, which\nfires only for calls that survived approval — denied calls never label). The\nsession reference carries both `agent_session_id` and, when the profile\npersists sessions as jsonl, `agent_session_path` (the absolute log path);\nsqlite or no-persistence backends omit the path.\n\nBlocked observations are **passive**: the plugin calls `await next()` and returns\nthe downstream decision unchanged, so approval and question flows are never\naltered. Reports are coalesced (latest value wins) and tagged with a strictly\nincreasing `seq`, mirroring Herdr's own Pi integration wire contract.\n\nThe plugin releases the pane's lifecycle authority on unload and process exit,\nand re-reports on `agent/session-start` so a reload does not leave Herdr with a\nstale authority.\n\n## How it reports metadata\n\nAll display-only extras ride Herdr's `pane.report_metadata` channel. Title and\nstate labels are presentation fields guarded by the same `source`/`agent` as\nthe state reports plus an `applies_to_source` guard, so they apply exactly\nwhile this reporter holds the pane's lifecycle authority; tokens always apply\nand are this reporter's to clear. Herdr checks the guards when a report\narrives (not continuously), so the reporter clears everything it sent when it\nreleases the pane's authority. Metadata never affects waits, notifications, or\nrollups, and is not restored across a Herdr server restart.\n\n- **Title** (`title: session`) mirrors the dsh session title — first-prompt\n  fallback, LLM-generated refinement, or pinned by `/rename`. Titles are\n  observed on the same `session/title` session-log feed the dsh TUI renders,\n  filtered to the session the pane's agent is running (subagent sessions in\n  the same process are skipped); a resumed session's existing title is read\n  directly at `agent/session-start`, since past title events are replay seeds\n  that never re-enter the live feed. After a `/clear` the previous title stays\n  until the new session produces its first title (usually seconds).\n- **Tokens** (`tokens: auto`) report `model` (the raw model id) and `ctx`\n  (context occupancy, `used/window` mirroring the dsh TUI status bar, e.g.\n  `34k/1.0M`; bare `used` when the route's context window is unknown). Model\n  and window come from the `request/header` / `request/context` log events and\n  update on every assistant step's usage; a resumed session seeds all three\n  from the replayed log. Herdr's Agent sidebar can render them as `$model`\n  and `$ctx`. Tokens are cleared on release.\n- **State labels** (`stateLabels`) override the visible text per Herdr state —\n  for example `{ working: 工作中, blocked: 等待确认 }`. Non-blank entries are\n  sent once per session start and cleared on release.\n- **Working message** (`workingMessage: tool`) attaches the\n  currently-executing tool name to `working` state reports (see above);\n  blocked labels are unchanged and still governed by `message`.\n\n## Configuration\n\n### Configuration reference\n\n| Field | Type | Default | Meaning |\n|---|---|---|---|\n| `agent` | string | `'dsh'` | The Herdr agent label reported for the pane. Set a frontend's own name (e.g. `blue`) so Herdr's sidebar groups it under that label. |\n| `source` | string | `'herdr:dsh-agent-state'` | Stable, unique integration source. Herdr attributes the pane's lifecycle authority to this source. **Keep it constant.** Changing it makes Herdr treat the pane as a *different* authority mid-session. |\n| `transport` | `'socket'` \\| `'cli'` | `'socket'` | How to report to Herdr. Only `socket` is implemented (speaks the pane socket directly). `cli` is declared but not yet implemented — it throws **at load**, so don't set it. |\n| `reportSession` | boolean | `true` | Report the pane's session reference (`agent_session_id`) so Herdr can expose it for restore. Set `false` to suppress session reporting. |\n| `title` | `'session'` \\| `'none'` | `'session'` | Which title to publish as the Herdr pane title (display-only metadata). `session` mirrors the dsh session title — first-prompt fallback, LLM-generated, or pinned by `/rename`; `none` disables title reporting. |\n| `message` | `'tool'` \\| `'none'` | `'tool'` | Whether to attach a human label to `blocked` reports. `tool` sends the tool name / question summary; `none` sends `blocked` with no message. |\n| `workingMessage` | `'tool'` \\| `'none'` | `'tool'` | Whether to attach the currently-executing tool name to `working` reports. |\n| `tokens` | `'auto'` \\| `'none'` | `'auto'` | Report the `model` and `ctx` (context usage `used/window`) tokens as Herdr Agent-sidebar metadata. `none` disables. |\n| `stateLabels` | `{ idle?, working?, blocked?, done?, unknown? }` | `{}` | Display text per Herdr state; non-blank entries are sent as pane state labels. |\n| `enabled` | boolean | `true` | Kill-switch. Set `false` to disable the reporter in this tree — useful to coexist with another reporter. |\n\n### How to configure it\n\nThe plugin is a bundle row labelled `herdr-agent-state`, so it is inserted\nautomatically when you `dsh plugin add`. Because its `Config` schema gives every\nfield a default, you only set what you want to change; the schema fills the\nrest. A profile's `cordis.patch.yml` is a **top-level YAML array of loader patch\nentries**, so you target the row by `id` and replace its `config`:\n\n```yaml\n# ~/.dsh/profiles/<profile>/cordis.patch.yml\n- id: herdr-agent-state\n  config:\n    agent: blue\n```\n\nThe patch replaces the row's whole `config`, so the schema defaults supply any\nfield you don't set. Include `name` as a guard — if it ever mismatches the row,\nthe patch is skipped with a warning instead of silently applying:\n\n```yaml\n- id: herdr-agent-state\n  name: '@dsh-blue/herdr-agent-state'\n  config:\n    agent: blue\n    source: herdr:dsh-agent-state\n    transport: socket\n    reportSession: true\n    title: session\n    message: tool\n    workingMessage: tool\n    tokens: auto\n    stateLabels:\n      idle: ''\n      working: ''\n      blocked: ''\n      done: ''\n      unknown: ''\n    enabled: true\n```\n\n### Examples\n\nSet the Herdr label to `blue` when Blue hosts the pane (all other fields\ndefault):\n\n```yaml\n- id: herdr-agent-state\n  config:\n    agent: blue\n```\n\nDisable session reporting and verbose blocked messages:\n\n```yaml\n- id: herdr-agent-state\n  config:\n    reportSession: false\n    message: none\n```\n\nDisable title reporting (keep state and session reports):\n\n```yaml\n- id: herdr-agent-state\n  config:\n    title: none\n```\n\nLocalize the Herdr state display (state labels):\n\n```yaml\n- id: herdr-agent-state\n  config:\n    stateLabels:\n      working: 工作中\n      blocked: 等待确认\n      idle: 空闲\n      done: 已完成\n```\n\nTurn off the sidebar tokens while keeping the title:\n\n```yaml\n- id: herdr-agent-state\n  config:\n    tokens: none\n```\n\n### Notes\n\n- **Changing `source`** re-attributes the pane's authority in Herdr. Keep it at\n  the default unless you are deliberately running two reporters in the same\n  tree — then give each a distinct `source`, and use `enabled: false` on the one\n  you want silent.\n- **`transport: 'cli'` is not implemented.** Setting it throws during plugin\n  load (fail-fast), so leave it as `socket`.\n- **`config` is validated** against the schemastery schema at load; an invalid\n  value (for example a `transport` that isn't `socket`/`cli`) is rejected, and\n  the plugin fails to load rather than running half-configured.\n- The pane title and state labels ride the same `source` and `agent` guards as\n  the state reports; changing `source` mid-session affects them the same way\n  it affects lifecycle authority. Tokens are not guarded — they always apply —\n  so this reporter clears them on release.\n- Because a patch replaces the row's whole `config`, any field you don't set\n  comes from the schema default — you do not need to copy every field.\n\n## Version compatibility\n\nBuilt against the dsh `0.1.2-alpha` line. It shares the host's\n`@deepseek-ai/schemastery` instance (declared as a peer, so the runtime\n`Config` schema uses the same copy the host validates against).\n\n## Development\n\n```sh\npnpm install\npnpm test        # vitest run (unit + fake-socket integration)\n```\n\nThe plugin ships as plain ESM JavaScript, so there is no build step. Its\n`state` and `transport` modules depend only on Node builtins, so their tests\nrun without a dsh host.\n\n## License\n\nMIT.\n","readmeFilename":"README.md"}