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.
- 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. - 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
diffto see what changed. - Before sending text to the model or writing to files, identifiable secrets like API keys are obscured.
- 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 usingexamples/draft-from-session.mjsto 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 .