dsh-notes
suomir1995/dsh-notes
Conserve des notes Markdown locales, classées par dossier sous une racine choisie, avec une page dans la barre latérale. Les fichiers de règles de type AGENTS sont proposés comme contexte de rédaction ; six outils Agent sont inclus.
Installer
dsh plugin --profile web add github:suomir1995/dsh-notesREADME
dsh-notes — Notes
English | 中文
A DeepSeek Harness plugin (bundle) that keeps your notes as local Markdown files, grouped by directory.
It is a DSH bundle in two halves:
- Host half (
index.js, plain ESM, no build step) — the read/write service for your notes. Choose a local directory as the root (default<DSH_HOME>/dsh-notes; switchable inside the page and remembered, no restart required); a direct subdirectory of the root is a group (second-level directory, created automatically when missing); an md file inside a group is a note; rule md files under the root or a group — AGENTS.md / CLAUDE.md / *.rules.md / *规则.md and the like — are read as convention context. Loopback + same-origin guarded routes serve the Web UI, and six agent tools are registered:note_root/note_list/note_rules/note_create/note_read/note_delete. - Client half (
src/client/*, built tolib/client.js) — the sidebar entry 「笔记」 opens a page: group list, rule viewer, note create (paste text) / view / edit / rename / delete, and switching the root directory.
Storage model (a directory is a group, an md file is a note)
<root>/ ← the local directory you chose (level 1)
AGENTS.md ← root-level rule file (optional, matched case-insensitively)
<group>/ ← level-2 directory = a group (created automatically if missing)
AGENTS.md ← that group's rule file (optional)
<note>.md ← one note (every other .md counts as a note)
Rule files = md files whose name matches (case-insensitive): AGENTS.md,
AGENTS.local.md, CLAUDE.md, *.rules.md, *规则.md / *規則.md. A note with the same
name cannot be created (that name is reserved for rules). Tolerant parsing: hand-written
plain Markdown can be dropped into a group as a note — a missing title falls back to the
file name, a missing group to the directory name; pasting a complete md file that already
carries front matter stores it verbatim and never wraps it twice.
Each note the plugin creates:
---
title: useState 笔记
group: 前端
created: 2025-01-01T00:00:00.000Z
updated: 2025-01-01T00:00:00.000Z
---
Body (any Markdown).
Features
- Groups = second-level directories under the root: list / create; writing a note creates the directory when the group does not exist.
- Notes: paste text or organized content → stored as
<group>/<note>.md; view / edit / rename / delete; the body is any Markdown. - Rule context: the AGENTS-style rule md files of the root and of each group are shown as
chips — click one to read it in full; before writing, the model can read the conventions
with
note_rulesand then file the note. - Root directory: switched inside the page, effective immediately and remembered (the
host stores the current path in
<DSH_HOME>/dsh-notes/.notes-root; an explicitrootDirin the config file takes precedence). - Agent tools:
note_root— view / switch the root directory;note_list— list the group overview, or list the notes inside one group;note_rules— read the root rules (plus a given group's rules) as writing context;note_create— create / update a note (the group is created automatically;update: trueoverwrites);note_read— read one note in full;note_delete— delete one note (removes only that md, never the group directory).
- Chinese UI; the sidebar entry DOM and visual language follow the skill center (36px
rounded row + 24px icon box, shell
--dsw-alias-*tokens, collapsible sidebar).
Layout
| Path | Purpose |
|---|---|
index.js | Host half: group/note/rule read-write + agent tools + guarded routes |
cordis.patch.yml | Bundle layer: host row notes |
src/client/* | Browser half: sidebar entry + notes page overlay (React) |
lib/client.js | Built client artifact (exports["./client"]) |
tsdown.config.ts | Client build (closure-factory __ModuleLoader__ format) |
scripts/smoke-host.mjs | Host-half smoke (md parsing/CRUD/rules/tools, isolated DSH_HOME) |
scripts/loader-boot.mjs | Real Loader + webServer HTTP route smoke |
scripts/smoke-client.mjs | Client artifact smoke (executes the closure in a stub browser) |
Build
The client half needs a build; the host half ships as plain ESM:
npm run build:client # tsdown → lib/client.js (+ map)
The tsdown binary comes from the DeepSeek Harness checkout. React is resolved through the
shell's module table (react, react-dom/client) and is never bundled. The smoke scripts
need @deepseek-ai/* to be resolvable locally (a temporary
ln -s ~/.dsh/profiles/node_modules node_modules, removed afterwards, is enough).
Install
dsh plugin --profile web add ./dsh-notes
This appends a dsh-notes layer; restart the profile afterwards (both host and client
changes require a restart):
pnpm dsh web
After the restart a「笔记」entry appears in the left sidebar. The default root directory is
<DSH_HOME>/dsh-notes (created automatically); use "switch directory" in the page to point
it at any absolute local path (~ is supported; leave it empty to restore the default).
Plugin config
All optional (defaults shown); override in the profile's own cordis.patch.yml:
- id: notes
config:
rootDir: '' # explicit root dir (absolute path / ~/…); empty = use the remembered one
maxRuleBytes: 524288 # single rule-file read limit
maxNoteBytes: 2097152 # single note read limit
maxBodyBytes: 1048576 # submitted note body limit
Host routes (all loopback + same-origin guarded)
| Route | Method | Purpose |
|---|---|---|
/api/notes/state | GET | Root state (current path / config-pinned / exists) |
/api/notes/root | PUT | Switch the root (empty = restore default) |
/api/notes/groups | GET | Group overview (note count + rule file names in the group) |
/api/notes/group | POST | Create a group directory |
/api/notes/rules?group= | GET | Root (or group) rule file list |
/api/notes/rule?group=&file= | GET | Read one rule file in full |
/api/notes/notes?group= | GET | Note list of one group |
/api/notes/note?group=&file= | GET / DELETE | Read / delete a note |
/api/notes/note/create | POST | Create a note (group created automatically; duplicate name 409) |
/api/notes/note/update | POST | Update a note (keeps created, refreshes updated) |
/api/notes/note/rename | POST | Rename a note file |
Security boundaries
The browser reaches data only through the guarded routes above and never touches the disk
directly; group and note names are sanitized first (path-traversal characters and hidden
files rejected) and then, after resolve, checked to still be inside the root; switching
the root writes a dedicated pointer file; every Markdown write goes through a temp file +
atomic rename with a single-writer queue against concurrent corruption; a missing directory
is created automatically. Rule and note reads are byte-capped (413 when exceeded).
Remove
dsh plugin --profile web remove dsh-notes
Verification record
scripts/smoke-host.mjs(isolated DSH_HOME + temp root, no network) — all passed: front matter / note parsing and idempotent round-trips, tolerant parsing of hand-written md, a pasted whole md file stored verbatim (no double wrapping), name sanitizing and rejection of reserved rule names (AGENTS/CLAUDE/*rules/*规则), rule-file detection (root/group), group CRUD (duplicate name 409, auto-creation), note add/read/duplicate-name 409/in-place update (keepscreated)/rename (implicit title follows)/delete/repeat-delete 404, over-limit body 413,note_list/note_rules(root + group rule text) /note_create(auto-creates the group) /note_read/note_delete/note_root.scripts/loader-boot.mjs(real Cordis Loader +dsh-host-webserver, isolated DSH_HOME) — all passed: row loading, webServer binding, state/root switching and persistence, HTTP CRUD for groups/rules/notes, rule text reading, foreign-host 403, wrong method 405, unknown route 404, malformed JSON 400, invalid group name 400, deleting a missing note 404.scripts/smoke-client.mjs— all passed:lib/client.jsregistersdsh-notesas a__ModuleLoader__closure and exportsname: notes-ui / inject / apply; no machine paths leak; only module-table externals (the react family) are resolved.- Static preflight:
node …/dsh-plugin-development/scripts/check-artifact.mjs bundle .→ PASS, 0 warnings.
Plugins associés
hindsight (coding-agents)
vectorize-io/hindsight
OpenViking (dsh-memory-plugin)
volcengine/openviking
MemOS (memos-local-plugin)
memtensor/memos
ReMe (dsh)
agentscope-ai/reme