dsh-plugin-maoxuan-pet 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.en.md +97 -0
- package/README.md +38 -142
- package/assets/PROVENANCE.md +9 -8
- package/assets/icon-256.png +0 -0
- package/assets/icon.svg +43 -15
- package/assets/pet-blink.png +0 -0
- package/assets/pet-idle.png +0 -0
- package/assets/pet-read.png +0 -0
- package/assets/pet-talk.png +0 -0
- package/docs/INSTALL.md +1 -1
- package/docs/RELEASE.md +19 -4
- package/docs/screenshot-hero.png +0 -0
- package/package.json +5 -3
- package/{scripts → tools}/audit-corpus-coverage.mjs +1 -1
- package/docs/preview-v3.png +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.2.2 — 2026-11-01
|
|
4
|
+
|
|
5
|
+
展示层维护版:README 从技术说明改成安装页,npm 页面的介绍随之更新。
|
|
6
|
+
|
|
7
|
+
### 文档
|
|
8
|
+
- README 开头一句话说清是什么(对齐市场 PR #11067 的条目文案),之后按「安装 → 界面截图 → 四帧立绘 → 能力表 → 配置 → 语料 → 已知限制 → License」排列。
|
|
9
|
+
- 删掉架构图、Bubble 字段表、`template × axis` 矩阵、开发验证与踩坑记录;这些只在末尾链到 `docs/` 与 `verify/`。
|
|
10
|
+
- 删掉「已知限制」里的立绘生成说明与「逐字可辨」表述;素材记录统一放 `assets/PROVENANCE.md`,版权声明放 `NOTICE`。
|
|
11
|
+
- 截图与四帧立绘改用 GitHub raw 绝对地址(npm 页面同样能显示);`README.en.md` 同步同结构。
|
|
12
|
+
- `docs/RELEASE.md` 的当前版本同步到 `0.2.2`。
|
|
13
|
+
|
|
14
|
+
## 0.2.1 — 2026-11-01
|
|
15
|
+
|
|
16
|
+
上架插件市场后的首个维护版:图标重做 + 整包瘦身 + 打包门禁补强。
|
|
17
|
+
|
|
18
|
+
### 图标
|
|
19
|
+
- 包内 `assets/icon.svg` 换成「红皮书」造型:米白底、深红书壳、烫金五角星与书名条;按插件面板卡片实际 36px 校过,缩到 36px 仍能读成一本红皮书。
|
|
20
|
+
- 新增 `assets/icon-256.png`(256×256 RGBA,17 KB),给 [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) 条目的 `icon:` 用——市场只收 GitHub 托管位图,不收 SVG。
|
|
21
|
+
|
|
22
|
+
### 体积
|
|
23
|
+
- 四帧立绘 640×1348 → 256×539(UI 展示高 132px,2x 屏幕足够):4 张合计 **2.96 MB → 603 KB**。
|
|
24
|
+
- `npm pack` 整包 **4.2 MB → 约 1.2 MB**(59 files),安装与首屏都更快;README / 市场条目用的大图 `docs/screenshot-hero.png` 保留。
|
|
25
|
+
|
|
26
|
+
### 打包与发布门禁
|
|
27
|
+
- `scripts/audit-corpus-coverage.mjs` 迁到 `tools/`:`scripts/` 是开发脚本,不该进 npm 包;全局开源契约检查此前因此 1 项 FAIL,现在是 0 FAIL / 1 WARN(WARN 已由下一条解决)。
|
|
28
|
+
- 新增 `prepublishOnly`:发布前自动跑 `verify/smoke.mjs` + `verify/contract.mjs`,防手滑发坏版本。
|
|
29
|
+
- `scripts/post-publish-check.mjs`:市场索引有 3.3 MB,超时从 60s 提到 180s(可用 `MARKET_TIMEOUT_MS` 覆盖),慢网下 `--strict` 不再误红。
|
|
30
|
+
- 仓库根新增 `screenshots.json`(`["docs/screenshot-hero.png"]`),喂给 dsh-market 详情页的 AppStore 式截图;以后换图只需往本仓 push,不用再来提 PR。
|
|
31
|
+
|
|
32
|
+
### 文档
|
|
33
|
+
- 新增英文 README(`README.en.md`),中文 README 顶部加英文入口。
|
|
34
|
+
- README 的资产尺寸、审计脚本路径同步更新;`assets/PROVENANCE.md` 记录交付尺寸与图标改版。
|
|
35
|
+
|
|
3
36
|
## 0.2.0 — 2026-11-01
|
|
4
37
|
|
|
5
38
|
首个公开版本。
|
package/README.en.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Xiao Mao, the whale-girl desktop pet — one essay an hour in the corner of DSH
|
|
2
|
+
|
|
3
|
+
A red-book speech bubble plus four sprite frames: every card = a cited line from a Mao essay
|
|
4
|
+
(with source date) + one line of pressure for you + one rule you can verify today, capped at
|
|
5
|
+
**200 characters** in total.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
dsh plugin --profile web add dsh-plugin-maoxuan-pet
|
|
11
|
+
# then restart dsh web (Ctrl+C, then `dsh web` again) and reload the page
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Requirements: DSH `>=0.2.1-rc.2 <0.3.0`, Node `^22.19.0 || >=24.0.0`. Web shell only.
|
|
15
|
+
Source install / uninstall / troubleshooting: [docs/INSTALL.md](docs/INSTALL.md).
|
|
16
|
+
|
|
17
|
+
## Screenshot
|
|
18
|
+
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
The bubble hangs to the **left** of the pet, so the pet never moves. Opening the card marks it
|
|
22
|
+
read (the unread badge disappears); `‹ ›` walks back through history; `收起` / `再督促` are
|
|
23
|
+
text-only buttons. New bubbles pop up on the hour.
|
|
24
|
+
|
|
25
|
+
## Xiao Mao
|
|
26
|
+
|
|
27
|
+
| standing | talking | blinking | reading |
|
|
28
|
+
|:--:|:--:|:--:|:--:|
|
|
29
|
+
|  |  |  |  |
|
|
30
|
+
|
|
31
|
+
The four frames share one canvas and one foot line, so switching never makes her jump. A
|
|
32
|
+
fan-made character; not affiliated with DeepSeek.
|
|
33
|
+
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
| Ability | Behaviour |
|
|
37
|
+
|---|---|
|
|
38
|
+
| **One essay an hour** | 33 bundled public-domain essays of Mao Zedong, rotated so she doesn't reread the last one; templates rotate between `quote` / `excerpt` / `summary` |
|
|
39
|
+
| **Never invents a quote** | `quote` / `excerpt` must match the corpus verbatim, otherwise she falls back to `summary`; if the model retells the original, the whole card is dropped |
|
|
40
|
+
| **Six angles** | customers / projects / organisation / cash flow / decisions / self-discipline — one per card, with a hard rule and a way to verify it |
|
|
41
|
+
| **You can ask back** | ships the `maoxuan-pet` ("Selected Works startup advisor") preset and the `maoxuan-vademecum` skill; start a new session and ask "given Mao, what should I do next?" |
|
|
42
|
+
| **Doesn't nag** | quiet hours (02:00–08:00 by default), daily cap (24), remembered position, unread badge clears only when read, `‹ ›` history |
|
|
43
|
+
| **Degrades gracefully** | no credentials / timeout / non-JSON → a local excerpt labelled 「离线摘录」, never passed off as model output |
|
|
44
|
+
|
|
45
|
+
## Config
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
- id: dsh-maoxuan-pet
|
|
49
|
+
config:
|
|
50
|
+
enabled: true
|
|
51
|
+
everySeconds: 3600 # hourly
|
|
52
|
+
firstDelaySeconds: 90
|
|
53
|
+
quietHours: [2, 8] # no pings between 02:00 and 08:00 local time
|
|
54
|
+
dailyLimit: 24
|
|
55
|
+
maxBubbles: 40
|
|
56
|
+
headless: true # false = only local excerpts, zero model calls
|
|
57
|
+
dshBin: dsh
|
|
58
|
+
profile: headless
|
|
59
|
+
timeoutMs: 180000
|
|
60
|
+
businessContext: "40, indie developer, small-tool SaaS"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Corpus
|
|
64
|
+
|
|
65
|
+
- 33 essays, all `verified: true`, covering volumes I–V;
|
|
66
|
+
- texts come from the [Chinese Marxist Internet Archive](https://www.marxists.org/chinese/maozedong/index.htm), bundled for personal study only;
|
|
67
|
+
- refresh / extend: `npm run corpus`;
|
|
68
|
+
- licensing and redistribution limits: [NOTICE](NOTICE) and [corpus/README.md](corpus/README.md).
|
|
69
|
+
|
|
70
|
+
## Known limitations
|
|
71
|
+
|
|
72
|
+
- web shell only (`dsh.client.platform: web`) — no pet in the terminal / TUI;
|
|
73
|
+
- the timer only runs while this `dsh web` process is alive; a stopped process does not catch up,
|
|
74
|
+
and on restart `nextRunAt` decides whether to run once more;
|
|
75
|
+
- each headless generation is a fresh session (no shared context): stable, but she "doesn't
|
|
76
|
+
remember what she said yesterday" — hence the last 6 nudges are passed into the prompt to avoid
|
|
77
|
+
repeats.
|
|
78
|
+
|
|
79
|
+
## License and third-party content
|
|
80
|
+
|
|
81
|
+
- **Code**: MIT — see [LICENSE](LICENSE).
|
|
82
|
+
- **Bundled corpus** (`corpus/`, 33 essays): **not MIT.** Texts come from the
|
|
83
|
+
[Chinese Marxist Internet Archive](https://www.marxists.org/chinese/maozedong/index.htm) and
|
|
84
|
+
are bundled for personal study only. See [NOTICE](NOTICE). Delete `corpus/articles/` to drop it;
|
|
85
|
+
quote/excerpt templates then degrade safely to summary.
|
|
86
|
+
- **Sprites and icon** (`assets/`): a fan-made "whale girl" character — not affiliated with
|
|
87
|
+
DeepSeek. See [assets/PROVENANCE.md](assets/PROVENANCE.md).
|
|
88
|
+
|
|
89
|
+
This plugin is a reading/nudging tool that treats the essays as a source of product and
|
|
90
|
+
entrepreneurship method. It is not affiliated with DeepSeek or any publisher, and it is not
|
|
91
|
+
political advocacy.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
Package `dsh-plugin-maoxuan-pet` · [中文](README.md) · technical details in [docs/](docs/): [API-CONTRACT.md](docs/API-CONTRACT.md) · [CONTENT-FRAMEWORK.md](docs/CONTENT-FRAMEWORK.md) · [verify/README.md](verify/README.md)
|
|
96
|
+
|
|
97
|
+
[](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml) [](https://www.npmjs.com/package/dsh-plugin-maoxuan-pet)
|
package/README.md
CHANGED
|
@@ -1,109 +1,42 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 鲸鱼娘 · 小毛 —— 住在 DSH 右下角、每小时陪你读一篇毛选的桌宠
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> 每小时读一篇毛选,把它变成一句针对**你的**创业处境的思想 + 一句督促,
|
|
5
|
-
> 并且随时可以开一个新会话问她:根据毛选,我这一步该怎么走。
|
|
3
|
+
红皮书气泡 + 四帧立绘;每条内容 = 原文引文(带来源日期)+ 一句说给你听的督促 + 一条能当天验证的启示,整条 ≤ 200 字。
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|---|---|
|
|
9
|
-
| 宠物形态、鲸鱼娘、红军制服、手捧毛选 | `assets/` 里 4 帧 AI 立绘(idle / talk / blink / read,640×1348 RGBA,红封面竖排「毛泽东选集」可辨),`client.js` 在 `shell.overlay` 槽位渲染悬浮宠物 |
|
|
10
|
-
| 每小时帮我读毛选 | Host 定时器按小时读 `corpus/` 里的下一篇(轮转、避开刚读过的) |
|
|
11
|
-
| 每小时生成思想 / PUA 我的话,出现在气泡里 | 每次生成 `spawn` 一个 `dsh --profile headless` 对话,拿到结构化 JSON 后推给气泡 |
|
|
12
|
-
| 有个 preset,能直接问「根据毛选我该怎么做」 | `maoxuan-pet`「毛选创业参谋」preset + 运行时注册的 `maoxuan-vademecum` skill 指向内置语料 |
|
|
13
|
-
|
|
14
|
-
## 它到底怎么工作
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
┌─ DSH Web (dsh web) ───────────────────────────────────────────┐
|
|
18
|
-
│ │
|
|
19
|
-
│ index.js (Host) │
|
|
20
|
-
│ ├─ 状态:$DSH_HOME/storages/dsh-maoxuan-pet.json (原子写) │
|
|
21
|
-
│ ├─ 定时器:ctx.timeout 链 → quietHours / dailyLimit 约束 │
|
|
22
|
-
│ ├─ 语料:corpus/index.json → 轮转挑一篇 verified 的 │
|
|
23
|
-
│ ├─ 生成:spawn `dsh --profile headless --json "<prompt>"` │
|
|
24
|
-
│ │ └ 失败/超时/非 JSON → 本地摘录降级(标注“离线摘录”) │
|
|
25
|
-
│ ├─ 路由:/api/dsh-maoxuan-pet.{state,generate,dismiss, │
|
|
26
|
-
│ │ asset,corpus} │
|
|
27
|
-
│ └─ skill:把 corpus/ 注册成 maoxuan-vademecum │
|
|
28
|
-
│ │
|
|
29
|
-
│ client.js (Web) │
|
|
30
|
-
│ └─ shell.overlay → 宠物 + 气泡,20s 轮询 / 生成中 3s 轮询 │
|
|
31
|
-
│ │
|
|
32
|
-
│ cordis.patch.yml │
|
|
33
|
-
│ ├─ 插件行 dsh-maoxuan-pet │
|
|
34
|
-
│ └─ preset-maoxuan-pet「毛选创业参谋」(persona + skill + 工具) │
|
|
35
|
-
└───────────────────────────────────────────────────────────────┘
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
气泡里的每条内容都是**结构化**的,而且**整条不超过 200 字**:
|
|
39
|
-
|
|
40
|
-
| 字段 | 含义 |
|
|
41
|
-
|---|---|
|
|
42
|
-
| `template` | 三种模板轮转:`quote` 金句 / `excerpt` 文章节选 / `summary` 小毛概括 |
|
|
43
|
-
| `cite` | 上面那一句(逐字核对过;`summary` 是小毛的概括,不加引号),带来源链接 |
|
|
44
|
-
| `axis` | 启示落点,六选一:客户 / 项目 / 组织 / 现金流 / 决策 / 自律 |
|
|
45
|
-
| `pua` | 小毛对你说的一句话(≤40 字,第一人称;**模型复述原文时会整条丢弃**,气泡只留引文 + 启示) |
|
|
46
|
-
| `lesson` | 启示:一条硬规则 + 怎么验证(≤100 字,围绕 `axis`) |
|
|
47
|
-
| `chars` | 引文 + pua + 启示的实际字数,Host 保证 ≤200 |
|
|
48
|
-
| `mode` | `headless` = 模型生成;`offline` = 本地摘录降级(UI 会标「离线摘录」) |
|
|
49
|
-
|
|
50
|
-
框架是这样设计的(`template × axis` 矩阵,而不是每次同一套):
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
取材 3 种:原文金句 / 文章节选(逐字取整句)/ 小毛概括(模型自己概括)
|
|
54
|
-
落点 6 种:客户 · 项目 · 组织 · 现金流 · 决策 · 自律
|
|
55
|
-
语气 3 种:sharp 硬话 · calm 冷静 · urgent 催
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
- 模板游标 `templateCursor` 持久化在状态里,按 3 种循环;不会因为历史条数封顶而卡住;
|
|
59
|
-
- `axis` 在 prompt 里指定,并尽量避开上一条的落点;
|
|
60
|
-
- 引文句式/节选都在 `corpus/articles/<id>.md` 里做 `isVerbatim` 逐字校验,校验不过就退到 `summary`,绝不编造;
|
|
61
|
-
- 所有字段最后过一遍 `fitLesson`,把「引文 + pua + 启示」压进 200 字。
|
|
62
|
-
|
|
63
|
-
为什么落点是 6 类名词、而「动作」不单列一类、字数预算怎么分、真实生成样例长什么样,
|
|
64
|
-
见 [docs/CONTENT-FRAMEWORK.md](docs/CONTENT-FRAMEWORK.md)。语料能不能支撑 Quote 模板,跑一条审计就知道:
|
|
5
|
+
## 安装
|
|
65
6
|
|
|
66
7
|
```bash
|
|
67
|
-
|
|
8
|
+
dsh plugin --profile web add dsh-plugin-maoxuan-pet
|
|
68
9
|
```
|
|
69
10
|
|
|
70
|
-
|
|
11
|
+
装完按 **Ctrl+C 停掉 `dsh web`,再重新 `dsh web`**,刷新页面——右下角就有小毛了。
|
|
71
12
|
|
|
72
|
-
|
|
13
|
+
- 要求:DSH `>=0.2.1-rc.2 <0.3.0`、Node `^22.19.0 || >=24.0.0`,仅 Web 界面;
|
|
14
|
+
- 从源码安装、卸载、排错:[docs/INSTALL.md](docs/INSTALL.md)。
|
|
73
15
|
|
|
74
|
-
|
|
75
|
-
- **宠物不动**:卡片绝对定位在宠物左侧(宠物被拖到靠左边缘时自动翻到右侧),点开/收起只让气泡出现或消失,宠物坐标不变。
|
|
76
|
-
- **打开即已读**:卡片真正显示的那一刻才把这条标已读,宠物右上角的未读数随之消失;正在读的那条会被"钉住",Host 把 `current` 推进到下一条时,眼前的文字不会跳。
|
|
77
|
-
- **没有未读也有内容**:全部读过后再点开,仍然停在上一次产出的那张卡,`‹ ›` 可以往前翻历史。
|
|
78
|
-
- **定时弹出**:整点生成的新气泡会自己弹出来;手动关掉的那条不会自己再弹,等下一条。
|
|
79
|
-
- **按钮无盒子**:`收起` / `再督促` 是纯文字 + 下划线,没有背景和边框。
|
|
16
|
+
## 界面
|
|
80
17
|
|
|
81
|
-
|
|
18
|
+

|
|
82
19
|
|
|
83
|
-
|
|
20
|
+
深红封面 + 烫金书脊的气泡挂在宠物左边,宠物自己不动;打开即已读(右上角未读数消失),`‹ ›` 可以往回翻历史,`收起` / `再督促` 是纯文字按钮。整点生成的新气泡会自己弹出来。
|
|
84
21
|
|
|
85
|
-
|
|
86
|
-
dsh plugin --profile web add dsh-plugin-maoxuan-pet
|
|
87
|
-
# 然后 Ctrl+C 停掉 dsh web,再重新 `dsh web`,刷新页面
|
|
88
|
-
```
|
|
22
|
+
## 小毛
|
|
89
23
|
|
|
90
|
-
|
|
24
|
+
| 站着 | 说话 | 眨眼 | 看书 |
|
|
25
|
+
|:--:|:--:|:--:|:--:|
|
|
26
|
+
|  |  |  |  |
|
|
91
27
|
|
|
92
|
-
|
|
93
|
-
node install.mjs --dry-run # 先看要改什么
|
|
94
|
-
node install.mjs # 写入 profile 清单 + pnpm link
|
|
95
|
-
```
|
|
28
|
+
四帧切换时身体不跳(共用同一画布与脚底线)。民间同人设定,与 DeepSeek 官方无关。
|
|
96
29
|
|
|
97
|
-
|
|
30
|
+
## 它能做什么
|
|
98
31
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
32
|
+
| 能力 | 说明 |
|
|
33
|
+
|---|---|
|
|
34
|
+
| **每小时读一篇** | 内置 33 篇毛选公开语料,轮转挑一篇没刚读过的;`quote` 金句 / `excerpt` 节选 / `summary` 小毛概括 三种模板轮转 |
|
|
35
|
+
| **不编造原文** | `quote` / `excerpt` 必须逐字命中语料全文,不命中就降级成 `summary`;模型复述原文会被识别并整条丢弃 |
|
|
36
|
+
| **六个落点** | 客户 / 项目 / 组织 / 现金流 / 决策 / 自律——每次只给一个,配「一条硬规则 + 怎么验证」 |
|
|
37
|
+
| **能追问** | 自带 `maoxuan-pet`(毛选创业参谋)preset 与 `maoxuan-vademecum` skill,可开新会话问「根据毛选,我这一步该怎么走」 |
|
|
38
|
+
| **不打扰** | 免打扰时段(默认 02:00–08:00)、每日上限(默认 24 条)、位置本地记忆、已读才消徽标、`‹ ›` 可回翻 |
|
|
39
|
+
| **掉线也不空转** | 无凭据 / 超时 / 非 JSON 时降级为本地摘录,并在页脚标注「离线摘录」,不冒充模型生成 |
|
|
107
40
|
|
|
108
41
|
## 配置
|
|
109
42
|
|
|
@@ -124,65 +57,28 @@ node install.mjs # 写入 profile 清单 + pnpm link
|
|
|
124
57
|
用户是一位正在创业的独立开发者……
|
|
125
58
|
```
|
|
126
59
|
|
|
127
|
-
## 用 preset 问「根据毛选我应该怎么做」
|
|
128
|
-
|
|
129
|
-
新建会话 → preset 选 **「毛选创业参谋」**(id `maoxuan-pet`)→ 直接问。它会:
|
|
130
|
-
|
|
131
|
-
1. 加载 `maoxuan-vademecum` skill(知道语料在哪、怎么检索);
|
|
132
|
-
2. 用 `read` 打开对应篇目**全文**,取逐字原文;
|
|
133
|
-
3. 按固定结构回答:原文金句(篇名 + 时间)→ 当时的问题与论证 → 方法 → 你的处境 → 今天能做的一步;
|
|
134
|
-
4. 核不到原文就明说,不编造。
|
|
135
|
-
|
|
136
|
-
`maoxuan-vademecum` skill 是运行时由 Host 注册的(内容来自 `skill/maoxuan-vademecum/SKILL.md` + 语料索引),所以它永远指向当前安装目录,不写死路径。
|
|
137
|
-
|
|
138
60
|
## 毛选语料
|
|
139
61
|
|
|
140
|
-
- **33 篇,全部 `verified: true
|
|
141
|
-
- 来源:中文马克思主义文库公开电子文本(https://www.marxists.org/chinese/maozedong/index.htm
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
- 版权:文本版权归原权利人,此处仅用于个人学习研究,不用于售卖,详见 `corpus/README.md` 与 `LICENSE`。
|
|
145
|
-
|
|
146
|
-
## 开发与验证
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
npm test # node verify/smoke.mjs
|
|
150
|
-
npm run test:contract
|
|
151
|
-
node verify/host.test.mjs # 假 ctx 端到端:路由、状态、降级、原子写
|
|
152
|
-
node --check index.js
|
|
153
|
-
node --check client.js
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
验证边界见 [verify/README.md](verify/README.md):单元与端到端测试不联网、不启动子进程、不花模型调用。
|
|
157
|
-
|
|
158
|
-
真实链路另做过一次隔离启动验证(`DSH_HOME=/tmp/... dsh web --port 3099`,不碰当前 GUI 的 profile):
|
|
159
|
-
|
|
160
|
-
| 验证 | 结果 |
|
|
161
|
-
|---|---|
|
|
162
|
-
| `--dump-config` 组装 | 插件行与 `preset-maoxuan-pet` 都在组合后的配置里 |
|
|
163
|
-
| `GET /api/dsh-maoxuan-pet.state` | 200,`corpus.count=33`,`nextRunAt` 已排定 |
|
|
164
|
-
| `GET /api/dsh-maoxuan-pet.asset?name=idle` | 200,`image/png`,640×1348 RGBA |
|
|
165
|
-
| 页面 boot payload | 含 `dsh-plugin-maoxuan-pet/client.js`,实际拉到的 bundle 里含本插件代码且可解析 |
|
|
166
|
-
| `POST /api/dsh-maoxuan-pet.generate`(真实 headless) | 61s,`mode: "headless"`,返回结构化气泡(篇名/金句/思想/启示/督促/动作) |
|
|
167
|
-
| 失败降级 | 无凭据时 5.5s 内降级为 `mode: "offline"` 并写入 `lastError` |
|
|
168
|
-
|
|
169
|
-
### 两个真实踩到的坑(已在 docs/API-CONTRACT.md §6 详述)
|
|
170
|
-
|
|
171
|
-
1. 自定义路由必须显式 `requestBody: 'buffered'`,否则 GET 会被 Host 直接 400、handler 不被调用;
|
|
172
|
-
2. `ctx.timeout()` 必须在 `inject` 里声明 `'timer'`,否则真实 `dsh web` 启动 fatal。
|
|
62
|
+
- **33 篇,全部 `verified: true`**,覆盖第一至第五卷;
|
|
63
|
+
- 来源:中文马克思主义文库公开电子文本(https://www.marxists.org/chinese/maozedong/index.htm),仅作个人学习、研究之用;
|
|
64
|
+
- 重新抓取 / 扩充:`npm run corpus`;
|
|
65
|
+
- 版权与再分发限制见 [NOTICE](NOTICE) 和 [corpus/README.md](corpus/README.md)。
|
|
173
66
|
|
|
174
67
|
## 已知限制
|
|
175
68
|
|
|
176
|
-
- 只支持 Web 界面(`dsh.client.platform: web
|
|
69
|
+
- 只支持 Web 界面(`dsh.client.platform: web`),终端 / TUI 里没有宠物;
|
|
177
70
|
- 定时器只在这个 `dsh web` 进程活着时走;进程停了不会补跑,重启后按 `nextRunAt` 决定是否补一次;
|
|
178
|
-
- headless
|
|
179
|
-
- 生图是 AI 生成,中文“毛泽东选集”可能不是逐字可辨,详见 `assets/PROVENANCE.md`;
|
|
180
|
-
- DeepSeek「鲸鱼娘」是民间同人设定,本项目不是官方素材,也不代表 DeepSeek 立场。
|
|
71
|
+
- headless 生成每次是独立会话(不复用上下文):稳定,但「不记得昨天说过什么」——所以 prompt 里带最近 6 条督促来避免重复。
|
|
181
72
|
|
|
182
73
|
## License
|
|
183
74
|
|
|
184
75
|
- **代码**:MIT,见 [LICENSE](LICENSE)。
|
|
185
|
-
- **内置毛选语料**(`corpus/`):**不是 MIT**。文本来自[中文马克思主义文库·毛泽东](https://www.marxists.org/chinese/maozedong/index.htm)
|
|
186
|
-
|
|
187
|
-
- **立绘**(`assets/`):AI 生成(gpt-image-2,2026-10-31),民间同人形象「鲸鱼娘·小毛」,与 DeepSeek 官方无关。生成记录见 [assets/PROVENANCE.md](assets/PROVENANCE.md)。
|
|
76
|
+
- **内置毛选语料**(`corpus/`):**不是 MIT**。文本来自[中文马克思主义文库·毛泽东](https://www.marxists.org/chinese/maozedong/index.htm),著作权归原作者与出版方,本项目仅作个人学习、研究之用的整理,不构成再出版或商业授权。详见 [NOTICE](NOTICE) 与 [corpus/README.md](corpus/README.md)。
|
|
77
|
+
- **立绘与图标**(`assets/`):民间同人形象「鲸鱼娘·小毛」,与 DeepSeek 官方无关;素材记录见 [assets/PROVENANCE.md](assets/PROVENANCE.md)。
|
|
188
78
|
- 本项目与 DeepSeek、毛泽东著作出版方均无隶属关系;内容用于产品与创业方法论的阅读辅助,不作政治宣传。
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
包名 `dsh-plugin-maoxuan-pet` · [English](README.en.md) · 技术细节(架构、接口契约、内容规范、验证方式)见 [docs/](docs/):[API-CONTRACT.md](docs/API-CONTRACT.md) · [CONTENT-FRAMEWORK.md](docs/CONTENT-FRAMEWORK.md) · [verify/README.md](verify/README.md)
|
|
83
|
+
|
|
84
|
+
[](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml) [](https://www.npmjs.com/package/dsh-plugin-maoxuan-pet)
|
package/assets/PROVENANCE.md
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
- talk → `assets/raw/talk-final.png`
|
|
21
21
|
- blink → `assets/raw/blink-final.png`
|
|
22
22
|
- read → `assets/raw/read-v3.png`
|
|
23
|
-
4. **统一画面**:四帧用**同一个裁剪框**(原图 1024×1536 的 `(160, 0, 880, 1516)`)裁切,先把透明区域外扩成相邻像素颜色(避免缩放时白边渗入轮廓),再 Lanczos 等比缩放到 **640×1348
|
|
24
|
-
5. `assets/icon.svg`:**手写 SVG**(纯几何形状,非 AI
|
|
23
|
+
4. **统一画面**:四帧用**同一个裁剪框**(原图 1024×1536 的 `(160, 0, 880, 1516)`)裁切,先把透明区域外扩成相邻像素颜色(避免缩放时白边渗入轮廓),再 Lanczos 等比缩放到 **640×1348** 作为母版;交付版再降到 **256×539**(UI 展示高 132px,2x 屏幕够用,四帧共用同一画布与脚底线,切换帧时身体不跳)。
|
|
24
|
+
5. `assets/icon.svg`:**手写 SVG**(纯几何形状,非 AI 生成),米白底 + 红皮书 + 烫金五角星与书名条,2326 字节;另导出 `assets/icon-256.png`(256×256 RGBA)供市场条目 `icon:` 使用(市场只收 GitHub 托管位图,不收 SVG)。
|
|
25
25
|
|
|
26
26
|
原始中间产物保留在 `assets/raw/`(本仓库 `.gitignore` 已忽略该目录,不随 git 提交;如需瘦身可直接删除)。
|
|
27
27
|
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
|
|
54
54
|
| 文件 | 像素 | 色彩/通道 | `file` 输出 | 说明 |
|
|
55
55
|
| --- | --- | --- | --- | --- |
|
|
56
|
-
| `assets/pet-idle.png` |
|
|
57
|
-
| `assets/pet-talk.png` |
|
|
58
|
-
| `assets/pet-blink.png` |
|
|
59
|
-
| `assets/pet-read.png` |
|
|
60
|
-
| `assets/icon.svg` | viewBox 512×512,
|
|
56
|
+
| `assets/pet-idle.png` | 256×539 | RGBA,带 alpha | PNG image data, 256 x 539, 8-bit/color RGBA, non-interlaced | 站姿抱书微笑,封面竖排「毛泽东选集」可辨 |
|
|
57
|
+
| `assets/pet-talk.png` | 256×539 | RGBA,带 alpha | 同上 | 同姿势张嘴说话,封面题字保留(字号比 idle 略小、略挤) |
|
|
58
|
+
| `assets/pet-blink.png` | 256×539 | RGBA,带 alpha | 同上 | 闭眼微笑,与 idle 仅表情不同 |
|
|
59
|
+
| `assets/pet-read.png` | 256×539 | RGBA,带 alpha | 同上 | 低头看书,书摊开(见下方缺陷第 2 条) |
|
|
60
|
+
| `assets/icon.svg` | viewBox 512×512,2326 字节 | 纯几何矢量 | — | 米白底 + 红皮书 + 烫金五角星 + 书名条,手写;同款导出为 `assets/icon-256.png` |
|
|
61
61
|
|
|
62
62
|
每张 PNG 都用 `read_image` 逐张看过后才采用;另外把四帧合成到棋盘格背景上放大检查轮廓边缘,确认透明通道有效、无白色描边、脚底与发梢没有被裁断。
|
|
63
63
|
|
|
@@ -88,5 +88,6 @@ python3 ~/.codex/skills/gpt-image/scripts/gen_image.py --size 1024x1536 \
|
|
|
88
88
|
# image=assets/raw/idle-text-v2.png, background=transparent, size=1024x1536
|
|
89
89
|
# prompt=<见上文各帧 prompt>
|
|
90
90
|
|
|
91
|
-
# 3) 统一裁剪 640×1348
|
|
91
|
+
# 3) 统一裁剪 640×1348 母版、透明区域颜色外扩、Lanczos 缩放(Pillow)
|
|
92
|
+
# 4) 交付版再等比降到 256×539,PNG optimize=True(四帧共 603 KB,0.2.1 起)
|
|
92
93
|
```
|
|
Binary file
|
package/assets/icon.svg
CHANGED
|
@@ -1,17 +1,45 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512" role="img" aria-label="鲸鱼娘·小毛
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512" role="img" aria-label="鲸鱼娘·小毛 图标:米白底上的一本红皮书《毛泽东选集》,封面烫金五角星与书名条">
|
|
2
2
|
<title>鲸鱼娘·小毛</title>
|
|
3
|
-
<!--
|
|
4
|
-
<rect x="0" y="0" width="512" height="512" rx="116" fill="#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<!--
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
<!-- 底板:米白圆角方块(深色市场卡片上有边界,浅色界面下不刺眼) -->
|
|
4
|
+
<rect x="0" y="0" width="512" height="512" rx="116" fill="#FFF6E9"/>
|
|
5
|
+
<rect x="14" y="14" width="484" height="484" rx="104" fill="none" stroke="#C1342B" stroke-width="6" stroke-opacity="0.16"/>
|
|
6
|
+
|
|
7
|
+
<!-- 投影:把书从米白底上「抬」起来 -->
|
|
8
|
+
<g filter="url(#softShadow)" opacity="0.22">
|
|
9
|
+
<rect x="132" y="112" width="286" height="308" rx="28" fill="#7A1410"/>
|
|
10
|
+
</g>
|
|
11
|
+
|
|
12
|
+
<g transform="translate(252,256) scale(1.08) translate(-258,-256)">
|
|
13
|
+
<!-- 书页块:右侧露出的米黄页缘 + 两道浅红页线 -->
|
|
14
|
+
<g>
|
|
15
|
+
<path d="M330 118 h78 a14 14 0 0 1 14 14 v248 a14 14 0 0 1 -14 14 h-78 z" fill="#EFDFC4"/>
|
|
16
|
+
<path d="M356 138 v236 M382 138 v236" stroke="#D9C4A2" stroke-width="5" stroke-linecap="round"/>
|
|
17
|
+
</g>
|
|
18
|
+
|
|
19
|
+
<!-- 书壳:深红封面 + 更深一档的书脊 -->
|
|
20
|
+
<g>
|
|
21
|
+
<rect x="120" y="104" width="232" height="304" rx="26" fill="#B3271E"/>
|
|
22
|
+
<rect x="120" y="104" width="46" height="304" rx="22" fill="#8F1E17"/>
|
|
23
|
+
<!-- 书脊烫金线 -->
|
|
24
|
+
<path d="M143 148 v216" stroke="#E8C36A" stroke-width="7" stroke-linecap="round" opacity="0.9"/>
|
|
25
|
+
</g>
|
|
26
|
+
|
|
27
|
+
<!-- 封面烫金细框 -->
|
|
28
|
+
<rect x="192" y="126" width="142" height="260" rx="14" fill="none" stroke="#E8C36A" stroke-width="5" stroke-opacity="0.55"/>
|
|
29
|
+
|
|
30
|
+
<!-- 五角星(10 点纯几何):中心 (263,196),外径 46,内径 17.6 -->
|
|
31
|
+
<polygon fill="#E8C36A" points="263,150 273.32,181.76 306.72,181.76 279.7,201.74 289.02,234.5 263,214.25 236.98,234.5 246.3,201.74 219.28,181.76 252.68,181.76"/>
|
|
32
|
+
|
|
33
|
+
<!-- 书名条:两道烫金横杠,替代小字(36px 下也能读成「书名」) -->
|
|
34
|
+
<g fill="#E8C36A">
|
|
35
|
+
<rect x="215" y="272" width="96" height="16" rx="8"/>
|
|
36
|
+
<rect x="232" y="304" width="62" height="13" rx="6.5" opacity="0.78"/>
|
|
37
|
+
</g>
|
|
38
|
+
</g>
|
|
39
|
+
|
|
40
|
+
<defs>
|
|
41
|
+
<filter id="softShadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
42
|
+
<feGaussianBlur stdDeviation="14"/>
|
|
43
|
+
</filter>
|
|
44
|
+
</defs>
|
|
17
45
|
</svg>
|
package/assets/pet-blink.png
CHANGED
|
Binary file
|
package/assets/pet-idle.png
CHANGED
|
Binary file
|
package/assets/pet-read.png
CHANGED
|
Binary file
|
package/assets/pet-talk.png
CHANGED
|
Binary file
|
package/docs/INSTALL.md
CHANGED
package/docs/RELEASE.md
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
| 项 | 现状(2026-11-01 核对) |
|
|
9
9
|
|---|---|
|
|
10
10
|
| 包名 | `dsh-plugin-maoxuan-pet`(unscoped,npm 上未占用) |
|
|
11
|
-
| 版本 | `0.2.
|
|
11
|
+
| 版本 | `0.2.2` |
|
|
12
12
|
| 代码许可 | MIT(`LICENSE`);语料与立绘的非 MIT 声明见 `NOTICE` |
|
|
13
|
-
| 打包清单 | `npm pack --dry-run` →
|
|
13
|
+
| 打包清单 | `npm pack --dry-run` → 59 files / 1.26 MB(含 33 篇语料;0.2.1 起立绘降到 256×539,包体从 4.2 MB 降下来) |
|
|
14
14
|
| GitHub 账号 | `gh auth status` → `yuna78`(scopes 含 `repo`) |
|
|
15
15
|
| npm 凭据 | **当前 `npm whoami` 返回 401,必须先 `npm login` 或换 token** |
|
|
16
16
|
| 市场收录机制 | awesome-dsh-plugin 索引 **npm 包**(`versions[].source.type = npm`),并用 `package.json` 的 `repository.url` 关联 GitHub 仓;**没有投稿表单**,发布后由爬虫收录 |
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
node verify/smoke.mjs && node verify/contract.mjs && node verify/host.test.mjs
|
|
22
|
-
node
|
|
22
|
+
node tools/audit-corpus-coverage.mjs # 金句逐字命中 33/33 才算健康
|
|
23
23
|
npm pack --dry-run | tail -20 # 确认没有 .dsh-dev/、assets/raw/、verify/
|
|
24
24
|
grep -rInE "sk-[A-Za-z0-9]{16,}|ghp_[A-Za-z0-9]{20,}" --include="*.js" --include="*.json" . | grep -v node_modules
|
|
25
25
|
grep -rIn "/Users/" --include="*.md" --include="*.js" . | grep -v node_modules # 不应出现本机绝对路径
|
|
@@ -56,6 +56,21 @@ gh repo create yuna78/dsh-maoxuan-pet --public --source=. --remote=origin --push
|
|
|
56
56
|
`package.json` 里的 `repository` / `homepage` / `bugs` 目前按**方案 A** 写成 `yuna78/dsh-maoxuan-pet`;
|
|
57
57
|
若选方案 B,先改这三个字段再 publish(npm 版本号不能复用,顺序不能反)。
|
|
58
58
|
|
|
59
|
+
## 3.5 发布后体检(一条命令)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
node scripts/post-publish-check.mjs # 只报告:npm latest / repository / 市场收录
|
|
63
|
+
node scripts/post-publish-check.mjs --strict # 门禁:版本不符或市场未收录则 exit 1
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
注意两个真实踩过的坑:
|
|
67
|
+
|
|
68
|
+
1. **占位版本**:首次发布前若先推了一个 `0.0.0-stage` 之类的 stub 占名,`latest` 会指向它。发完正式版后建议:
|
|
69
|
+
```bash
|
|
70
|
+
npm deprecate dsh-plugin-maoxuan-pet@0.0.0-stage "占位版本,请使用 0.2.0"
|
|
71
|
+
```
|
|
72
|
+
2. **2FA**:账号开了 2FA 时 `npm publish` 会报 `EOTP`,需要 `--otp=<6 位动态码>`,动态码 30 秒过期——要么你在终端交互式输入,要么拿到码后立刻发。
|
|
73
|
+
|
|
59
74
|
## 4. 等市场收录 + 在本地索引里核对
|
|
60
75
|
|
|
61
76
|
```bash
|
|
@@ -78,7 +93,7 @@ cd .. && node build-registry.mjs --write # 重算 registry.json / README 表
|
|
|
78
93
|
node -e "const r=require('./registry.json');console.log(r.plugins.find(p=>p.name==='dsh-plugin-maoxuan-pet'))"
|
|
79
94
|
```
|
|
80
95
|
|
|
81
|
-
期望字段:`openSource: true`、`npm: "0.2.
|
|
96
|
+
期望字段:`openSource: true`、`npm: "0.2.2"`、`market: { title: "yuna78/dsh-maoxuan-pet", version: "0.2.2" }`。
|
|
82
97
|
|
|
83
98
|
## 5. 版本号规则
|
|
84
99
|
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-plugin-maoxuan-pet",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "DSH 悬浮宠物「鲸鱼娘·小毛」:每小时读一篇毛选,给创业中的你说一句能动手的督促;内置毛选公开语料与 maoxuan-pet preset。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|
|
@@ -52,9 +52,10 @@
|
|
|
52
52
|
"corpus/",
|
|
53
53
|
"skill/",
|
|
54
54
|
"docs/",
|
|
55
|
-
"
|
|
55
|
+
"tools/",
|
|
56
56
|
"README.md",
|
|
57
57
|
"CHANGELOG.md",
|
|
58
|
+
"README.en.md",
|
|
58
59
|
"NOTICE",
|
|
59
60
|
"LICENSE",
|
|
60
61
|
"package.json"
|
|
@@ -63,7 +64,8 @@
|
|
|
63
64
|
"corpus": "node scripts/fetch-corpus.mjs",
|
|
64
65
|
"test": "node verify/smoke.mjs && node verify/contract.mjs && node verify/host.test.mjs",
|
|
65
66
|
"test:contract": "node verify/contract.mjs",
|
|
66
|
-
"audit:corpus": "node
|
|
67
|
+
"audit:corpus": "node tools/audit-corpus-coverage.mjs",
|
|
68
|
+
"prepublishOnly": "node verify/smoke.mjs && node verify/contract.mjs"
|
|
67
69
|
},
|
|
68
70
|
"dsh": {
|
|
69
71
|
"bundle": {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// - quote : article.quote must be verbatim in corpus/articles/<id>.md
|
|
4
4
|
// - excerpt : extractExcerpt() must find a usable window (40–90 chars)
|
|
5
5
|
// Read-only, no network, no model calls.
|
|
6
|
-
// Usage: node
|
|
6
|
+
// Usage: node tools/audit-corpus-coverage.mjs [--json]
|
|
7
7
|
import { readFileSync, existsSync } from 'node:fs';
|
|
8
8
|
import { dirname, join } from 'node:path';
|
|
9
9
|
import { fileURLToPath } from 'node:url';
|
package/docs/preview-v3.png
DELETED
|
Binary file
|