dennisrongo/dsh-plugins--plugins-dsh-headless-plus0

@dennisrongo/dsh-headless-plus

Claude Code parity for the dsh headless app: --model, --resume, --continue flags

包名
@dennisrongo/dsh-headless-plus
版本
0.3.0
许可证
MIT
最近更新
2026年8月28日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:dennisrongo/dsh-plugins#377c8ef55a1bc9a64a99d08a7b73c398ae83b113&path:plugins/dsh-headless-plus

dsh-plugins

Dennis Rongo's plugin collection for DeepSeek Harness (dsh) — an MIT agent harness where every capability is a plugin.

Everything here is built on the harness's public seams: cordis service keys, the Typert host/client bridge, shell.* slots, the system-prompt section registry, and ctx.cmdlineArgs. No forks, no patched launcher, no vendored harness code.

Both surfaces are supported. Every plugin runs unchanged under the dsh CLI and under DSH Desktop — a community desktop wrapper that ships the harness pre-packaged with multi-provider model support ("Any model, zero setup"), for Windows and macOS. It is an independent project, not affiliated with DeepSeek.

The desktop keeps its own DSH_HOME (%APPDATA%\dsh-desktop\harness on Windows) with its own profiles, so you install a plugin once per profile on whichever surface you use. Nothing here is CLI-specific: the same package, the same cordis.patch.yml row, and the same /api endpoints serve both.

Status: developed against dsh 0.1.1-rc.2. dsh is a fast-moving 0.1.x dev preview that promises breaking changes — re-verify against your installed version.

Platforms: the plugins are plain Node and platform-agnostic, and DSH Desktop ships for Windows and macOS, so they should run on either. Most tooling is portable Node — verify.mjs, anchor.mjs, link-superpowers-skills.mjs. Only dev-link.ps1's profile-junction half is Windows-only. Everything here has been exercised on Windows against both the CLI and DSH Desktop; macOS and Linux are untested.

Plugins

PackageAddsHalvesEndpoints
dsh-todoper-workspace sprint/roadmap task list, plus a dsh-todo CLIhost + client + CLIdshTodo/list, replace
dsh-gitsource-control "Changes" tabhost + clientdshGit/status, diff, stage, commit, init, sync, suggestMessage
dsh-weatherweather bar in the shell overlayclient only
dsh-headless-plus--model / --resume / --continue for the headless appCLI app
dsh-superpowersSuperpowers methodology as a system-prompt sectionhost
dsh-mission-controlfleet dashboard overlay — sessions, swarm tree, token burn, permission inboxclient only

dsh-todo

A task tab scoped to the workspace you're working in, so each project keeps its own backlog instead of one global pile. It is a sprint/roadmap list, not a checklist: each task carries a status, a priority, and optional release and sprint labels.

What you get. A tab beside Chat and Trajectory. Tasks move through real workflow states — backlog · todo · in-progress · blocked · done — changed from a pill on the row, because a boolean can't express the two things a standup actually asks: what is moving, and what is stuck. Priority is P0P3 as a chip, with only P0/P1 coloured so the list flags what's urgent instead of turning into a rainbow. Release (v1.2.0, what ships together) and sprint (Sprint 24, when it's worked) are deliberately separate free-text axes — a task can be in both, and grouping works with no releases table to administer. Group by None · Status · Release · Sprint · Priority gives collapsible sections with their own progress bars; grouping by status is a kanban board without drag-and-drop. Clicking a title opens a task detail modal (description, status, priority, labels, due date); the chevron still gives a cheap in-row peek, and double-click renames inline. Due dates are stored as calendar days, so "due the 14th" reads as the 14th in every timezone; overdue is flagged red, due-today amber. Completed work is archived, not deleted — an item carries an optional archivedAt stamp whose presence is the archived state, so there's one source of truth and no way to store an archived item without a date. Every irreversible action goes through a confirmation dialog that quotes the task by name.

CLI. The package ships a dsh-todo binary so an AI agent can shell out and manage the same list you see in the tab — no profile, no session, no running server:

npx dsh-todo list --open --json
npx dsh-todo add "Fix token refresh" --priority p0 --release v1.2.0 --due 2026-03-14
npx dsh-todo update t1a2 --status in-progress --sprint "Sprint 24"
npx dsh-todo done t1a2 && npx dsh-todo archive

It targets a workspace directory (--workspace, default cwd) and talks to the same SQLite file the host uses, which is safe by construction: SQLite's file lock refuses a writer that lands inside another process's transaction, and the CLI sets a busy_timeout so it waits for the harness to commit rather than failing. Verified live — the CLI wrote while a running server held its handle and the API returned the new task with no restart. Ids accept any unambiguous prefix, an empty value clears a field (--release ""), invalid values are refused rather than dropped, and --json prints structured output on the error path too. Exit codes are distinct: 0 ok, 2 usage, 3 not found.

How it works. TodoService extends TypertRemoteService registers under the cordis key dshTodo and owns one SQLite database per project at /.dsh/todo.db, resolved through workspaceRegistry. Writes use optimistic concurrency: every replace states the revision it observed, and the host rejects a stale write with ok:false, code:'revision-conflict' and the current list, rather than silently clobbering. A legacy central ~/.dsh/storages/dsh_todo.json is migrated on first read.

Endpoints. POST /api/dshTodo/list{ list: { items, revision, updatedAt } }; POST /api/dshTodo/replace → the new list or a revision conflict. Both take a single parameter named request.

The task shape is { id, title, description?, status, priority, release?, sprint?, dueDate?, createdAt, completedAt?, archivedAt? }. status is the source of truth — there is no separate done flag to fall out of sync — and only the status transition writes completedAt. Absent optional fields are absent keys, never ''. Existing v1 databases are migrated in place on first open: CREATE TABLE IF NOT EXISTS doesn't add columns to a table that already exists, so each new column is added with ALTER TABLE after consulting PRAGMA table_info, then title is backfilled from the old text and done = 1 becomes status = 'done'. The v1 columns are still written on every insert, so a downgrade still reads a sane list. src/db.ts is shared by the host and the CLI on purpose — a second copy of the migration is the one duplication that could genuinely corrupt a database.

Requires. workspaceRegistry from dsh-base, which @deepseek-ai/dsh-web-app composes by default. The CLI requires none of it.


dsh-git

Source control for the workspace, without leaving the harness.

What you get. A Changes tab showing branch, upstream ahead/behind, and a file list split into staged and unstaged, with per-row stage/unstage/discard and a diff pane. An ✦AI message button drafts a commit message from the staged diff through the harness's own llm service, then Commit all commits. Recent history is listed underneath. A directory that isn't a repository reports repo: false and offers Initialize repository rather than erroring.

The layout is responsive to the tab, not the window. The diff sits beside the file list when there's room and below it when there isn't, switched by a container query (@container dshgit (min-width: 720px)) — the tab is resized by the shell's own sidebar and panels independently of the viewport, so the width that matters is its own. Opening a diff never moves a row: the list's column width is reserved in both states, so the first click can't reflow and re-truncate every filename under the pointer. While a patch is in flight the pane shows a skeleton shaped like a diff — shimmering meta/hunk/add/del bands sized off the real 18px diff line — rather than a spinner, which would blank a large surface; the shimmer animates background-position, never a transform or a box dimension, so it can't shift layout, and prefers-reduced-motion flattens it. Clicking down a list starts overlapping requests, so each is stamped with a monotonic sequence and a stale reply is discarded rather than painted under the wrong filename. Icons are inline 16px SVGs on a matching 0 0 16 16 viewBox in 20px buttons, which keeps file rows at 32px.

How it works. GitService extends TypertRemoteService under the cordis key dshGit, shelling out to git in the workspace directory. Writes are serialised per repository root through an internal queue, so two tabs can't interleave a stage and a commit. Paths from the client go through assertSafePath, which refuses absolute paths and .. escapes. Untracked files have no diff for git to produce, so their contents are synthesized into a /dev/null patch — otherwise clicking a new file would show a blank pane and look broken. push without a remote fails as data ({ ok: false, output }), not an exception.

Endpoints. status, diff, stage, commit, init, sync, suggestMessage under POST /api/dshGit/, each taking one parameter named request.

Requires. workspaceRegistry and llm (both composed by dsh-base) and agentDefaultModel for message drafting.


dsh-weather

Current conditions pinned to the bottom of the web UI: temperature, condition, location, a short hourly outlook, humidity and wind.

How it works. A pure-consumer client plugin registering into the additive shell.overlay slot — no host service, no endpoints, no API key. It fetches Open-Meteo directly from the browser (CORS-enabled). Readings are always fetched in Celsius and converted at render time, so the °F/°C toggle needs no refetch; the choice persists in localStorage["dsh-weather:unit"] and defaults to °F. Location resolves from localStorage["dsh-weather:location"], then a geo-provider chain, then a hard fallback to New York; every network path degrades to a visible error state rather than throwing into the shell.

Accessibility is deliberate: the unit toggle is a real `` with an aria-label, the bar is aria-live="polite", focus is styled via :focus-visible, and prefers-reduced-motion disables the refresh spinner.


dsh-headless-plus

The stock headless app answers one task and exits, with no way to choose a model or continue a conversation. This replaces it.

Stock headlessheadless-plus
dsh --profile headless "task"unchanged
--model provider/model — per-invocation model override
--resume — continue a persisted session
--resume latest / --continue / -c — continue this workspace's most recent session
--session-info — print the new session id on stderr at exit
dsh --profile headless-plus --model anthropic/claude-sonnet-4-6 "refactor the auth module"
dsh --profile headless-plus --continue "now add tests"
dsh --profile headless-plus --resume session-6f2ca6dc-… "pick up where we left off"

How it works. Two rows replace the two stock ones: a startup row that owns the flag family via ctx.cmdlineArgs (each app owns its own flags, so this doesn't collide with the launcher), and a runner row that receives the parsed task by injection. Resuming goes through the public ctx.agents.resume() with ResumeAgentOptions; --resume latest maps the workspace to its session directory using the same slug rule as dsh-session-persistence-jsonl. Model overrides go through ctx.agentDefaultModel. Note the folder is plugins/dsh-headless-plus but the package is @dennisrongo/dsh-headless-plus, and a mount row takes the package name.


dsh-superpowers

Makes the Superpowers methodology mandatory-first for every agent in a profile, rather than a skill the model may or may not reach for.

How it works. Upstream delivers its bootstrap through a SessionStart hook that must re-fire on startup|clear|compact. dsh has no hook shell, but its system prompt is a layered, ordered section registry that is reassembled after compaction — so one registered section covers all three upstream trigger points for the life of the session, with no gap where the bootstrap can fall out. It sits at order -50, just before persona.

Nothing is vendored. The section body is read from your own clone of the upstream repo at profile start, located via superpowersRoot, then SUPERPOWERS_ROOT, then a probe of common clone paths under $HOME. So git pull + a profile restart is the entire update path. To have the clone's skills catalog follow a pull too, instead of drifting as copies:

node scripts/link-superpowers-skills.mjs     # --dry-run to preview, --restore to undo

dsh-mission-control

One glass panel over the whole agent fleet, floating above the stock web UI.

What you get. A shell.overlay dashboard, docked as a right rail, with a Fleet list of every session (root and subagents) grouped by workspace and showing running / waiting / done, a swarm tree of coordinator → worker lineages, a stats strip (session count, running, subagents, waiting-on-you), estimated token burn broken down by model, and a permission inbox surfacing sessions blocked on approval / question / plan-review.

Stage is a full-screen takeover — press it and the rail swaps for a live grid of tiles, one per session that is running, waiting on you, or was touched inside the activity window (30m / 2h toggle), busiest first. A tile carries the session's live conversation and answers a pending permission in place, so you never lose the tab you came from; Esc or × returns to the panel. Because Stage covers the whole viewport it also spans DSH Desktop's 36px window-drag strip, which swallows clicks before hit-testing — its bar clears that band and every control opts out with data-dsh-no-drag.

A settings drawer persists to localStorage (bad shapes fall back to defaults, and a storage failure degrades to in-memory rather than throwing): sessions listed per workspace group, fleet sort order, and an optional pomodoro timer in the footer with configurable work / short-break / long-break lengths and a desktop notification on phase change.

How it works. A pure consumer on public faces only — ctx.sessions.list and ctx.workspaces.list as ObservableSnapshots bridged into React, sessionStats projections (turns / steps / llmMs / decodeTokens), and PendingInteraction off the session summaries. No services, no tools, no presets and no host half; it floats over the stock UI without touching it. CSS is namespaced dshmc-, and control metrics are CSS custom properties so the 400px rail's compact sizing and Stage's full-screen sizing derive from one set of tokens rather than diverging.


Every package carries an AGENTS.md with its endpoints, mount row, dev loop and a verification recipe. See AGENTS.md for the repo as a whole.

Install a plugin

All six are on npm, and each declares dsh.bundle — so one command installs and mounts it. dsh plugin forwards to pnpm inside the profile directory:

# web/desktop UI plugins
dsh plugin --profile web add @dennisrongo/dsh-todo
dsh plugin --profile web add @dennisrongo/dsh-git
dsh plugin --profile web add @dennisrongo/dsh-weather
dsh plugin --profile web add @dennisrongo/dsh-mission-control

# CLI-app and prompt plugins, in a headless-style profile
dsh plugin --profile headles