dsh-hxc-blog

docsnpmMIT

Manage a GitHub Pages blog from a DSH panel — browse the Markdown articles grouped by tag, edit them in a split editor with a front-matter form, and publish the changes as one commit over the GitHub REST API.

下载量 / Downloads
531

Install

dsh plugin --profile web add dsh-hxc-blog

Sandbox test

This plugin has not been tested yet. Submit a test →

README

DSH · GitHub Pages 博客管理插件

![tests](https://github.com/huangxicheng1/blog-manage/actions/workflows/tests.yml)

仓库:huangxicheng1/blog-manage
· 包名:dsh-hxc-blog · 许可证:MIT

把 huangxicheng1/huangxicheng1.github.io 的内容管理搬进 DeepSeek Harness:

在左侧边栏打开一个博客管理面板,浏览、撰写、编辑、删除 content/**/*.md,

把变更作为一次明确的 commit 推回 main,然后盯着 GitHub Actions 把站点构建出来。

整个插件不需要本地 git,也永远不会写 entries.js —— 那个文件由 build.py

在 Actions 里生成,插件只负责 content/ 下的 Markdown。

前提:站点的 Pages 源必须设成 GitHub Actions(Settings → Pages → Source)。
如果还停在「Deploy from a branch」,GitHub 会自己把分支内容原样发布一遍,覆盖掉
Actions 的产物,于是构建明明成功、线上却没有新文章。详见第 10 节。

1. 功能需求

1.1 它做了什么

能力 · 说明

侧边栏入口 · 在「Downloads」之后新增一行「博客管理」,点击打开主区域面板

双栏浏览 · 左栏按 tag 分组(可折叠、多 tag 重复出现、无标签单独成组),支持搜索、草稿标记、格式错误标记;右栏渲染预览,可切到源码

可视化编辑 · front matter 用表单填写(不手写 YAML),正文 Markdown 编辑 + 实时预览

发布前校验 · 按 build.py 规则校验,不通过就拦住发布并高亮出错字段

一次 commit · 所有待发布变更合并成一次 commit(blob → tree → commit → ref),冲突时拒绝覆盖

构建反馈 · 推送后轮询 Actions 最新 run,显示「构建中 / 成功 / 失败」,成功给出站点链接

自动化接口 · HTTP 路由 + Host 服务 + 浏览器事件三种钩子,见第 7 节

1.2 连接与浏览

设置面板配置 GitHub fine-grained PAT(加密存储)、仓库、分支、内容目录、站点地址。

点击侧边栏按钮后,主区域打开双栏界面。

左栏:按 tag 分组(详见第 2 节)

  • 从每篇文章 front matter 的 tags 提取标签,一个标签一个分组,分组标题显示「标签名 + 文章数量」。
  • 可折叠 / 展开:点击分组标题收起或展开,折叠状态会记忆(重开 DSH 仍然保留)。
  • 一篇文章有多个 tag 时,同时出现在多个分组下;没有 tag 的归入「无标签」分组,永远排在最后。
  • 分组内每篇文章显示标题、日期、其余标签(灰色小字)、文件名;草稿与格式错误各有徽标,有未发布更改时标题右侧有小圆点。
  • 搜索支持标题、标签、文件名(另外也匹配摘要、分类与路径)。

右栏:选中文章的 Markdown 渲染预览,可切换源码模式;顶部显示 front matter 元信息

(类型、分类、标签、复习日期、日期),并显示文章 id。

1.3 可视化编辑与发布

  • 「编辑 + 实时预览」分屏编辑器,正文左侧编辑、右侧即时渲染。
  • 新建文章时 front matter 用表单填写:标题、日期(默认今天)、类型(diary / note 下拉,

决定写入 content/diary/ 还是 content/notes/)、摘要、分类(仅 note 显示)、标签、

复习日期、草稿开关、文件名。

  • 保存前在本地按 build.py 的规则校验,不通过则阻止发布并高亮错误字段。
  • 编辑后显示「未发布更改」标记;发布时弹出确认框,显示变更文件列表

(M 修改 / D 删除)和 commit message 输入框,确认后通过 GitHub API 创建单个 commit 并推进分支。

1.4 发布状态反馈

推送成功后查询该仓库最新 Actions workflow run,显示「构建中 / 成功 / 失败」,

成功后给出 https://huangxicheng1.github.io/ 链接,失败时给出构建日志链接。

1.5 自动化扩展

HTTP 路由、Host 服务、浏览器事件三个入口,见第 7 节。


2. 内容浏览视图:按标签分组

左栏的组织原则是 tag,不是目录。规则全部落在 client.js 的

groupArticlesByTag() 与 articleMatchesQuery() 两个纯函数里,

由 test/tag-groups.mjs 直接验证:

行为 · 规则

分组键 · front matter 的 tags(逗号分隔,中英文逗号都接受)

分组标题 · # + 标签名 + 文章数量

折叠 · 点击分组标题,箭头旋转;aria-expanded 随状态变化

折叠记忆 · 存 localStorage 的 dsh-gh-blog:collapsed-tag-groups;读取失败或值损坏时退化为「全部展开」,不会抛错

搜索时 · 自动全部展开(搜索是明确的「我要看结果」),清空搜索后恢复折叠记忆

多 tag · 一篇文章出现在它每个 tag 的分组下,重复出现是预期行为

无 tag · 归入「无标签」分组,永远排在最后

分组顺序 · 文章数多的在前;数量相同按首次出现顺序(文章列表本身按日期倒序,所以是最新文章所属的标签先出现)。刻意不用 localeCompare,避免排序依赖运行时的 ICU 数据

卡片 · 标题 / 日期 / 其余标签(灰色小字 #a #b,即全部标签减去当前分组的那个)/ 文件名(等宽小字)

搜索字段 · 标题、标签、文件名;另外也匹配摘要、分类、路径

「其余标签」是卡片的关键细节:分组标题已经说明了当前标签,卡片再重复一遍就是噪音,

所以卡片只显示剩下的标签 —— 这也回答了「这篇文章为什么会出现在这里」之外的信息。


3. 安装

这是一个 DSH bundle 包,用 plugin_manager 的 install_bundle 安装。

不要在 profile 目录里手写 package.json,也不要在那里跑 pnpm —— install_bundle 会做完这些。

从 npm 安装(最省事)

plugin_manager  action: install_bundle  target: dsh-hxc-blog

包在 npm 官方源上:<https://www.npmjs.com/package/dsh-hxc-blog>。

当前版本 0.1.1,声明兼容 DSH >=0.2.1-rc.2。

从 GitHub 安装

git clone https://github.com/huangxicheng1/blog-manage.git

然后把 install_bundle 的 target 指向 clone 下来的目录绝对路径:

plugin_manager  action: install_bundle  target: <clone 目录的绝对路径>

install_bundle 的 target 要的是本机路径,所以先 clone 再指过去,不要直接填 URL。

如果你只是想让 DSH 去拉这个仓库,dsh plugin add github:huangxicheng1/blog-manage 也可以。

从本地工作目录安装

如果你就在改这份源码,直接把 target 指向工作目录。本地目录安装是链接方式,

改完 client.js 刷新页面即可生效,不必重装。

安装完成后刷新 Web GUI:

  • 左侧边栏出现「博客管理」(位于「Downloads」下方);
  • 「插件」页里出现一行 GitHub Pages Blog,带本插件自己的图标。

若之后改动了 Host 端(index.js / lib/*),需要重启 Harness 让新的 JavaScript

模块代次生效(Node 会缓存已导入的模块,重装不会绕过它)。

可选:用配置固定默认值

cordis.patch.yml 里的 config 全部可选,用于给某台机器钉住默认仓库/分支:

- insert:
    - id: gh-blog
      name: dsh-hxc-blog
      config:
        repository: huangxicheng1/huangxicheng1.github.io
        branch: main
        contentRoot: content
        siteUrl: https://huangxicheng1.github.io/

优先级:内置默认值 < cordis.patch.yml 的 config < 设置面板里保存的值。


4. 配置 Token

1. 打开 <https://github.com/settings/tokens?type=beta> 创建一个 fine-grained PAT。

2. Repository access:只勾选 huangxicheng1.github.io 这一个仓库。

3. Permissions:

  • Contents: Read and write —— 读写文章;
  • Actions: Read —— 读取构建状态(可选;没有它只是看不到构建结果,推送仍然可用)。

4. 回到 DSH,侧边栏「博客管理」→ 右上角「设置」→ 粘贴 Token → 「保存设置」→「测试连接」。

Token 存在哪里:

  • 它走 DSH 的 凭据服务(credentials),键名 GH_BLOG_GITHUB_TOKEN,属于

provider 管理的可写存储,不会写进本插件的设置文件,也不会出现在页面 JavaScript 里

—— 浏览器端只和 DSH Host 的 /api/gh-blog/* 通信,从不直连 api.github.com。

  • 也可以不填面板,改用同名环境变量 GH_BLOG_GITHUB_TOKEN 提供(凭据服务会回落到环境)。
  • 面板里留空保存 = 保持现有 Token 不变;打开「清除已保存的 Token」再保存 = 删除。

非敏感设置(仓库、分支、内容目录、站点地址)存在:

$DSH_HOME/gh-blog/settings.json

写入是原子的(临时文件 + rename),权限 0600。


5. front matter 规范(与 build.py 一致)

文档必须以 --- 开头、以 --- 结束,中间只允许简单 key: value 行

(不支持嵌套、列表、多行标量)。

必填

字段 · 规则

title · 非空,单行,≤ 200 字符

date · YYYY-MM-DD,且必须是真实存在的日历日(2026-02-30 会被拒绝)

type · 只能是 diary 或 note

summary · 非空,单行

可选

字段 · 规则

category · 只对 note 有意义;不填视为「未分类」;写在 diary 上只做提醒,不会阻止发布

tags · 逗号分隔字符串(保存时会统一成 半角逗号 + 空格;中文逗号也接受)。左栏就是按它分组的

review · YYYY-MM-DD,复习日期

draft · true 时不发布;只接受 true / false

文件名与 id

  • 文章 id = 文件相对 content/ 的路径(去掉扩展名),例如 notes/2026-10-21-my-note。
  • 新建时插件按 type 决定目录,按 date + 文件名生成路径:
  content/diary/<date>-<slug>.md
  content/notes/<date>-<slug>.md
  • 文件名只允许字母、数字、中文、.、_、-,且不能以符号开

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::3,最后更新 2026-10-21

Links

GitHub · Homepage · npm

Same category