dsh-md-notes User Guide

September 6, 2026 · View on GitHub

中文 · English

A note-taking plugin for DeepSeek Harness (DSH). This guide covers everything the plugin can do — from your first note to syncing notes with Git. It assumes the plugin is installed (see README).

In a nutshell: notes are plain .md files stored under each workspace's .dsh-notes/ directory. You can write them here, capture conversations into them, and — optionally — back them up / sync them with a Git repository.


1. Where your notes live

  • Every dsh workspace has its own notes folder: <workspace>/.dsh-notes/.
  • Each note is a plain .md file. Open and edit it with any editor — the plugin picks up your changes the next time it reads the file.
  • meta.json in the same folder is just a cache of titles/timestamps; ignore it (it's never committed to Git). If it goes missing it is rebuilt automatically from note titles and file mtimes.

Notes are workspace-bound: without a workspace there's nowhere to store them — create a workspace in the dsh sidebar first.

2. Opening the notes manager

Click the notes entry at the bottom of the sidebar. A full-screen manager opens with two columns:

  • Left — note list, grouped by workspace. Each workspace row ends with, in order: a note count, a git entry, and a + button to create a note. With Git enabled, the group also shows a Git sync card (status "Synced" / "N unpushed" + update/push buttons — see §5).
  • Right — note content, with Preview / Edit tabs and a Save button. Clicking an existing note opens Preview by default; a newly created note opens directly in Edit mode.
  • Bottom — global Git status line: cross-workspace summary ("N unpushed · X workspaces · Y to sync").

Creating a note

Click + on a workspace row. A "New note" dialog opens:

  • Title: defaults to "Untitled note ", editable — it is the note's display title (the first # heading in the body) and can change later.
  • File name (optional): leave empty to derive it from the title, or type one (illegal characters become -, a .md suffix is enforced). The file name is fixed once created and no longer follows the title.

⚠️ Don't reuse file names: the file name is the note's unique identity (interlinks, @ references, and Git sync all locate notes by file name). Duplicate names within one workspace cause mis-routed links/references and Git-sync overwrites — strongly discouraged. The dialog shows "Will create: " live and, on a collision, shows a red warning and disables creation; change the title or file name.

On create the note opens directly in Edit mode.

Editing & previewing

  • Preview tab: see the rendered result (GFM tables / task lists / math / code highlighting) — shown by default when you open an existing note.
  • Edit tab: write markdown source.
  • Save: writes to the local .md file and refreshes the list.

Searching notes

The search box in the manager's top bar searches every workspace — titles and bodies, case-insensitive; separate keywords with spaces (all of them must match).

  • While you type, the left pane switches to the grouped results (workspace → note → matched lines, keywords highlighted); the editor and git areas are untouched. Clear the box (or press Esc) to return to the list.
  • Each note row shows the total match count; a "Title match" badge means the keywords matched the title.
  • Click a matched line: the note opens in the editor on that line — the line centered in view, the keyword selected. Click the note row to jump to its first match. Notes under a write lock open in preview instead.

Linking notes

Write [[Note name]] (or a backtick `Note name`) in a note's body to reference another note; the preview renders it as a clickable link that jumps to the target note (cross-workspace supported). Links match by title or file name (case-insensitive):

  • A bare name prefers the current workspace on cross-workspace collisions, and still crosses workspaces when there's no collision.
  • To link a same-named note in another workspace, write [[workspace/Note name]] (workspace name or id).
  • When several notes share a title within one workspace, hovering shows "N notes share this title — use the file name"; link by [[file-name]] instead (file names are unique per workspace).
  • A reference to a missing note stays plain text.

Deleting a note

Hover a note in the list and click the 🗑 icon. A confirmation dialog asks for confirmation (deleting cannot be undone).

While a note is being written

While a note is being written (save / capture), that note cannot be edited (locked across sessions) until the write finishes.

3. Capturing a conversation into a note

Below any assistant answer, click the notes icon (next to the copy button). A picker opens:

  1. Choose an existing note — the list shows all workspaces' notes, grouped by workspace (fold/collapse a workspace row to browse; the current workspace's notes are included), or create a new one on the spot with the + button on any workspace row. A note that is currently being written is not selectable (it shows a row loading) — writes are mutually exclusive per note across sessions.

  2. Click Write to note. The question + answer text is captured from the conversation itself (instant, no waiting) and appended to the note as a timestamped section; while the write runs the button reads "Writing…", and on success a green "Written ✓" appears left of the button before the picker closes:

    ---
    
    ## <session title> -- <timestamp>
    
    ### 👤 <user label>
    <question>
    
    ### 🤖 <assistant label>
    <answer>
    

4. Referencing notes in a conversation (@)

Type @ in the chat input to pick a note: the pick inserts a note chip, and on send the note's content is put into the model context automatically — the model can see and cite the note without you having to tell it to read files.

4.1 Picking a note

  1. Type @ → the candidate menu lists notes of the current workspace (file icon; the title is the primary row, the file name the secondary line).
  2. Select with arrows / click → a note chip appears (leading with the plugin icon); keep typing @ to add more.
  3. Keep typing to filter the candidates (by title or file name).

4.2 Referencing notes from other workspaces

  • Type a partial workspace name (e.g. @dsh-pl) → a workspace row appears (dsh-plugin/, folder icon);
  • Pick the workspace row → it auto-completes to @dsh-plugin/ and immediately lists that workspace's notes; keep typing to filter within it;
  • An exact workspace name (@dsh-plugin) switches directly;
  • Chinese workspace names (no spaces) work; only names containing spaces cannot be triggered by text (dsh's trigger token stops at whitespace — a platform limit; a menu-based all-workspaces picker is planned).

4.3 What happens on send

Two things:

  1. Your message keeps a readable reference line (standard markdown link syntax) — e.g. Referenced note [title](.dsh-notes/note.md) (same workspace) or Referenced note [title](../other-dir/.dsh-notes/note.md) (cross-workspace) — it tells the model (and you) which note was referenced;
  2. The plugin's backend (the local dsh process) injects the note's content into the model context — a collapsible "context injection" row (source md-notes) appears in the chat; expand it to see the injected content. The model gets the content directly — it does not depend on calling its read tool itself.

4.4 Common questions

  • No need to re-reference for follow-ups: the injected content stays in the session context (until dsh compacts old history), so follow-up questions (e.g. "what was X in the note?") work without re-referencing. If a note is large and you worry about context usage, start a new session or reference only the notes you need.
  • Note deleted / moved: if the note no longer exists at send time, the send is blocked with "«name» could not be found. Remove the reference." — delete the stale chip and resend.
  • A typed @note-title does nothing: plain-text @note-title is only a highlight decoration — it does not enter the model context; real references go through the menu (chip).
  • No workspace: sessions without a workspace get no @ candidates (silent).

5. Git sync (optional)

Git sync keeps your notes backed up and synchronized across machines. The plugin manages a local clone of your repository automatically — you only need to give it a repository URL.

Notes always live locally in <workspace>/.dsh-notes. Git sync only pushes them to / pulls them from a repository; it never changes where notes are stored locally.

The workspace-row git icon:

  • It only appears for workspaces with a git repo configured; unconfigured workspaces don't show it.
  • Click it to expand/collapse that workspace's Git sync card.
  • Two small dots under the icon appear only when there is something to act on:
    • bottom-left yellow = the remote has updates (click Update to pull);
    • bottom-right red = you have unpushed local changes (click Push).
  • Hovering the icon shows two lines: the remote-update count and the local-unpushed count.

5.1 Two modes (choose one)

In the settings panel (see §6), pick a mode:

ModeWhat it doesConfigure
OffNo Git sync. Notes are just local files.
Shared repoOne repository for all workspaces. Each workspace's notes sync into that repo's branch under a pinned folder (its name is fixed on the first sync and stays the same if the workspace is renamed).Repo URL + optional branch (default main)
Own reposEach workspace has its own repository.Per workspace: repo URL + branch (default main) + in-repo subpath (default repo root)

We recommend Shared repo: one URL for everything, each workspace gets a pinned subfolder automatically — the least configuration. Use Own repos when you want per-project separation or different credentials per repo.

5.2 Pushing notes

  1. Open the notes manager and click Push on the workspace's Git sync card — the button row switches to a commit-message row (input + confirm / cancel).
  2. Enter a commit message (default "Notes update
  3. First push clones the repository automatically (credentials come from git itself — HTTPS credential helper or your SSH key).

Before pushing, the plugin compares the remote against the last-synced state (three-way: base / local / remote). It asks only when the remote changed since your last sync and your local side differs from it (or a note you deleted locally still exists remotely):

Remote notes changed and differ from or are missing locally: <names>. Overwrite/delete the remote with your local state?

  • Overwrite remote with local → push proceeds, including deletions.
  • Cancel → nothing is pushed.

A note you edited locally while the remote stayed unchanged is not a conflict — it pushes normally.

5.3 Updating notes (pulling)

Click Update on the workspace's Git sync card to pull the remote version of the notes down:

  • If the remote has new notes you don't have → they're pulled in and the list refreshes automatically.

  • If a note changed on the remote (since your last sync) and differs from your local edit → the plugin keeps your local version and asks whether to replace it:

    The remote has N note(s) different from local ones. Replace local with the remote version?

    • Use remote version → the remote copy overwrites your local file.
    • Cancel → local stays unchanged.

5.4 Auto-pull when opening a note

When you open a note, the plugin (if gitAutoPull is on) silently pulls the remote first — without overwriting anything you've edited locally. If the remote has notes that conflict with local ones, it shows a hint on the Git sync card: "Remote has updates — update manually." Click Update to resolve.

5.5 When a push is rejected

If the remote is ahead or the histories are unrelated, the push is rejected and you'll see a "Merge remote & retry" action. Click it to merge the remote into the local clone, then push again.

6. The settings panel

Open the notes manager and click the ⚙ settings icon next to the title (or open dsh's Settings → MD Notes section). Everything Git-related is here:

  • Mode: Off / Shared repo / Own repos.
  • Shared repo: repository URL + branch (optional, default main).
  • Own repos (per workspace): URL + branch + in-repo subpath.
  • Auto-pull on open (checkbox, default on).
  • Commit author name / email (used when the repository has no git identity configured; otherwise the repo's own config wins).

7. Update notifications

The plugin checks npm for a newer version of dsh-md-notes when it loads (the check is cached for 10 minutes; failures are silent). If a new version exists, a yellow "Update available" tag appears:

  • at the tail of the sidebar notes entry (hover to see the version number);
  • next to the settings icon in the notes manager title bar.

Upgrade with dsh plugin --profile web update dsh-md-notes, then restart dsh web.

8. Tips & notes

  • Files are yours: notes are ordinary .md files; edit them anywhere, keep them after uninstalling the plugin.
  • File names are unique per workspace: the file name is the note's identity; duplicates break interlinks/references/Git sync — don't reuse names.
  • meta.json is a local cache only — it's never committed, and a fresh clone rebuilds it.
  • Deleting a note locally and pushing removes it from the remote too (mirror sync), after confirmation.
  • Only .md files sync. Non-markdown files you place in a remote repository are not pulled into your notes.
  • Language: all UI copy follows dsh's language setting (Chinese / English).