dsh-skill-scribe: Turn repetitive work into SKILL.md, but scripts don't count

Introduction

When agents are working, the most frequent repetition is not reasoning, but that sequence of fixed actions: reading files, grouping by a certain field, aggregating, and writing to another location. The Skill (SKILL.md) exists to save these steps for reuse. There is a class of approach called “auto-save skills,” similar to Hermes, where if the model feels it has learned something, it directly saves it as a skill and loads it next time it encounters a similar task.

The problem with this path isn’t in saving, but in timing: you don’t know when it saved, nor when it will be loaded. A skill written for “summarizing a certain type of CSV” could be matched in a completely unrelated conversation, then intervene in a way you didn’t expect. By the time you discover it afterwards, a lot of things have been changed. Therefore, the thinking behind writing dsh-skill-scribe takes half a step back: saving remains automatic, but enabling it is left to the user. Candidates are generated as usual, but only after you accept it does it become a skill.

What is it

dsh-skill-scribe is a plugin for DeepSeek Harness (dsh), belonging to the “workflow” category. It is positioned as an editor: at the end of every turn (round), the plugin reviews what was done in that turn; if the steps look reusable, it asks the model to draft a SKILL.md and place it in a review directory. The draft will not be loaded until confirmed.

The plugin is maintained by MaresaN41 (the author field inside the package says MaresaN). The repository README is written for the author’s own use, and the documentation itself is written by AI, so there are many edge cases; this will be mentioned later.

License is MIT, requires Node.js 20.3 or higher, and dsh version requires >=0.2.0-rc.2 <0.3 (the author has verified on 0.2.0-rc.2 and 0.2.1-rc.5).

What it does

The premise for looking further is: the plugin itself does not execute commands; it only drafts text, and whether to execute is always decided by the caller.

  1. After a normal turn ends, if the number of tool calls in that turn reaches a threshold (default 3, configurable), the plugin hands this turn’s work to the model to judge if it is reusable; if so, it drafts a SKILL.md.
  2. If an existing skill was used in that turn, the plugin does not create a new skill, but instead generates a “patch”, which you can view with diff to see what changed.
  3. Before sending text to the model or writing to files, identifiable secrets like API keys are obscured.
  4. Drafting uses the model of the current session, including OpenAI-compatible local models; an alternative endpoint can also be configured.

The form of a skill draft is the front matter of SKILL.md plus step descriptions:

---
name: csv-aggregate-by-date
description: "Aggregates numeric columns in a CSV file by grouping on a date column"
whenToUse: "When summarizing transactional or time-series data by calendar date"
---

# CSV Aggregate by Date

## Steps
1. Read the input CSV file to extract date and amount columns
2. Group rows by the date column
3. Sum the amount values for each unique date
4. Write the aggregated data to a new CSV file

## Notes
- Works with any CSV where one column is a date and another is numeric

Installation and enabling

The README provides two ways. The first is to clone it and install using an absolute path:

git clone https://github.com/MaresaN41/dsh-skill-scribe.git
dsh plugin --profile <profile> add /absolute/path/to/dsh-skill-scribe

Replace <profile> with your dsh profile name, and the path with the absolute path of the clone. The plugin is automatically registered via dsh.bundle.patch in the package, no need to add --patch extra.

The second is to not clone and install directly from GitHub:

dsh plugin --profile <profile> add github:MaresaN41/dsh-skill-scribe

Running tests requires dsh’s peer packages:

npm test
npm pack --dry-run

Typical usage

Run a task in a dsh session that will use tools several times. At the end of the turn, the plugin drafts the candidate in the background. Afterwards:

cd dsh-skill-scribe
node bin/scribe.js list

The output looks like:

id                     kind  created                   drafter  task
csv-aggregate-by-date  new   2026-11-04T22:44:10.340Z  llm      Sum amount by date ...

Look at the content, then decide whether to accept or reject:

node bin/scribe.js show csv-aggregate-by-date
node bin/scribe.js accept csv-aggregate-by-date

After accept, this skill becomes available starting from the next session. Use reject to reject; it will be moved to rejected/ instead of deleted, kept for records.

There are three entry points for commands: in the repo it’s node bin/scribe.js <cmd>, under the profile’s node_modules/.bin it’s scribe <cmd>, and inside dsh you can directly type /scribe <cmd>.

Command Description
list Lists pending candidates for approval
show <id> Shows the candidate and metadata
diff <id> [--project <dir>] [--dest <dir>] Compares candidate with existing skills
accept <id> [--project <dir>] [--dest <dir>] Finalizes the skill
reject <id> Moves to rejected/

The default write location for accept is $DSH_HOME/skills; with --project <dir> it writes to <dir>/.dsh/skills; with --dest <dir> it writes to the location you specify. If a skill with the same name already exists, it backs up the existing one before overwriting. The rules for the patch destination are the same: if the original skill is in another location, the original file is not moved, and accept will prompt you.

When candidates are not generated

It is only generated when all conditions are met:

  • The turn completes without errors;
  • Tool calls reach minToolCalls (reading skills does not count);
  • The model judges this is a reusable step;
  • The draft passes format checking (retry only once);
  • The daily limit is not reached;
  • A previous draft in the same session is not in progress (turns ending during the in-progress period will be skipped);
  • The draft is completed before the process ends.

Configuration

All configurations can be omitted and written in the profile’s cordis.patch.yml:

- id: skill-scribe
  config:
    minToolCalls: 5
    language: ja
Config Default Description
enabled true Plugin switch
minToolCalls 3 Minimum number of tool calls in a turn
model Follows session { provider, model } for drafting
endpoint None Fallback OpenAI-compatible address { baseURL, model, apiKeyEnv }
language "auto" Draft language, auto follows the request text
maxProposalsPerDay 10 Daily candidate limit
timeoutMs 180000 Model call timeout
maxOutputTokens 4096 Draft output limit
shutdownGraceMs 3000 Time to wait for in-progress drafts on exit
home $DSH_HOME Override dsh home, mainly for testing

What will be sent

Drafting requires sending the request text, tool parameters and results, and the final answer to the model; if it is a patch, the body of the existing skill must also be attached. It defaults to using dsh’s own model pipeline. If endpoint is set, when the main pipeline fails, the same content will be sent to that backup address. So if a local model is running but endpoint points externally, the content will leave the domain—you should only configure addresses you trust.

Constructing commands can obscure secrets like keys, but it does not guarantee that keys and personal information definitely disappear; content already written in the draft will become instructions for subsequent agents after accept. The generated steps might be wrong to begin with, so reading the full text before accept is the truly necessary step.

The plugin only writes to $DSH_HOME/skill-scribe/ and the location selected when accept is called. If the environment variable SKILL_SCRIBE_DEBUG is set, logs will be appended to the specified file.

Things to read before installing

The plugin runs with the permissions of the current dsh process, so read the source code before deciding to install. Pay special attention to two points: first, it reads the tool parameters and results of the entire turn; second, the wording of the draft enters the subsequent session directly. The repository is MIT, dependencies are simple, but the README is written for personal use, and external connections like the endpoint backup address need to be confirmed by yourself.

Known limitations are also written in the README:

  • In dsh’s single-run usage, slow drafting might not finish before the process exits, and the candidate will be lost; the plugin will wait shutdownGraceMs, but the overall window for dsh to exit is about 5 seconds. For long sessions, or using examples/draft-from-session.mjs to redo from a recorded session will be more stable.
  • dsh itself is a preview version, and when there are breaking changes, the plugin needs to follow up.
  • If the daily limit quota is occupied and then the process crashes, the quota is deducted that day and is not refunded.

Summary

What this mechanism actually saves is the cost of “realizing it afterwards”: auto-save doesn’t block, auto-load is what blocks. For people who use dsh daily for data cleaning and batch processing tasks, the cost of one list + show + accept is lower than discovering later that a skill quietly intervened. The directory page is at https://www.skillhub.cn/plugins/MaresaN41/dsh-skill-scribe , and the source code is at https://github.com/MaresaN41/dsh-skill-scribe .

羽毛球分组比赛记分
小程序二维码

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

Xiaoye