dsh-plugin-agentcss: Add a layer of deliverable self-check to the agent's report page

Preface

The most common failure mode when letting models write HTML reports directly is not throwing exceptions, but silent failure: class names are made up by the model from memory, so that section has no style after the page opens; a <link> is missing from the <head>, all component class names are correct, but the whole section has no style; the skeleton hierarchy is wrong, the layout collapses, and the console doesn’t throw an error. The common point of these three situations is that they will not be discovered until someone opens the page.

owain323/dsh-plugin-agentcss is designed to tackle these three types of problems. It is a plugin for DeepSeek Harness, maintained by owain323, categorized under “Workflows” in the community directory SkillHub (the directory page shows current 0 stars), under the MIT License. It wraps the agentcss report page library into four tools that models can call directly: query components, generate page skeleton, self-check before delivery, and export PDF.

Below introduces the plugin’s specific capabilities, installation method, and an actual usage round.

What it solves

The README lists these three pitfalls clearly:

Pitfall Phenomenon Who can discover
Class names made up from memory Page doesn’t throw an error, just that section has no style No one, until someone opens it
Missing a <link> in <head> Component class names are all correct, but that part has no style at all No one, until someone opens it
Wrong skeleton hierarchy Layout collapses, but no exception is thrown No one, until someone opens it

Existing approaches are either to let the model copy the entire library into the page (large size, version drift), or to manually open the file for inspection after writing. This plugin chooses the third path: let the model query the library, generate according to rules, and then machine self-check blocks these three types of problems before delivery. It explicitly does not contain component definitions; components, tokens, and criteria all come from npm’s agentcss.

The Four Tools

The tools registered by the plugin all start with agentcss_. The four tools correspond to “Query, Generate, Deliver, Export”.

  1. agentcss_catalog: Call before writing HTML. Search by keyword or layer. Returns component ID, layer, root class name, path to required stylesheet, and a one-line purpose. Use it first if you need additional components.

  2. agentcss_new_page: Start a new page from here, do not hand-write <head>. Returns a self-contained directory with index.html and agentcss/ (a copy of the library stylesheet).

  3. agentcss_check: Run once after modifying the page. Returns a structured list of issues, each with rule name, line number, level, and description.

  4. agentcss_pdf: Use when content is finalized, needs to be sent out, or needs to be handed over for printing. Returns PDF path, page count, paper size, byte count; if there is a JS exception, it will name the culprit.

The checks in agentcss_check include: is the class name in the library, does the class exist but the page hasn’t imported the stylesheet that defines it, are images missing alt, do headers have scope, are there heading level jumps, do form controls have readable names, are IDs duplicated. It is a purely static check, does not connect to the network, does not open a browser.

agentcss_pdf launches a local Chrome/Edge instance, does not open ports, and does not reuse your browser configuration. The export sequence is fixed by the library: page load → font ready → optional visible elements → extra wait → freeze animation → print. When it fails or exceeds the page count budget, it does not rewrite the old PDF, nor does it truncate content for you—the README states that truncation is silently dropping data, which is much more dangerous than stopping with an error.

Installation & Enablement

The installation commands come directly from the README. In Harness, “Add Plugin” has three entries: npm package name (recommended, version follows the library), GitHub address, and local directory. The command line equivalent:

# Install from npm
dsh plugin --profile desktop add dsh-plugin-agentcss

# Or install from GitHub (tracks main)
dsh plugin --profile desktop add https://github.com/owain323/dsh-plugin-agentcss

After installation, Harness needs to be restarted for the tools to appear in the model’s callable list.

Typical Round

The following flow is taken from an example in the README:

User: Use agentcss to make a Q3 revenue analysis page, put it in /work/reports/q3

Model → agentcss_new_page({ dir: "/work/reports/q3", recipe: "report/finance" })
     ← /work/reports/q3/index.html generated; stylesheet copied to …/agentcss

Model writes content (use agentcss_catalog to check if extra components are needed)

Model → agentcss_check({ path: "/work/reports/q3/index.html", recipe: "report/finance" })
     ← Failed: 1 error
          L42  error  class-not-linked  .bar is in the library, but this page didn't import 09-assets/bar/bar.css

Model adds a <link>, runs again → Passed: 0 error · 0 warn

The key point is: do not hand-write <head> and skeleton first, let agentcss_new_page generate them; after writing the content, use agentcss_check to verify; when ready to deliver, run agentcss_pdf. Both dir and path must be passed as absolute paths; passing the wrong one will result in an explicit error, it will not guess.

Dependencies & Compatibility

The compatibility table given in the README:

Item Requirement
Node >= 18 (Harness desktop version comes with 24)
agentcss ^0.27.5
Harness 0.2.x tested (0.2.2-rc.1)

The lower limit of ^0.27.5 was not chosen randomly. The README explained that half of the capabilities depend on the library layer: before 0.27.3 it was gray background light text; before 0.27.4 images inside .rep__fig had no width constraint, a 1920px screenshot would break the whole page; 0.27.5 unified the repository name and package name and changed the site root path to /agentcss/. None of these three things are obvious on the screen; you only know by printing them out or seeing them in the URL. The caret range for 0.x is only within the same minor version; when the library releases 0.28, the plugin needs to be upgraded once.

The other two deliberate choices are worth knowing:

  • Does not depend on any @deepseek-ai/* package. Does not use defineTool, directly uses ctx.tools.register() to register bare definitions. The README points out that defineTool is just a wrapper that compiles parameters into JSON Schema; they are equivalent, and having one fewer peer dependency means fewer whole classes of version resolution failures.
  • Does not declare engines.dsh. 0.2.x is a pre-release version; semver’s pre-release rules will cause ranges like >=0.2.0 to fail the check, causing the installation to be directly rejected.

Known Limitations

  1. dir / path must be passed as absolute paths. Passing the wrong one will result in an explicit error, it will not guess.

  2. When creating a page, the library stylesheet is copied next to the page, about 340 KB, 80 files. This is trading volume for self-containment: the page can be opened by double-clicking, no network requests are sent, and styles won’t be lost when sent to others.

  3. ai shot (screenshot health check for horizontal overflow and JS errors) hasn’t been integrated yet. The README explicitly states it is a “look” loop, not on the same line as “write correctly + send out” here.

  4. PDF is a screen rendering result. Paper size, driver scaling, duplex printing, headers, and footers for physical printers still need manual proofing once; agentcss_pdf does not claim to have verified them for you.

  5. agentcss_new_page does not overwrite existing files by default. When the target index.html exists, it defaults to rejection unless overwrite: true is explicitly passed.

  6. The package itself is only about 700 lines of adaptation code (including comments), with absolutely no component definitions. Components, tokens, and criteria all come from npm’s agentcss; the agentcss_check class name whitelist is calculated from the library’s CSS on the fly. The README explains the reason for this: copying a component tree over means two copies of the truth exist simultaneously; changing a token once starts desynchronization, and each side runs its own gatekeeping, so no one will discover the issue.

Use Cases & Notes

Suitable scenarios: using Harness to write HTML report pages, wanting to use a set of predefined component libraries and layouts, needing a machine self-check before manual opening, needing to export the page to PDF for sending.

Points to note:

  • This plugin runs with the permissions of the current dsh process. It can launch local Chrome to export PDF and read/write files in arbitrary locations according to absolute paths. Before installing, read the source code and license (MIT, the package’s files includes index.js, cordis.patch.yml, README.md, LICENSE).
  • The package’s dsh.bundle.patch points to cordis.patch.yml, indicating that a patch will be applied to Harness’s packaging phase during installation. This is the plugin’s own adaptation; it is worth opening this file before integrating a third-party plugin to see what was changed.
  • The library is 0.x, ^0.27.5 means minor upgrades will bring behavioral changes. When upgrading the plugin, pay attention to the agentcss range it declares; do not upgrade the library separately.
  • The directory page (SkillHub) is a community site, with no official affiliation with DeepSeek or Hypothesis, and does not represent this as an official app store entry.
  • Areas requiring manual fallback: printing on a physical printer for proofing, and the act of “looking once to see if it renders correctly”, which the plugin currently does not cover.

Conclusion

The value of this plugin lies not in having one more component library, but in building a gate before delivery for the model: the page skeleton is generated according to rules, class names and stylesheet references can be queried and self-checked, and if the self-check fails, it does not wrap up; if PDF fails, it would rather stop than silently truncate. It solves problems of the “no error but not pretty” type; without this gate, such problems can only be discovered by humans opening the page.

  • Directory page: https://www.skillhub.cn/plugins/owain323/dsh-plugin-agentcss
  • GitHub: https://github.com/owain323/dsh-plugin-agentcss
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye