dsh-preset-rules
Keep DeepSeek Harness agent presets under a small, editable rule file — regenerated on every start, so a dsh update never leaves your presets stale.
dsh-preset-rules is a dsh bundle with one host plugin. On boot it reads the preset declarations that ship with your installation, applies your rules, and writes the result to $DSH_HOME/cordis.patch.yml. That file is a normal dsh patch layer: dsh applies it after the profile layer, and its file watcher recomposes the tree when it changes.
Why a generated file
An override written by hand goes stale: when dsh ships a new preset row, a frozen copy silently loses it. Generating the patch at every start keeps the snapshot current without any manual step, and the output stays a plain YAML file you can read, diff, and delete.
Requirements
- dsh 0.2.x
- Node.js >= 20 (the bundled runtime is newer)
Install
dsh plugin --profile desktop add dsh-preset-rules
From a checkout instead of npm:
dsh plugin --profile desktop add github:wannaknowhys/dsh-preset-rules
Or install it from the Harness UI with the plugin manager (Creator mode writes the same bundle patch).
Then write your rules:
node bin/preset-rules.js --init # creates a starter file with commented examples
# $DSH_HOME/preset-rules.rules
presets = all; entry = id: time-context; action = hide()
The plugin never writes rules on its own: with no rules file it logs one line per start (so the first install is not silent) and changes nothing.
Start with check mode — either flip mode: check in the plugin config or run the CLI:
node bin/preset-rules.js --check
It prints what would change and writes nothing. Switch to apply (the default) once you are happy.
Rules
One rule per line, three clauses separated by ; (any order):
presets = all; entry = id: time-context; action = hide()
| clause | values |
|---|---|
presets |
all, an id, {a, b}, not(x), and + / - between them |
entry |
*, id: value, name: value, {a, b}, not(...), + / - |
action |
hide(); disable(), enable(), set(path, value) are reserved for 0.2 |
Binary + and - need spaces on both sides; identifiers may contain -, ., @, /. # starts a comment.
Examples:
presets = not(minimal); entry = id: time-context; action = hide()
presets = {standard, cordis}; entry = not(id: persona); action = hide()
Diagnostics carry file:line:column. An unknown preset or a rule that matches nothing is a warning; a syntax error, an unknown action, or a reserved action stops the run and leaves the previous file untouched.
Modes
| mode | behaviour |
|---|---|
apply (default) |
validate, then write when the bytes changed |
check |
compute and print the result, write nothing |
off |
do nothing |
CLI
node bin/preset-rules.js [--check|--apply] [--rules <file>] [--target <file>] [--source <dir>] [--json]
node bin/preset-rules.js --init [--rules <file>]
Defaults: $DSH_HOME/preset-rules.rules and $DSH_HOME/cordis.patch.yml. --source points at the @deepseek-ai/dsh-web-app package directory; auto-detection covers both a desktop install and an npm install. Reading files inside a packaged app.asar requires Electron-as-node, which is what the desktop app already uses.
Generated file
# generated by dsh-preset-rules 0.1.0 — do not edit
# source: @deepseek-ai/dsh-web-app 0.2.2-rc.1
# source-hash: sha256:…
# rules-hash: sha256:…
- id: preset-cordis
name: '@deepseek-ai/dsh-agent-preset'
config:
id: cordis
order: 4
plugins: [ … ]
No timestamps: identical inputs produce identical bytes, so a start with nothing to do writes nothing.
The file is owned by this plugin. It refuses to overwrite a file that does not start with the marker above — move hand-written patches into the profile layer instead.
Uninstall
Remove the plugin, then delete $DSH_HOME/cordis.patch.yml (or empty your rule file and start once). The generated layer is global to the machine, so every profile on it shares it.
License
MIT
No comments yet. Be the first to write one.