DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-aiignore

Aiignore

See what a conversation feeds the model, what your rules keep out, and what one click would change.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-aiignore@0.38.2
READMECompatibilityVersions

Compatibility and provenance

Aiignore is published as dsh-aiignore and currently resolves to version 0.38.2. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/4/2026

Versions

0.38.2stable
11/1/2026
0.38.1stable
11/1/2026
0.38.0stable
10/31/2026
Show 47 more versionsCollapse versions
0.37.1stable
10/31/2026
0.37.0stable
10/30/2026
0.36.0stable
10/30/2026
0.35.0stable
10/30/2026
0.34.0stable
10/30/2026
0.33.0stable
10/30/2026
0.32.0stable
10/30/2026
0.31.0stable
10/30/2026
0.30.0stable
10/30/2026
0.29.1stable
10/30/2026
0.29.0stable
10/30/2026
0.28.0stable
10/30/2026
0.27.0stable
10/30/2026
0.26.3stable
10/30/2026
0.26.2stable
10/29/2026
0.26.1stable
10/29/2026
0.26.0stable
10/29/2026
0.25.0stable
10/29/2026

Related plugins

Loading related plugins…

Latest
0.38.2
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
367.4 kB
Files
13
Surface
web
License
Apache-2.0
Source
npm
GitHub
★ 1
Weekly downloads
9,712
Security scan
✓ v0.38.2 scan passed
Last push
11/4/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
0.24.5stable
10/29/2026
0.24.4stable
10/29/2026
0.24.3stable
10/29/2026
0.24.2stable
10/29/2026
0.24.1stable
10/29/2026
0.24.0stable
10/29/2026
0.23.1stable
10/29/2026
0.23.0stable
10/29/2026
0.22.0stable
10/29/2026
0.21.0stable
10/28/2026
0.19.0stable
10/28/2026
0.18.0stable
10/28/2026
0.17.0stable
10/28/2026
0.16.0stable
10/28/2026
0.15.0stable
10/28/2026
0.14.0stable
10/28/2026
0.13.0stable
10/28/2026
0.12.0stable
10/28/2026
0.11.0stable
10/28/2026
0.10.0stable
10/28/2026
0.9.0stable
10/28/2026
0.8.0stable
10/28/2026
0.7.0stable
10/28/2026
0.6.0stable
10/28/2026
0.5.0stable
10/28/2026
0.4.0stable
10/28/2026
0.3.0stable
10/28/2026
0.2.1stable
10/27/2026
0.2.0stable
10/27/2026

Related plugins

More verified plugins in models-usage.

Connect Workbuddydsh-connect-workbuddyConnects locally signed-in WorkBuddy models (domestic and international versions) to DeepSeek Harness, automatically reading each model’s points multiplier from the upstream catalog on every refresh, with per-model image input toggles, multi-account switching, automatic account rotation from an accoCost Meterdsh-cost-meterDeepSeek Harness session cost statistics plugin: tracks current session costs, today’s expenses, and historical records, with synchronization to official pricing. Supports billing across multiple vendors and models, with a built-in catalog of prices for 170+ model IDs and automatic matching. Also suCodex Subscriptiondsh-codex-subscriptionUse ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images and Fast mode, and control DSH from the ChatGPT mobile app (Beta)Xdpooldsh-xdpoolOne DSH model pool for every free quota you have: merge all locally signed-in WorkBuddy accounts with auto-failover, sign in to 13 vendors by QR/web, aggregate 76 vendors' free tiers, plus a usage dashboard, model routing, a local OpenAI-compatible gatewa

README

dsh-aiignore — context noise guard for DeepSeek Harness

A Host plugin that checks a workspace when a session opens it and tells the agent which files would waste its context — build output, lockfiles, logs, huge files.

The scan is the same one the ai-context-doctor CLI runs; this package only decides when to run it and how to phrase the result for the model. Everything is local: no network, no API key, no upload.

Requirements

DeepSeek Harness>= 0.2.0 — the version that ships sidebarRightTabs; declared as engines.dsh in package.json and in every market-index entry, so an older Harness refuses the install instead of half-loading it
Node.js>= 18 — the Host half uses node:test and structuredClone
Permissionsnone. No network, no API key, no telemetry; it reads the workspace and writes .aiignore and .aiignore.policy.json

Without a sidebar service the same button opens the panel as a floating card, so an older or trimmed-down Harness still gets the report, just not the tab.

What the agent sees

When a workspace scores below the threshold, the agent receives one short note before it starts reading files:

[ai-context-doctor] This workspace scores 29/100 for context health: 71% of 1.7 MB in 24 files is likely noise.
Biggest offenders: dist/ (400.0 KB, generated build output), package-lock.json (400.0 KB, lockfile).
Suggested .aiignore: dist/, package-lock.json, *.log.
Do not read those files unless the task needs them; ask before opening large generated files.

Clean workspaces get no message at all — a plugin that speaks on every session becomes noise itself.

The panel

The bundle also ships a browser half. A folder button sits beside the add-files button in the composer; clicking it opens the right sidebar on the AIignore tab, and expands the sidebar if it was collapsed. On a Host without sidebar services the same button opens the panel as a floating card instead, so one plugin covers both.

The Protection tab, light theme

The Files tab: what this session read and wrote

Three tabs inside, and the first one exists to answer a single question: is this doing anything?

  • Protection — a score, one button, and nothing else competing with them. The number is this conversation's current score: the one it would have if the rules in force applied to what it actually read. There is no before → after pair to read — one number, and it moves when the rules or the strength move, because it is computed from them. (The folder's own score, rules and all, lives on Settings as On disk 22 · Reaches the model 71, where the arithmetic belongs.) A folder nobody has scanned says not scanned yet rather than printing a dash under a label that promises a number, and a conversation that read nothing junk-worthy says so in words instead of a zero. Optimize now is always there — it rescans, writes whatever is missing, re-scores, and reports what moved, so the interaction is: look, press, watch the number change. The strength ladder is one click away in Fine-tune the strength: five notches, each labelled with the score this folder would have there, because five scores at once answer a question nobody asked yet. Picking a notch writes it, rescans and repaints from the new report. Below that, one notch stricter with the number attached ("would block 2 more files, about 65k–81k tokens"), then the files actually kept out and how many rules are in force.

  • Files — opens on the files this session touched (what the agent read and what it wrote), then lets you browse the whole workspace a directory at a time. Search, filter by verdict — and when a filter has nothing in it, the panel says which filter that was instead of looking empty. The three verdicts are spelled out right under the filters: noise is regenerated by a build, a lockfile or a log; review is worth a look before it goes in (env files, deploy scripts, big data); ignored already has a line in .aiignore. Under that, Worth a rule lists what the scanner would still add (+ *.log, + coverage/) — one click writes the line and rescans. A noise file's detail card offers the widest rule that covers it, Add dist/, not only its own path, because a per-file line is a rule you write again every build.

  • Settings — everything you can change, off the screen that answers is it working: Rules in .aiignore with an × per line, the note for the agent with a preview of exactly the text it will read, and the five-dimension arithmetic folded away at the bottom. It points at Protection for the strength ladder instead of keeping a second copy of it — two controls for one setting drift, and the copy that stops being authoritative is always the one on the page nobody is looking at.

The words this panel uses

Five terms carry most of the panel, and they are used the same way everywhere — in the tabs, the tooltips, the changelog and this file.

TermMeansNot to be confused with
held backa read your rules stopped, or would stop. The counter, the list under it and the badge all say this.refused — the guard turning a read away right now
ruleone line in .aiignore, matched against pathsa note, which is text for the agent, not a rule
notchone of the five strength settings, from Off to Strictthe score, which the notch changes
scoretwo numbers: this conversation, and what still reaches the modeltokens, which are a byte-based estimate
noisebuild output, lockfiles, logs, generated files and anything over 1 MBreview, which means look before you decide

Following the conversation, not a folder

The panel asks the Host who the current conversation is, and the Host reads the session store: <DSH_HOME>/sessions/*/session-*/session.v4.jsonl.zstd is an append-only zstd file whose first frame is a JSON header carrying the session id and its cwd. The most recently written log is the conversation in front of you, and its header names the folder — no guessing from directory names, and no dependency on the workspace index ever having been told about that session. The header names the workspace; the guard, the score and the file list then all speak about that one folder.

The Chat tab's picker shows the conversations this app knows about, newest first, with current on the live one. Picking an older one re-reads that conversation — header title, turn count and file list all switch — and a showing an earlier conversation chip appears in the header; clicking it takes you back to the live one.

The folder button keeps a menu: follow this conversation (the default), pick another folder…, or stop pinning — so a choice made once is a choice you can take back. Every workspace this app has been used in is also listed on the Context across your workspaces page in the left rail, scored with the same rules.

One click, with a way back

Optimize this workspace appends the scanner's suggestion to .aiignore, keeping the lines already there, then reports the score before and after. The previous file is held in memory for the session, so Undo puts it back byte for byte — and if optimize created the file, undo removes it.

Two decisions per file, available from the tree, the session list and the report:

  • Read once (the report calls it Read it anyway) pre-approves a path for the rest of the Host run, including one the session has not tried yet. Reloading the Harness forgets it — a temporary override should stay temporary.
  • Never read it appends the path to the workspace's .aiignore. That is the durable direction, because the file is the record: it survives restarts, shows up in review, and you can delete the line yourself.

One workspace can hold many conversations, so the panel never averages them: the Chat tab's picker lists the conversations this app knows, marks the one currently open, and every number above it is that conversation's. There is no separate "follow" entry in the picker — the folder button already means follow, and two controls for one state is one control too many. When the session store cannot answer, the panel falls back to the directory the slot hands it (?cwd=), then to the agent and session registries, then to whatever was scanned last. Only an absolute path to an existing directory is accepted.

The aggregate view lives in the left rail, under New Session: AIignore lists every conversation this app has run, worst first, and can act without opening any of them. Each row shows the conversation's title, folder, turns, files read and size; the score on the left is the one your rules and strength leave behind, with the pre-rule number trailing behind it when the two differ, and a N kept out badge once a clean-up covers something. Scan again refreshes, Clean up N writes that conversation's suggestions, Open the panel jumps to it. It is served by GET /aiignore/conversations (twenty-one routes in total).

Both numbers are computed from the session projection, never from a guess: the conversation score is what that chat was actually handed, and the effective score re-runs the same decision the guard uses — rules, then strength — so a conversation that read dist/ before you had a rule shows 74 and 100 afterwards, with the file named under No longer reaching the model.

Styling comes from the Host's design tokens (--dsw-*) with fallbacks, so the panel follows light and dark themes instead of shipping its own palette. Every control is reachable with Tab.

Loading, empty and failure are three states of one component, on all three surfaces that fetch anything (the panel, the left page, the strength table): a skeleton while a request is in flight, one sentence when there is nothing to show, and an error that names what failed, carries the real status (status 500), and offers a retry that repeats the same request. Nothing silently disappears — the strength table used to vanish while it loaded — and nothing invents a cause: an unreachable server says network, a rejected one says the status.

The panel talks to the Host half over twenty-one same-origin routes (GET /aiignore/report, GET /aiignore/tree?dir=, GET /aiignore/overview, GET /aiignore/sessions, GET /aiignore/workspaces, GET /aiignore/levels, GET /aiignore/debug, GET/POST /aiignore/notes, GET/POST /aiignore/policy, GET /aiignore/upload?digest=, POST /aiignore/scan, POST /aiignore/client-report, POST /aiignore/optimize, POST /aiignore/optimize/undo, POST /aiignore/allow, POST /aiignore/ignore, POST /aiignore/unignore, POST /aiignore/rules, POST /aiignore/rules/delete). The upload route serves a thumbnail and refuses anything that is not a 64-hex digest inside the attachment store; the unignore route removes the rule that names a file and refuses symlinks and directories, while rules/delete removes one rule line by its exact text (dist/, *.log) and never touches a comment, while rules writes one rule that was suggested without a file to name (*.log) — it checks the shape (relative, no .., no leading /) and clears the scan caches so the next read sees it. They answer for the most recently scanned workspace and set no-store; the only one that returns file bytes is the upload thumbnail, and it only ever returns an image the user already handed to this session. The Host half installs them through ctx.inject(['webServer']), so a profile without a web server still gets the read guard — it just has no panel. There is no authentication beyond a same-origin check: like every ctx.webServer route, this one inherits the loopback bind of the Harness and must not be exposed to a network.

The Protection tab, dark theme

Settings, dark theme: rules and the note for the agent

When something looks wrong

Settings ends with a Diagnostics fold: plugin version, Node, platform, data folder, workspace, how many conversations it can see, how many rules are in effect, and which surface (sidebar tab or floating card) you got. One button copies it as plain text.

It is built to be pasted in public — the home directory is shortened to ~ and there is no token, session id or conversation title anywhere in it.

Looking at the panel without a Harness

dev/preview.html renders the real panel against the Host's real design tokens with mock data: both themes, four scenarios (noisy, healthy, freshly opened, request failing), and ?nosidebar=1 to see the floating-card fallback. Open the file in a browser; no build, no server. It is a development page and is not part of the published package.

Behaviour tests

test/interaction.test.mjs mounts the real client.js in Node — jsdom, the real React, a host context that records what the bundle registers, and stubbed /aiignore/* routes — and then does what a person does:

const panel = await mountClient({ file: 'client.js', fetch: createFetch(routes) });
await panel.press('#aicd-tab-protect', 'ArrowRight');   // the tab moves
await panel.click('[data-aicd-menu-btn]');               // the menu opens
await panel.press('[role="menu"]', 'Escape');            // and closes on Escape
await panel.click('[data-wide="true"]');                 // Optimize posts once
assert.match(panel.text(), /96/);                        // and the score moves

The tool is dsh-plugin-toolkit/testkit. The older *.test.mjs guards that read this file as text are still here: they are fast and they catch a deleted string, but they could never have caught the bug where Optimize was hidden — only mounting it could.

Visual baselines

docs/assets/baseline/ holds the eight screenshots the panel is measured against: four preview scenarios (noisy, healthy, fresh, broken) in both themes, cropped to the 420 × 660 the sidebar actually gives it. They are committed, not generated in CI — this repository has no headless browser.

After an intentional visual change, re-capture all eight. Each one is a cold load of its own URL, which the manifest records per file:

dev/preview.html?scenario=noisy&theme=light
dev/preview.html?scenario=noisy&theme=dark
...  (healthy, fresh, broken × light, dark)

Open each URL at 1280 × 800, crop to the panel, and rewrite docs/assets/baseline/manifest.json with each file's size, SHA-256 and URL. The URL is not decoration: three baselines once drifted because they had been taken with ?first=1 and ?failreport=1 and nothing recorded it, so the difference looked like a rendering bug. Then run:

node plugin/scripts/check-baseline.mjs

It fails when a baseline is missing, edited by hand, or left out of the manifest — the change that looks like a small fix but moves everything.

The crop is fixed so the images stay comparable: with the preview open at 1280 × 800, the panel occupies (861, 100) to (1281, 760) — the preview's own toolbar sits above it, and a crop that included it would compare the harness.

Install

Through the Plugin Manager:

  • From npm — install dsh-aiignore.
  • From a checkout — install the plugin/ directory of this repository.

Installing a local directory links it, so re-check the files directly: files does not filter a linked directory.

From the plugin market

Harness has no central store: the Discover tab lists whatever indexes the user adds. This repository publishes one at

https://raw.githubusercontent.com/WJDdidi-1/ai-context-doctor/main/market/index.json

To use it:

  1. Open Plugins in the Web sidebar.
  2. Beside Experimental plugins, open More and switch on Custom plugin markets. The Plugins page then gains an Installed / Discover split.
  3. In Discover, add the index URL above.
  4. Install dsh-aiignore from the result.

The Harness checks the declared engines.dsh range before installing and refuses the plugin if the running version falls outside it.

Configure

Values go in the plugin's config row in cordis.patch.yml:

- insert:
    - id: ai-context-doctor
      name: 'dsh-aiignore'
      config:
        healthThreshold: 80
        maxFiles: 20000
        maxBytes: 268435456
keydefaultmeaning
healthThreshold80Inject only when the workspace scores below this. 100 disables the notice without uninstalling.
maxFiles20000Stop scanning after this many files.
maxBytes268435456Stop scanning after this many bytes (256 MiB).
readPolicydenydeny refuses read calls on the noisy files below; off only warns at session start.

The caps exist because the scan is a synchronous directory walk: without them, opening a huge monorepo would stall the Host.

The guard also refuses anything the workspace's own .aiignore lists, including files the size heuristic considers clean. A hand-written rule beats the heuristic, and editing the file takes effect on the next read.

What it refuses to read

With readPolicy: deny, the plugin installs a tool guard that refuses read calls on the same files the notice names:

refusedwhy
dist/, build/, coverage/, .next/, .turbo/generated output; the source is what matters
package-lock.json, pnpm-lock.yaml, yarn.lockthousands of lines of resolved versions
*.loglocal run output, usually stale
files over 1 MiBa single read can consume the whole budget

The refusal is a message, not a silent failure: it names the file, its size and the tokens the read would have cost, so the agent can tell the user instead of retrying. Templates like .env.example and scripts with deploy in the path are never blocked — they are small, and a wrong guess there loses real information.

Every refusal is recorded per workspace (getSkippedReads) so the UI half can list what this session did not open.

Limits

  • The notice fires once per workspace per Host run; changing the directory in a session does not re-trigger it.
  • The score is a size heuristic; token figures are a range from the measured 3.08–4.32 bytes-per-token ratio, not an exact count.
  • bash, grep and other tools that can read a file indirectly are not intercepted: the guard only sees the read tool.
  • .gitignore is ignored on purpose: the point is what the agent would read, not what git tracks.
  • The panel follows the conversation whose log was written last. Switching to a conversation you have not touched since this Host run started moves it only after that conversation writes something, so it can lag one click behind.
  • Switching the interface language takes effect the next time the panel opens; the open panel does not re-render.

License

Apache-2.0. See LICENSE at the repository root and NOTICE beside this file: the plugin contains no third-party source, and its only runtime dependency is ai-context-doctor from the same repository.

It no longer asks you to imagine what the note does: three one-click sentences, then a preview of exactly the text the agent will read before your next message.

  • One button runs the job. Optimize now reads the folder, writes the rules, re-scores and moves the number on screen. While it runs you see the two steps it actually performs, each marked done only when its work is finished — no percentage bar inventing progress the Host never reported.

  • The rules are visible, and removable one at a time. Under the score sits Rules in .aiignore: every line that is in force, each with an ×. Removing one edits exactly that line — comments and the other rules stay — so a rule you disagree with is one click away instead of an all-or-nothing undo.

  • The strength is part of the score, not a separate page. Five buttons from Off to Strict, each already scored against your workspace before you commit to one, so the difference between Balanced and Strict is a number you read instead of a slider you drag. There is no slider any more: two ways to say the same thing was one too many. Each notch says what it stops and what that costs; the Host stores it in .aiignore.policy.json; the read guard and the scan share the same predicate, so saving a notch re-scans and the number moves.