Back to home@therain2020

dsh-obsidian-sync

Obsidian vault tools for DeepSeek Harness: write/read markdown notes with path-traversal protection

Stars
0
Language
TypeScript
Created
Aug 21, 2026
Updated
Aug 21, 2026
GitHub repo

Introduction

dsh-plugin-obsidian-sync

A DeepSeek Harness plugin that gives a dsh agent read/write access to a local Obsidian vault.

Two packages:

PackageRole
packages/plugin/obsidian-syncthe plugin — registers obsidian_write_note and obsidian_read_note tools plus a system-prompt section
packages/bundle/obsidian-sync-bundlethe profile bundle — a patch layer that mounts the plugin into a dsh composition

What it does

  • obsidian_write_note — writes a markdown note into the configured vault. The title becomes the filename (sanitized); an optional directory places it under a vault-relative subfolder; refuses to replace an existing note unless overwrite: true.
  • obsidian_read_note — reads a note back by its vault-relative path.

Safety properties (all enforced, all tested):

  • Path containment — absolute paths and .. segments are rejected, and every resolved path is re-checked against the vault root. The agent cannot write outside the vault, even if it tries.
  • Size caps — a configurable maxNoteBytes (default 1 MiB) applies to both reads and writes, so a stray binary file cannot flood the context window.
  • No silent overwrites — an existing note is an error unless overwrite: true, so the model learns the argument matters instead of clobbering your notes.

Use case: the agent persists session summaries, research findings, and durable decisions straight into your knowledge base — no copy-paste.

Requirements

  • Node ^22.19.0 || >=24.0.0
  • pnpm (only for dsh plugin installs)
  • dsh 0.1.1-rc.2 (the @deepseek-ai/dsh-* packages ship as a set; this plugin pins that release)

Quick start

pnpm install
pnpm run check        # typecheck + lint + test + build

pnpm run check passing means the plugin compiles under dsh's own compiler settings, its tool schemas are valid, it mounts over the real dsh tool registry, and it withdraws cleanly on disposal.

Install into dsh

From npm:

dsh plugin --profile web add dsh-bundle-obsidian-sync

From a local checkout:

pnpm run pack:bundle
dsh plugin --profile web add ./dsh-bundle-obsidian-sync-0.1.0.tgz

Configure — the plugin refuses to mount without a vaultPath, so set it in a patch layer:

# $DSH_HOME/cordis.patch.yml  (defaults to ~/.dsh/cordis.patch.yml; hot-reloaded)
- insert:
    - id: plugin-obsidian-sync
      name: 'dsh-plugin-obsidian-sync'
      config:
        vaultPath: 'D:/GitHub/MyVault'   # absolute path to your vault — required
        notesDir: agent                  # default directory when a call omits one
        maxNoteBytes: 1048576            # read/write size cap

Then verify the row is in the composed tree and start using it:

dsh --profile web --dump-config   # the row should appear with your config
dsh web

Ask the agent to save something — e.g. "把这次会话的结论存成笔记" — and it will call obsidian_write_note.

Layer order, the no-pnpm path, and hot-reload behavior are documented in docs/loading-into-dsh.md.

Layout

packages/plugin/obsidian-sync/src/index.ts is the wiring; the filesystem logic lives beside it in notes.ts (pure functions, no Cordis) so it stays unit-testable without booting a Context. Tests mount the plugin over the real dsh tool registry and assert what the model actually sees, plus disposal on unmount.

dsh version

This project targets one dsh release, pinned across every @deepseek-ai/dsh-* dependency. They are released as a set and are not independently compatible, so upgrade them together. pnpm run trace @deepseek-ai/dsh-tools prints the installed version and where to read its contract.

License

MIT