DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

martyartem /

martyartem/dsh-plannotator

Verified

Review a file, a folder or a web page in the Plannotator browser UI from DeepSeek Harness, and get the annotations back as a message.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@aea1b20e

dsh-plannotator

English | Русский

Review a file, a folder or a web page in the Plannotator browser UI — the annotations come back to the agent as a normal message in the conversation.

version license tests CI DeepSeek Harness


Why this plugin exists

Two things get in the way when a review is started from inside a DSH session, and each one hurts differently.

What gets in the way How it looks to you What this plugin does
The review blocks the call The review server waits for a human for minutes, while a DSH bash call gives up far sooner: the process is pushed to the background, and killing it loses the notes you already wrote, with no record. Starts the review in the background, answers with the link immediately, and delivers the decision into the conversation when the human submits it.
plannotator is not found A DSH session starts with PATH=/usr/bin:/bin:/usr/sbin:/sbin, so an install in ~/.local/bin/plannotator is not on it — the agent sees plannotator: command not found and the review never starts. Resolves the CLI itself: plugin config → PLANNOTATOR_BIN → PATH → well-known install locations.

Features

Surface Where What it does
Review button Document preview header, right sidebar Starts a review of the file on screen. A file Plannotator would refuse (PDF, image, Office, an exotic suffix) is reviewed as its containing folder, so the button is never a dead end.
/plannotator <file|folder|url> Composer The same review, started from the text box — and the agent's non-blocking entry point.
/plannotator Composer Reviews this session's workspace folder.
/plannotate Composer Alias.
Delivered annotations Conversation The decision record (--json) is steered back as a message, so the agent addresses the annotations in the same chat.

That is the whole surface: one sidebar seat, one command, two HTTP routes, and no flags.

Requirements

  • DeepSeek Harness >=0.1.0-rc.5 (declared in package.json).
  • Node >=20 for the host half. There are no runtime dependencies.
  • The Plannotator CLI installed somewhere the plugin can find: plugin config, PLANNOTATOR_BIN, PATH, or one of ~/.local/bin, /usr/local/bin, /opt/homebrew/bin, ~/.bun/bin, ~/.cargo/bin. Without it the plugin still loads and reports how to point it at the CLI.

Install

From the Harness plugin manager

Open Plugins in the app and install this repository:

https://github.com/martyartem/dsh-plannotator

Then restart the app. The npm package name is plannotator-dsh; the repository is dsh-plannotator.

From a checkout

Clone anywhere outside ~/.dsh, and install it as a link so edits reach the profile:

git clone https://github.com/martyartem/dsh-plannotator ~/Projects/plannotator-dsh

Add it to your profile (~/.dsh/profiles/<profile>/package.json) and restart:

{
  "dependencies": { "plannotator-dsh": "link:/Users/you/Projects/plannotator-dsh" },
  "dsh": { "profile": { "bundles": ["…", "plannotator-dsh"] } }
}

scripts/uninstall.sh [profile] [--purge] rolls that back.

Configuration

Set values in your profile's patch layer (cordis.patch.yml) — the user patch layer survives DSH upgrades:

- id: plannotator-dsh
  name: plannotator-dsh
  config:
    gate: true
    timeoutMs: 1800000
Key Default Meaning
binary auto-detect explicit path to the plannotator CLI
binaryFallbacks well-known list extra candidate paths
origin dsh the PLANNOTATOR_ORIGIN every review is stamped with
gate false add an Approve button to every review
openBrowser true let Plannotator open the browser tab
port random fix the local review-server port
timeoutMs 900000 how long a review may stay open before it is stopped
readyTimeoutMs 20000 how long to wait for the local server to report readiness
autoFollowup true steer the annotations back into the conversation
debug false also write the plugin log to stderr
dataDir ~/.dsh/storages/plannotator-dsh where plannotator-dsh.log lives

How it works

  • Host half — lib/index.js: registers the command and the two routes, resolves the CLI and the workspace, starts the Plannotator process in the background, waits for its readiness file, then reads the decision record from its stdout and steers it into the session.

  • Browser half — lib/client.js: hand-written in the host's module-loader format (window.__ModuleLoader__.load), so it needs no bundler and only react from the platform seed table. It contributes its seat through ctx.slots.inject(seat, () => ctx.slots.register(…)), the documented way to be independent of plugin start order.

  • HTTP routes — the browser half never imports a host service:

    Route Purpose
    GET /plannotator/review?target=<path|url>[&session=<id>] starts a review in the background, answers { ok, url, label, gate }
    POST /plannotator/log forwards a client-side note into the plugin log
  • Workspace resolution, in order: the live agent's session directory → DSH_WORKSPACE_DIR / DSH_CWD → ctx.workspaceRegistry → the cwd in the session-log header → the newest session → the host process cwd.

  • Delivery contract — the message the agent receives is a DSH UserMessage with every field the type requires: id, role, content, and a producer-owned source.kind of plugin:plannotator-dsh. The append path accepts a message without id, but the restore path then rejects the whole session (session event at seq N lacks an identified message) and the history stops loading. The plugin mints the id itself, and the offline suite asserts the message carries one.

Compatibility

Dependency Range
DeepSeek Harness >=0.1.0-rc.5
Node >=20, built-ins only
Plannotator CLI the documented contract: argv annotate <target> --json, the readiness file (PLANNOTATOR_READY_FILE), the stdout decision record, PLANNOTATOR_ORIGIN, PLANNOTATOR_PORT

Troubleshooting

Everything is logged to ~/.dsh/storages/plannotator-dsh/plannotator-dsh.log. After a DSH or Plannotator upgrade, this is the whole check:

grep -E "loaded|apply:|registered|unavailable|steering failed" \
  ~/.dsh/storages/plannotator-dsh/plannotator-dsh.log | tail -12
Line Means
loaded …; binary=… the host loaded the plugin and found the CLI
registered /plannotator/review and /plannotator/log the HTTP routes are in place
client[info]: document preview action registered the Review button's seat exists
document preview action unavailable: … the seat was renamed or is gone
steering failed: … the host rejected the delivered message
session … timed out after … the review outlived timeoutMs and was stopped

If the first line is missing, the plugin did not load at all — usually an injected service the host renamed.

Development

Nothing but Node is needed: no install step, no bundler, no booted profile.

npm test                      # both offline halves
node scripts/selftest.mjs     # host half: 35 checks — parsing, CLI/workspace resolution, sessions, routes
node scripts/client-test.mjs  # browser half: 12 checks — bundle shape, the single seat, the cold-boot race
node scripts/live-test.mjs    # against the real Plannotator CLI and its HTTP API
lib/
  index.js      host row: command, HTTP routes, agent targeting
  command.js    input → Plannotator argv
  review.js     a review in the background: readiness, decision, steering, timeout
  config.js     config defaults, log file, helpers
  binary.js     PATH-independent CLI discovery
  workspace.js  which directory a relative target resolves against
  client.js     browser half: the document-preview Review seat
scripts/        offline suites, live smoke test, uninstall helper

Notes and limits

  • annotate accepts markdown, plain-text config/data files, HTML, URLs and folders. .env is refused by Plannotator itself.
  • Git diffs, pull requests and the archive are deliberately not here: the Plannotator CLI covers them directly, and a slash command that blocks for minutes is exactly what this plugin exists to avoid.
  • A review nobody finishes (process killed, machine asleep) yields no decision; the plugin says so instead of pretending the review was empty.
  • The plugin never scrapes the browser UI: it uses the CLI's documented stdout contract and its readiness file only.

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit aea1b20ea5ba

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout