dsh-plugin-maoxuan-pet 0.2.0 → 0.2.1

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.2.1 — 2026-11-01
4
+
5
+ 上架插件市场后的首个维护版:图标重做 + 整包瘦身 + 打包门禁补强。
6
+
7
+ ### 图标
8
+ - 包内 `assets/icon.svg` 换成「红皮书」造型:米白底、深红书壳、烫金五角星与书名条;按插件面板卡片实际 36px 校过,缩到 36px 仍能读成一本红皮书。
9
+ - 新增 `assets/icon-256.png`(256×256 RGBA,17 KB),给 [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) 条目的 `icon:` 用——市场只收 GitHub 托管位图,不收 SVG。
10
+
11
+ ### 体积
12
+ - 四帧立绘 640×1348 → 256×539(UI 展示高 132px,2x 屏幕足够):4 张合计 **2.96 MB → 603 KB**。
13
+ - `npm pack` 整包 **4.2 MB → 约 1.2 MB**(59 files),安装与首屏都更快;README / 市场条目用的大图 `docs/screenshot-hero.png` 保留。
14
+
15
+ ### 打包与发布门禁
16
+ - `scripts/audit-corpus-coverage.mjs` 迁到 `tools/`:`scripts/` 是开发脚本,不该进 npm 包;全局开源契约检查此前因此 1 项 FAIL,现在是 0 FAIL / 1 WARN(WARN 已由下一条解决)。
17
+ - 新增 `prepublishOnly`:发布前自动跑 `verify/smoke.mjs` + `verify/contract.mjs`,防手滑发坏版本。
18
+ - `scripts/post-publish-check.mjs`:市场索引有 3.3 MB,超时从 60s 提到 180s(可用 `MARKET_TIMEOUT_MS` 覆盖),慢网下 `--strict` 不再误红。
19
+ - 仓库根新增 `screenshots.json`(`["docs/screenshot-hero.png"]`),喂给 dsh-market 详情页的 AppStore 式截图;以后换图只需往本仓 push,不用再来提 PR。
20
+
21
+ ### 文档
22
+ - 新增英文 README(`README.en.md`),中文 README 顶部加英文入口。
23
+ - README 的资产尺寸、审计脚本路径同步更新;`assets/PROVENANCE.md` 记录交付尺寸与图标改版。
24
+
3
25
  ## 0.2.0 — 2026-11-01
4
26
 
5
27
  首个公开版本。
package/README.en.md ADDED
@@ -0,0 +1,94 @@
1
+ # dsh-maoxuan-pet · Xiao Mao, the whale-girl desktop pet
2
+
3
+ [![verify](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml/badge.svg)](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml) [![npm](https://img.shields.io/npm/v/dsh-plugin-maoxuan-pet.svg)](https://www.npmjs.com/package/dsh-plugin-maoxuan-pet)
4
+
5
+ A floating pet living in the DeepSeek Harness (dsh) web shell. Every hour she reads one
6
+ essay from *Selected Works of Mao Zedong*, turns it into **one ≤200-character nudge** for a
7
+ founder — a verbatim quote or excerpt, one line of pressure in her own voice, and one rule
8
+ with a way to verify it — and shows it in a red-book speech bubble.
9
+
10
+ ![bubble](docs/screenshot-hero.png)
11
+
12
+ > 中文说明见 [README.md](README.md)。
13
+
14
+ ## What it does
15
+
16
+ | Piece | Behaviour |
17
+ |---|---|
18
+ | Pet | 4 sprite frames (idle / talk / blink / read), draggable, position remembered |
19
+ | Bubble | dark-red "book cover" with a gold spine; anchored to the **left** of the pet, so the pet never moves; `收起` / `再督促` are text-only buttons |
20
+ | Reading | opening the card marks that bubble read — the unread badge disappears; the bubble you are reading never gets swapped out |
21
+ | History | `‹ ›` walks back through previous bubbles; with nothing unread you still see the last one produced |
22
+ | Timing | one generation per hour (`everySeconds`), quiet hours, `maxBubbles` history cap |
23
+ | Preset | `maoxuan-pet` — a "Selected Works startup advisor" preset with the bundled corpus registered as the `maoxuan-vademecum` skill |
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ dsh plugin --profile web add dsh-plugin-maoxuan-pet
29
+ # restart dsh web (Ctrl+C, then `dsh web` again), reload the page
30
+ ```
31
+
32
+ Requirements: dsh `>=0.2.1-rc.2 <0.3.0`, Node `^22.19.0 || >=24.0.0`. Web shell only.
33
+
34
+ ## How a bubble is produced
35
+
36
+ ```
37
+ everySeconds → pick next verified essay → template rotates quote/excerpt/summary
38
+ → spawn `dsh --profile headless --json "<prompt>"` (60s-ish, one model call)
39
+ → parse JSON {pua, lesson, axis, gist}
40
+ → quote/excerpt must match the corpus verbatim, otherwise fall back to summary
41
+ → fitLesson(): cite + pua + lesson ≤ 200 chars
42
+ → persist to $DSH_HOME/storages/dsh-maoxuan-pet.json (atomic write)
43
+ → client polls /api/dsh-maoxuan-pet.state every 20s
44
+ ```
45
+
46
+ If the model call fails (no credentials, timeout, non-JSON), the plugin degrades to a **local
47
+ excerpt** and labels it `离线摘录` in the footer — it never invents a quote.
48
+
49
+ - Templates: `quote` (golden line) / `excerpt` (verbatim whole sentences) / `summary` (her own gist).
50
+ - Lesson axes: 客户 customers / 项目 projects / 组织 organisation / 现金流 cash flow / 决策 decisions / 自律 self-discipline.
51
+ - The 200-character cap is a hard invariant, not a suggestion: `fitLesson()` shrinks the lesson,
52
+ never the quote.
53
+
54
+ ## Config
55
+
56
+ ```yaml
57
+ - id: dsh-maoxuan-pet
58
+ config:
59
+ enabled: true
60
+ everySeconds: 3600 # hourly
61
+ firstDelaySeconds: 90
62
+ quietHours: [2, 8] # no pings between 02:00 and 08:00 local time
63
+ maxBubbles: 40
64
+ headless: true # false = only local excerpts, zero model calls
65
+ profile: headless
66
+ timeoutMs: 180000
67
+ businessContext: "40, indie developer, small-tool SaaS"
68
+ ```
69
+
70
+ ## Verification
71
+
72
+ ```bash
73
+ node verify/smoke.mjs # 24 structural checks
74
+ node verify/contract.mjs # 38 pure-function tests
75
+ node verify/host.test.mjs # 18 fake-ctx end-to-end tests (no network, no subprocess)
76
+ node tools/audit-corpus-coverage.mjs # quote must be verbatim in all 33 essays
77
+ npm pack --dry-run # 59 files / 1.3 MB, no .dsh-dev / assets/raw / verify
78
+ ```
79
+
80
+ CI runs the same set on Node 22 and 24. See [verify/README.md](verify/README.md).
81
+
82
+ ## License and third-party content
83
+
84
+ - **Code**: MIT — see [LICENSE](LICENSE).
85
+ - **Bundled corpus** (`corpus/`, 33 essays): **not MIT.** Texts come from the
86
+ [Chinese Marxist Internet Archive](https://www.marxists.org/chinese/maozedong/index.htm) and
87
+ are bundled for personal study only. See [NOTICE](NOTICE). Delete `corpus/articles/` to drop it;
88
+ quote/excerpt templates then degrade safely to summary.
89
+ - **Sprites**: AI-generated (gpt-image-2), a fan-made "whale girl" character — not affiliated with
90
+ DeepSeek. See [assets/PROVENANCE.md](assets/PROVENANCE.md).
91
+
92
+ This plugin is a reading/nudging tool that treats the essays as a source of product and
93
+ entrepreneurship method. It is not affiliated with DeepSeek or any publisher, and it is not
94
+ political advocacy.
package/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # dsh-maoxuan-pet · 鲸鱼娘·小毛
2
2
 
3
+ [English](README.en.md) · 中文
4
+
5
+ [![verify](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml/badge.svg)](https://github.com/yuna78/dsh-maoxuan-pet/actions/workflows/verify.yml) [![npm](https://img.shields.io/npm/v/dsh-plugin-maoxuan-pet.svg)](https://www.npmjs.com/package/dsh-plugin-maoxuan-pet)
6
+
3
7
  > 一只穿红军制服、抱着《毛泽东选集》的鲸鱼娘,住在 DSH 的 Web 界面右下角。
4
8
  > 每小时读一篇毛选,把它变成一句针对**你的**创业处境的思想 + 一句督促,
5
9
  > 并且随时可以开一个新会话问她:根据毛选,我这一步该怎么走。
6
10
 
7
11
  | 需求 | 实现 |
8
12
  |---|---|
9
- | 宠物形态、鲸鱼娘、红军制服、手捧毛选 | `assets/` 里 4 帧 AI 立绘(idle / talk / blink / read,640×1348 RGBA,红封面竖排「毛泽东选集」可辨),`client.js` 在 `shell.overlay` 槽位渲染悬浮宠物 |
13
+ | 宠物形态、鲸鱼娘、红军制服、手捧毛选 | `assets/` 里 4 帧 AI 立绘(idle / talk / blink / read,256×539 RGBA,红封面竖排「毛泽东选集」可辨),`client.js` 在 `shell.overlay` 槽位渲染悬浮宠物 |
10
14
  | 每小时帮我读毛选 | Host 定时器按小时读 `corpus/` 里的下一篇(轮转、避开刚读过的) |
11
15
  | 每小时生成思想 / PUA 我的话,出现在气泡里 | 每次生成 `spawn` 一个 `dsh --profile headless` 对话,拿到结构化 JSON 后推给气泡 |
12
16
  | 有个 preset,能直接问「根据毛选我该怎么做」 | `maoxuan-pet`「毛选创业参谋」preset + 运行时注册的 `maoxuan-vademecum` skill 指向内置语料 |
@@ -64,12 +68,12 @@
64
68
  见 [docs/CONTENT-FRAMEWORK.md](docs/CONTENT-FRAMEWORK.md)。语料能不能支撑 Quote 模板,跑一条审计就知道:
65
69
 
66
70
  ```bash
67
- node scripts/audit-corpus-coverage.mjs # 33 篇:金句逐字命中 33/33,节选可用 32/33
71
+ node tools/audit-corpus-coverage.mjs # 33 篇:金句逐字命中 33/33,节选可用 32/33
68
72
  ```
69
73
 
70
74
  ### 界面行为(这一版按用户逐条反馈定的)
71
75
 
72
- 截图见 [docs/preview-v3.png](docs/preview-v3.png)(红皮书卡片 + `‹ ›` 翻看 + 纯文字按钮)。
76
+ (效果图见下方[「长什么样」](#长什么样))
73
77
 
74
78
  - **红皮书卡片**:深红封面 + 烫金书脊,正文米白;卡片里不出现蓝/紫/绿,落点 chip 用同一族暖金。滚动条也换成烫金滑块 + 深红轨道。
75
79
  - **宠物不动**:卡片绝对定位在宠物左侧(宠物被拖到靠左边缘时自动翻到右侧),点开/收起只让气泡出现或消失,宠物坐标不变。
@@ -100,10 +104,14 @@ node install.mjs # 写入 profile 清单 + pnpm link
100
104
 
101
105
  ### 长什么样
102
106
 
103
- ![红皮书气泡](docs/preview-v3.png)
107
+ ![红皮书气泡](docs/screenshot-hero.png)
108
+
109
+ 深红封面 + 烫金书脊的气泡挂在宠物左侧,宠物自己不动;打开即已读(右上角未读数消失),
110
+ `‹ ›` 可以往回翻历史;定时生成的新气泡会自己弹出来,`收起` / `再督促` 是纯文字按钮。
111
+
112
+ 截图由 `scripts/hero-shot.mjs` 生成(需要本地 headless Chrome + 一个 dsh web 实例),
113
+ 换版式时重拍即可。
104
114
 
105
- 深红封面 + 烫金书脊的气泡挂在宠物左侧;打开即已读,`‹ ›` 可以往回翻历史;
106
- 定时生成的新气泡会自己弹出来。
107
115
 
108
116
  ## 配置
109
117
 
@@ -161,7 +169,7 @@ node --check client.js
161
169
  |---|---|
162
170
  | `--dump-config` 组装 | 插件行与 `preset-maoxuan-pet` 都在组合后的配置里 |
163
171
  | `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 |
172
+ | `GET /api/dsh-maoxuan-pet.asset?name=idle` | 200,`image/png`,256×539 RGBA |
165
173
  | 页面 boot payload | 含 `dsh-plugin-maoxuan-pet/client.js`,实际拉到的 bundle 里含本插件代码且可解析 |
166
174
  | `POST /api/dsh-maoxuan-pet.generate`(真实 headless) | 61s,`mode: "headless"`,返回结构化气泡(篇名/金句/思想/启示/督促/动作) |
167
175
  | 失败降级 | 无凭据时 5.5s 内降级为 `mode: "offline"` 并写入 `lastError` |
@@ -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 生成),红底圆角方块 + 暖白圆盘 + 蓝色鲸鱼尾 + 红五星,1506 字节。
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` | 640×1348 | RGBA,带 alpha | PNG image data, 640 x 1348, 8-bit/color RGBA, non-interlaced | 站姿抱书微笑,封面竖排「毛泽东选集」可辨 |
57
- | `assets/pet-talk.png` | 640×1348 | RGBA,带 alpha | 同上 | 同姿势张嘴说话,封面题字保留(字号比 idle 略小、略挤) |
58
- | `assets/pet-blink.png` | 640×1348 | RGBA,带 alpha | 同上 | 闭眼微笑,与 idle 仅表情不同 |
59
- | `assets/pet-read.png` | 640×1348 | RGBA,带 alpha | 同上 | 低头看书,书摊开(见下方缺陷第 2 条) |
60
- | `assets/icon.svg` | viewBox 512×512,1506 字节 | 纯几何矢量 | — | 红底 + 暖白圆盘 + 鲸鱼尾 + 红五星,手写 |
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、透明区域颜色外扩、Lanczos 缩放(Pillow)
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="#C1342B"/>
5
- <!-- 内描边:在深色界面 / 深色插件市场卡片上保住边界 -->
6
- <rect x="14" y="14" width="484" height="484" rx="104" fill="none" stroke="#FFF6E9" stroke-width="6" stroke-opacity="0.26"/>
7
- <!-- 暖白圆盘:给蓝色鲸尾与红星提供对比度 -->
8
- <circle cx="256" cy="262" r="150" fill="#FFF6E9"/>
9
- <!-- 红五星:10 点纯几何星形,中心 (256,158),外径 36,内径 13.75 -->
10
- <polygon fill="#C1342B" points="256,122 264.08,146.88 290.24,146.88 269.08,162.25 277.16,187.12 256,171.75 234.84,187.12 242.92,162.25 221.76,146.88 247.92,146.88"/>
11
- <!-- 鲸鱼尾:右瓣尾鳍(圆头尾尖) -->
12
- <path fill="#2E6FB8" d="M256 302 C288 306 326 298 356 280 C384 262 404 234 400 210 A24 24 0 0 0 358 204 C338 232 312 266 290 292 C278 302 266 300 256 302 Z"/>
13
- <!-- 鲸鱼尾:左瓣尾鳍(与右瓣镜像对称) -->
14
- <path fill="#2E6FB8" d="M256 302 C224 306 186 298 156 280 C128 262 108 234 112 210 A24 24 0 0 1 154 204 C174 232 200 266 222 292 C234 302 246 300 256 302 Z"/>
15
- <!-- 尾柄:略深的蓝,把两瓣尾鳍收成一个「尾」 -->
16
- <path fill="#1E4E8A" d="M240 302 C238 332 244 356 256 382 C268 356 274 332 272 302 Z"/>
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>
Binary file
Binary file
Binary file
Binary file
package/docs/INSTALL.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  ```bash
13
13
  dsh plugin --profile web add dsh-plugin-maoxuan-pet
14
- # 想固定版本:dsh-plugin-maoxuan-pet@0.2.0
14
+ # 想固定版本:dsh-plugin-maoxuan-pet@0.2.1
15
15
  dsh plugin --profile web list # 确认出现在列表里
16
16
  ```
17
17
 
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.0` |
11
+ | 版本 | `0.2.1` |
12
12
  | 代码许可 | MIT(`LICENSE`);语料与立绘的非 MIT 声明见 `NOTICE` |
13
- | 打包清单 | `npm pack --dry-run` → 57 files / 4.2 MB(含 33 篇语料) |
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 scripts/audit-corpus-coverage.mjs # 金句逐字命中 33/33 才算健康
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.0"`、`market: { title: "yuna78/dsh-maoxuan-pet", version: "0.2.0" }`。
96
+ 期望字段:`openSource: true`、`npm: "0.2.1"`、`market: { title: "yuna78/dsh-maoxuan-pet", version: "0.2.1" }`。
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.0",
3
+ "version": "0.2.1",
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
- "scripts/audit-corpus-coverage.mjs",
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 scripts/audit-corpus-coverage.mjs"
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 scripts/audit-corpus-coverage.mjs [--json]
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';
Binary file