dsh-blog-engine
September 13, 2026 · View on GitHub
DeepSeek Harness plugin: offline static-site blog tools. Author Markdown posts with
YAML frontmatter, parse a post index, and build a minimal HTML site as an in-memory
path → content map.
All three tools are pure functions of their arguments plus deployment config. Nothing
is written to disk, no process is spawned, and no request leaves the process, so every
build is reproducible. The wall clock is the only ambient input, and fixedDate pins it.
Installation
npx -y @deepseek-ai/dsh plugin --profile web add @qingshanjiluo/dsh-blog-engine
Tools
| Tool | Arguments | Result |
|---|---|---|
blog_new | title (string), body (Markdown string), meta? (JSON object) | A complete Markdown document with YAML frontmatter, plus the resolved slug, suggested path, date, and warnings. Writes nothing. |
blog_list | files ([{ path, frontmatterText }]), includeDrafts? (boolean) | A JSON post index — slug, title, date, draft, tags, excerpt, path — sorted newest first, plus per-file parse warnings. Reads no files. |
blog_build | posts ([{ slug, title, body }]), site? (JSON object), includeDrafts? (boolean) | A path → content file map as files entries: index.html, one page per post, and feed.xml, plus postCount, draftsSkipped, bytes, and warnings. Publishes nothing. |
meta accepts slug, date, author, draft, excerpt, tags (array or
comma-separated string), and any extra key, which is preserved verbatim as
frontmatter. A post body handed to blog_build may begin with a --- frontmatter
block, so the output of blog_new feeds straight into blog_build. Drafts are skipped
by the builder unless includeDrafts is set.
Generated pages escape all Markdown input, neutralise javascript:/data: link
targets, and repair or de-duplicate colliding slugs.
Configuration
| Key | Type | Default | Description |
|---|---|---|---|
siteTitle | string | My Blog | Site title in page titles, the index heading, and the feed. |
siteUrl | string | https://example.com | Absolute base URL used only to build feed links; never fetched. |
postsDir | string | posts | Relative directory shaping suggested paths and generated page links. |
author | string | "" | Default frontmatter author for blog_new; empty omits the key. |
fixedDate | string | "" | Clock seam — when non-empty, blog_new stamps this ISO date instead of the wall clock. |
maxFeedItems | number | 20 | Maximum items written into the generated feed. |
Post format
---
title: My Post
slug: my-post
date: 2026-01-01
tags: tech, blog
draft: true
excerpt: A short description
---
# My Post
Content here...
Network and command usage
This plugin needs no external tool, server, or network access at runtime — every tool
is an in-process string transformation. Plugins in this family that do shell out or
fetch take an injectable seam so their tests stay offline too; here the seam is the
fixedDate clock pin, which keeps the suite deterministic without a real clock.
Development
npm install --no-audit --no-fund
npm run typecheck # tsc --noEmit
npm test # vitest run
npm run build # lib/index.js + lib/index.d.ts
node scripts/load-smoke.mjs
License
MIT