dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
dsh 日记插件:纸感信纸风 web 页写日记,原文先落盘、AI 评注后生成 · Diary plugin for dsh (DeepSeek Harness)
A diary plugin for dsh (DeepSeek Harness): write your diary on a paper-letter-styled web page where the raw text is saved to disk first and the AI comment is generated after — a failed summary never loses your writing.
中文版 · Built-in guide: press ? at the top right of the page (or open /diary/guide) after installing.
| Daily writing (light) | Dark |
|---|---|
| First-run setup card | Built-in guide (zh/EN) |
|---|---|
| Who | Owns |
|---|---|
| Plugin code (deterministic) | 30-hour-clock date resolution (system time), template-based file creation, entry appending, comment-block layout, trailing timestamp, stripping the old comment block on resubmit |
LLM (called directly via ctx.llm) | Produces exactly four things: a keyword, a one-line summary, an emoji of the day, and a comment. provider/model/temperature default to plugin config; the page's "comment model" selector can override provider/model per submit (only combinations present in the model catalog are honored). It also produces one new full user profile after each comment lands (same routing — see "Long-term memory") |
git clone https://github.com/zhm20001/dsh-diary.git
cd dsh-diary
pnpm install # compiled lib/ is committed — no build needed
dsh plugin --profile web add <path-to-this-repo>
# restart dsh web, then open http://127.0.0.1:<port>/diary
On first open the page shows a setup card: enter a diary directory (e.g. ~/Documents/Diary; ~ expands to your home) and save — it is written to the plugin's config.json and takes effect immediately, no restart. Then write your first entry → "Save & summarize".
Daily flow: open the page → write → submit. The raw text hits disk immediately; if the summary fails, your text is safe — press "Retry summary only". Drafts autosave to browser localStorage (keyed per date). The dsh web sidebar also gets a "Diary" entry at its footer (src/client.js, label follows your browser language). Each submit also quietly maintains a user profile (see "Long-term memory"); a failure there only shows a non-blocking note that saving is unaffected.
Alongside the summary, every save maintains a user profile — plain markdown, stored at .diary-meta/profile.md inside the diary directory, next to (but conceptually separate from) the emoji meta table, and readable by you at any time.
.diary-meta/profile.md.There is no switch and no new config key: daily LLM usage roughly doubles (one extra profile-update call plus the profile riding along with the summary), which is negligible for a single-user setup. Your diary text is never modified by "forgetting" — the profile is recomputable derived state.
Three layers, highest priority first:
| Layer | Notes |
|---|---|
| cordis patch / profile config | Injected at load time; when diaryDir is set here the setup card warns "overridden" |
config.json in the plugin root | What the setup card and the prompt card maintain; hand-editable too. Re-read on every request — edits apply immediately. See config.example.json; relative paths resolve against the plugin root, ~/ supported (summaryPrompt is a plain text key, never path-resolved) |
| Built-in defaults | Template falls back to assets/diary-template.md; with no directory configured the page enters setup mode; the comment prompt falls back to the built-in default |
Customizing the comment prompt: the 📝 button next to the "comment model" selector opens the prompt card — read the system prompt that drives the AI comment, then edit, save, or reset to default. It is stored as summaryPrompt in config.json and takes effect immediately (precedence as in the table above). Saving validates the output contract: the three markers 【今日关键词】 (keyword), 【一句话总结】 (one-line summary) and 【评注】 (comment) must stay (the 【当日 emoji】 line is optional — without it that day's heatmap cell falls back to green); a custom prompt only shapes future summaries, never rewrites comment blocks already in your diary. A broken prompt injected via a cordis patch fails loudly at summary time (no silent fallback).
Other plugin options (cordis patch layer): provider / model (summary model, defaults deepseek-official / deepseek-chat), temperature (0.6), timeoutMs (120000), nightCutoff (6), pagePath (/diary; if changed, update the href in src/client.js too), summaryPrompt (comment prompt override).
YYYY-MM-DD.md; the day's emoji lives in the hidden .diary-meta/YYYY.json and the user profile in .diary-meta/profile.md inside the same directory. Backup = copy the whole directory (don't forget .diary-meta/ when migrating, or emoji silently degrade to plain green cells and the profile falls back to a cold start).2026-04-28-note.md count as 04-28; multiple files per day are not double-counted) — manual create/delete/rename shows up on the heatmap immediately; orphaned emoji in meta are ignored harmlessly.nightCutoff (default 6 am) counts as the previous day, with timestamps shown as 25:xx–29:xx — late-night entries never split across two files.## AI评注 heading.<diaryDir>/YYYY-MM-DD.md, front matter from the template (empty date: field or {{date}} placeholder supported).stage:'summary' + hint (HTTP 502); a save failure returns stage:'save'.pnpm install
pnpm typecheck
pnpm test # vitest: core pure functions + path resolution + atomic writes
pnpm build # regenerates lib/ (CI verifies it matches src/)
# Smoke: a dev overlay points the plugin at /tmp/diary-sandbox — never touches your real diary
dsh web --patch dev.patch.yml # then browse /diary-dev
Structure: src/core.ts pure functions (no IO) → src/paths.ts path vars (config.json read/write) → src/service.ts routing & orchestration (webServer/httpServer dual-name compatible) → src/summary.ts summary LLM pipeline → src/profile.ts long-term memory (profile read/write, injection assembly, update loop, full rebuild) → src/page.ts page + src/guide.ts guide. lib/ is compiled output, committed with the repo (clone-and-use, no build); changes to src/ must be committed together with lib/.
Host requirement: a dsh web host (the internal harness build exposes ctx.webServer, the npm @deepseek-ai/dsh-host-webserver rc line exposes ctx.httpServer — both are supported).