deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
English | 中文
An ops plugin suite for DeepSeek Harness (dsh): it turns a dsh agent into a production-incident investigator — one that resolves kubectl / ceph / ssh credentials by name, runs read-only commands against your clusters, and organizes the investigation as a tree.
It installs as a single npm package, @elinpf/dsh-ops; the granular @elinpf/dsh-ops-* packages arrive as its dependencies, all published in lockstep versions.
trace tool structures investigations as trees, rendered git-graph-style in the web UIkubectl on the host with cluster network reachability; ceph / ssh as needed; sshpass too when using password-auth ssh profiles (network devices & co.)Install the package (dependencies and host-plane rows mount automatically):
dsh plugin --profile ops add @elinpf/dsh-ops
For the web UI, edit ~/.dsh/profiles/ops/package.json and add the web host to the bundles:
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"@elinpf/dsh-ops"
]
}
}
@deepseek-ai/dsh-web-app resolves through the dsh installation; it cannot be installed via dsh plugin add.
If the install fails with a minimumReleaseAge error, add a name-pattern exclusion to the profile's pnpm-workspace.yaml — plain @elinpf/*, with NO version qualifier, so upgrades never need the list edited again:
minimumReleaseAgeExclude:
- '@elinpf/*'
Materialize the ops preset:
npx @elinpf/dsh-ops preset install --agents-home ~/.dsh
The harness discovers user presets under ~/.dsh/.agent-presets/; without --agents-home the preset lands in ~/.agents and fails silently.
Edit ~/.dsh/profiles/ops/cordis.patch.yml, replacing the top-level array with:
- id: agent-presets
config:
default: ops
- id: session-reference
disabled: true
Start (--no-open skips opening a browser; flags match dsh web):
dsh --profile ops --no-open
Register credentials in ~/.dsh-ops/access.yaml — paths and connection parameters only, never secrets. list_access with help: true pulls the format docs; the web admin UI also covers registration.
Verify:
dsh --profile ops --dump-config | grep -A4 'id: agent-presets' # default should be ops
dsh --profile ops --dump-config | grep -A2 'id: session-reference' # should carry disabled: true
Then start an ops session in the web UI: list_access lists your profiles, kubectl resolves them, the trace panel renders, rw credential use raises an approval request.
By default credentials live in a local YAML registry on the dsh host. For a centralized store — one place to register, rotate, and audit credentials — run @elinpf/dsh-ops-access-hub, a standalone service (not a dsh plugin) that keeps every credential in a single AES-256-GCM-encrypted document and serves it over a small token-authenticated HTTP API with a built-in web UI.
Run the hub:
npx @elinpf/dsh-ops-access-hub serve
Options (flag / env / default): --port / ACCESS_HUB_PORT / 3090; --host / ACCESS_HUB_HOST / 127.0.0.1; --data-dir / ACCESS_HUB_DATA_DIR / ~/.dsh-ops-hub; --key-file / ACCESS_HUB_KEY_FILE / <data-dir>/hub.key; --admin-token / ACCESS_HUB_ADMIN_TOKEN and --read-token / ACCESS_HUB_READ_TOKEN / generated and printed once on first start when unset. The master key comes from ACCESS_HUB_KEY (base64/hex) or the key file (auto-generated, mode 0600).
Migrate an existing YAML registry into the hub (path-shaped field values are inlined as file content):
npx @elinpf/dsh-ops-access-hub import ~/.dsh-ops/access.yaml \
--url http://127.0.0.1:3090 --admin-token <admin token>
Offline alternative: --data-dir <dir> instead of --url writes the hub's data file directly.
Point ops-access at the hub via the dsh service's process environment — this is the upgrade-proof seam. The access core lives in the agent preset plane: the profile's cordis.patch.yml only patches the host plane, and the materialized preset file (~/.dsh/.agent-presets/ops/agent.cordis.yml) is rewritten by every preset install. With systemd:
# /etc/systemd/system/<your-dsh-unit>.service
Environment=ACCESS_HUB_URL=http://127.0.0.1:3090
Environment=ACCESS_HUB_READ_TOKEN=<read token>
Environment=ACCESS_HUB_ADMIN_TOKEN=<admin token>
ACCESS_HUB_URL alone flips the source to hub mode; the tokens already had env fallbacks. An explicit source/hubUrl in the preset's ops-access entry wins over the env when present (useful for temporary experiments — just remember it does not survive preset install).
Restart the service afterwards. File-field contents are pulled from the hub per resolve and materialized to TTL-bound cache files under ~/.dsh-ops/hub-cache (mode 0600, swept on expiry and at startup); profiles still carry only paths, and the access gate, probes, admin UI, and tools behave exactly as in YAML mode.
Security notes: v1 speaks plain HTTP — keep the default loopback bind or put the hub behind a TLS-terminating reverse proxy. The hub is a single point of custody: back up both the data file and the master key. The local YAML mode remains available as a fallback at any time.
Paste this into any dsh session and let the agent run the installation and deployment for you:
Read the README at https://github.com/Elinpf/dsh-ops-plugins,
install and deploy the @elinpf/dsh-ops plugin suite into the ops profile,
then confirm with the verification steps in the README.
dsh plugin --profile ops add @elinpf/dsh-ops@latest
npx @elinpf/dsh-ops@latest preset install --agents-home ~/.dsh # the preset is a file on disk — re-copy it
dsh --profile ops --no-open # restart
Use add @latest, not update — update does not cross minors. The preset does not refresh with the package; re-materialize it.
Remove the preset:
npx @elinpf/dsh-ops preset remove --agents-home ~/.dsh
Remove the package:
dsh plugin --profile ops remove @elinpf/dsh-ops
Restart the profile:
dsh --profile ops --no-open
Optionally delete ~/.dsh-ops/ — the credential registry, environment inventory, and referenced credential files.
Uninstalling never touches your clusters: credentials are read-only references to files you own.
docs/adr/; the domain glossary (Chinese) is CONTEXT.mdCLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。