Open-source project
howmp/dsh-pentest avatar
howmp/dsh-pentest

dsh-pentest: a pentest engagement mode for DeepSeek Harness

面向 DeepSeek Harness(dsh)的渗透测试模式 @CloverSecLabs

486 stars61 forksJavaScriptLicense varies

At a glance

What is it?
dsh-pentest turns a DSH session into a structured pentest record: goals, intents, facts, findings and assets linked by typed edges and rendered in a Web tab. It is a recording and reporting layer, not a scanner, and it keeps everything inside one session.
Who is it for?
Adopt dsh-pentest if you already run DeepSeek Harness against authorized targets and want the reasoning trail, findings and asset inventory in one place instead of scattered notes. Skip it if you need cross-session engagements, an automated scanner, or a host older than Node.js 22.5.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What dsh-pentest records that a chat log does not

A normal DSH conversation produces a transcript. dsh-pentest produces a graph. The README describes the storage domain as `pentest` at version 2 with six tables: `goals`, `intents`, `facts`, `findings`, `assets` and `edges`. Those tables are not free-form notes. Each one has a role in a chain of reasoning, and the edges between them carry a fixed vocabulary: `spawns` links a goal to an intent, `yields` links an intent to a fact, `derived_from` links a fact back to an intent, and `proves` links an intent to a finding. Assets relate to each other through a `parent` edge.

The audience is narrow and specific. This is for someone running DeepSeek Harness inside an authorized engagement who wants the exploration trail preserved in a form that can be reviewed afterwards. The README states the protocol section instructs the model to advance along the chain and to interact with the user in Chinese, so the working language of the preset is Chinese even though the plugin code and this review are not.

The design decision worth noting is that a finding cannot be stored without at least one reproducible step. The README lists `reproducibleSteps` as a required field on findings. That is a real constraint on the model: it cannot assert a vulnerability without describing how to reach it. Whether the steps are good is a separate question the schema cannot answer.

How the graph is built: deterministic ids and pure replay

The mechanism that makes this more than a note-taking plugin is in `store.ts`. Node and edge ids follow the pattern `<kind>-<n>`, counted per session, and the goal counter resets to zero when a new goal is added. Because ids are deterministic, a tool call can return an id that the model references in a later call, and the same graph can be reconstructed by replaying the session log.

That replay property is what the session projection in `projection.ts` depends on. It folds the logged `pentest_*` calls into an object shaped as `{ goal, nodes, assets, edges, counts }`, mirroring the store's reference rejections. The projection caps nodes, assets and edges at 200 each. This is the same data the Web tab draws, which is why the README calls the Web graph a window view rather than the record of truth.

Nine tools are exposed, all prefixed `pentest_`. `pentest_submit` lets a sub-agent write directly to a designated parent intent. `pentest_add_goal` resets the whole graph. `pentest_add_intent` takes exactly one anchor. `pentest_add_fact`, `pentest_add_finding` and `pentest_add_asset` add the remaining node kinds, with `pentest_add_asset` accepting an optional `parentId` where an empty string means a root asset. `pentest_state`, `pentest_graph` and `pentest_report` read back. The split between writers and readers is clean, and the fact that the graph resets on a new goal is the single most consequential behaviour to understand before you start.

Installing dsh-pentest from a release tarball

The README gives two install paths, both through the `dsh plugin` command with the `web` profile. The first pulls the latest release asset directly. Run it from a shell where `dsh` is on your path:

powershell
dsh plugin --profile web add https://github.com/howmp/dsh-pentest/releases/latest/download/dsh-pentest.tar.gz

The second path is for a tarball you have already downloaded. Note the `file:` prefix, which is part of the syntax and not a placeholder:

powershell
dsh plugin --profile web add file:C:\path\to\dsh-pentest.tar.gz

After either command, the README says to restart dsh and then select the automatically registered preset named 「渗透模式」 in a new session. If the preset does not appear in the mode selector, the plugin did not register, and the most likely cause is a host that is not running the web profile or is older than the runtime requirement described below.

The package manifest shows the bundle patch is applied through `cordis.patch.yml`, and the published files are limited to `lib/**/*.js`, `preset/pentest/**` and that patch file. The bundle ships its own `zod` and `@deepseek-ai/schemastery` dependencies while the rest of the host is supplied by peer dependencies pinned at `0.1.0-rc.6` for the dsh packages. That pinning is worth checking against your host version before installing.

First engagement: goal, intent, fact, finding

Once the preset is selected, the model gains the `pentest_*` tools. The first call in a session should be `pentest_add_goal`, because it resets the graph and sets the authorization note. The README states the `authorization` parameter accepts a description of the authorization, such as the target and a written permission reference, and that it is written into the state and the final report as an audit fact.

Read that last sentence carefully. The README is explicit that the parameter is not a gate. Scanning and exploitation actions remain constrained by the deployment sandbox and the approval flow, not by what you type into `authorization`. Treating it as a permission check would be a misreading of the design.

After the goal exists, the model adds intents as lines of enquiry, facts as what those enquiries yielded, and findings as what was proven. Assets are added parent-first, and the README notes that an empty `parentId` string means a root asset. When you want to see the result, `pentest_state` and `pentest_report` read the storage layer, so they reflect the full record rather than the 200-item window. The Web tab shows the same graph with four sub-tabs: the exploration chain rendered with `@xyflow/react`, findings with severity, description, reproducible steps and affected assets, assets as either a list or a graph, and the report as rendered Markdown with copy and save actions.

Where dsh-pentest stops: scope, window and layout

The limitations are stated plainly in the README, and they are the part to weigh before adopting.

Records are scoped to a single session. There is no cross-session or cross-project continuation, and starting a new engagement requires a new `pentest_add_goal` call, which resets the graph. If your work spans days and you expect to resume a graph where you left it, this design does not support that. The README says so directly: 记录按单会话作用域,无跨会话/项目续跑.

The Web graph is a window, not the archive. The session projection keeps the latest 200 nodes, assets and edges, and the oldest are evicted once that limit is passed, with dangling edges cleaned up at the same time. The UI counts and the graph therefore show the window. The complete record lives in the storage layer and is reachable through `pentest_state` and `pentest_report`. A large engagement will look truncated in the browser even though nothing has been lost.

Two smaller constraints matter for daily use. The graph layout is static and layered, so nodes can be panned and zoomed but not dragged. And the sqlite backend uses Node.js `node:sqlite`, which the README says requires a host runtime of Node.js 22.5 or higher. On an older host the storage backend will not load.

dsh-pentest against ARTEX, and against plain notes

The README lists ARTEX as a reference project. The two solve overlapping problems from opposite directions. ARTEX, as its own repository describes it, is an automated penetration testing tool that runs the testing itself. dsh-pentest does not scan anything. It provides a schema and a set of tools so that a DSH agent can record what it did, with a protocol section that pushes the model along the chain from goal to finding.

That difference decides the choice. If you want the tool to find the vulnerabilities, dsh-pentest is the wrong layer entirely, because it has no scanning capability of its own. If you already have an agent doing the work and the problem is that the reasoning and results evaporate into a transcript, dsh-pentest addresses exactly that.

The same comparison applies to a plain Markdown file or a spreadsheet. A notes file has no schema, so nothing prevents a finding without steps. dsh-pentest enforces `reproducibleSteps` at the tool boundary and links findings to the intents that proved them and the assets they affect. The cost is that you are now maintaining a graph inside a specific host, with a specific runtime requirement and a session-scoped lifetime.

Licence, upgrade cost and the rc versioning

The package manifest declares `"license": "MIT"`. The repository metadata does not list a licence, so the manifest is the only place the identifier appears. MIT is permissive, which means bundling the plugin into an internal deployment is straightforward, but this is a description of what the file says and not legal advice. If you redistribute the bundle, check whether the peer packages it depends on carry compatible terms, since those come from the host and not from this package.

The version string is `0.1.0-rc.30`, and the recent release list shows `rc.28`, `rc.29` and `rc.30` published on 2026-09-10 and 2026-09-11. Three release candidates in two days is a fast cadence, and the rc suffix signals that the author does not yet consider the interface stable. The last push to the repository was on 2026-09-11. Plan for the possibility that tool parameters or the storage domain version change between releases; the README already names the domain as version 2, which implies it has changed at least once.

Upgrading is the same command as installing, pointed at the newer tarball, followed by a dsh restart. The README does not document rollback, migration between storage domain versions, or what happens to an existing `pentest-sessions.db` when the schema changes. That gap is the main operational risk to verify on your own before upgrading a database you care about.

Editorial conclusion

Adopt dsh-pentest if you already run DeepSeek Harness against authorized targets and want the reasoning trail, findings and asset inventory in one place instead of scattered notes. Skip it if you need cross-session engagements, an automated scanner, or a host older than Node.js 22.5. Before committing, verify three things: that your dsh host is a web profile with Node.js 22.5 or newer, that $DSH_HOME/storages/pentest-sessions.db is written where you expect, and that the 200-node window in the Web tab is large enough for the engagements you plan to record, since pentest_state and pentest_report read the storage layer rather than that window.

Frequently asked questions

What is the full meaning of DSH in dsh-pentest?

DSH stands for DeepSeek Harness, the host application this plugin extends. The package name `@howmp/dsh-pentest` and the peer dependencies on `@deepseek-ai/dsh-*` packages both refer to that host.

What skills are needed for DSH?

The README does not describe prerequisites for using DeepSeek Harness itself. The only runtime requirement it states for this plugin is Node.js 22.5 or higher, because the sqlite backend uses `node:sqlite`.

How do I install dsh-pentest?

Install the release tarball with `dsh plugin --profile web add` pointed at the latest release download URL, or at a local file using the `file:` prefix. Restart dsh afterwards and select the 「渗透模式」 preset in a new session.

Does dsh-pentest scan targets for me?

No. It provides nine `pentest_*` tools and a protocol section so a DSH agent can record goals, intents, facts, findings and assets. The README describes it as a recording mode, and scanning or exploitation actions remain subject to the deployment sandbox and approval flow.

Why does the Web graph show fewer nodes than pentest_state?

The session projection keeps the latest 200 nodes, assets and edges and evicts the oldest, cleaning up dangling edges as it goes. `pentest_state` and `pentest_report` read the storage layer, so they reflect the complete record.

Can I continue an engagement in a new session?

No. The README states records are scoped to a single session with no cross-session or project continuation, and starting a new engagement requires a new `pentest_add_goal`, which resets the graph.

Official sources

  1. howmp/dsh-pentest on GitHub
  2. Issues
  3. README
  4. Releases
Community notes

Community notes