dsh-feiyu-wardrobe 0.1.0 → 0.2.0
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 +17 -0
- package/README.md +25 -6
- package/bin/feiyu-report.mjs +31 -2
- package/docs/preview/fish-demo.png +0 -0
- package/lib/commands.js +18 -1
- package/lib/image.js +93 -0
- package/lib/util.js +12 -0
- package/package.json +9 -3
- package/screenshots.json +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.0 — 2026-10-30
|
|
4
|
+
|
|
5
|
+
「换装是视觉性的」:补齐出图能力,可直接发 QQ 群 / 评论区。
|
|
6
|
+
|
|
7
|
+
### 新增
|
|
8
|
+
|
|
9
|
+
- `/fish png [尺寸]`:渲染当前穿搭的 PNG(默认 768,可选 256–1600)
|
|
10
|
+
- `dsh-feiyu-report --png <path>` / `--size <像素>`:CLI 直接出图
|
|
11
|
+
- PNG 合成:360×360 场景 + 底部水印条(repo 地址 + 鱼名 + 饲养天数)
|
|
12
|
+
- 依赖 `@resvg/resvg-js`(预编译二进制,本地渲染,无浏览器/无网络)
|
|
13
|
+
- 新增 `screenshots.json`(插件市场 / awesome 列表详情页展示卡图)
|
|
14
|
+
- README 增加「接 QQ / 聊天机器人」章节
|
|
15
|
+
|
|
16
|
+
### 验证
|
|
17
|
+
|
|
18
|
+
- `npm run verify`:tsc --checkJs + 53 tests
|
|
19
|
+
|
|
3
20
|
## 0.1.0 — 2026-10-30
|
|
4
21
|
|
|
5
22
|
第一个公开版本:把 DSH 的 token 花销变成大肥鱼的衣柜。
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
> 把 DSH 的 token 账单,变成一条鱼的衣柜。
|
|
8
8
|
|
|
9
|
-
当前版本:`0.
|
|
9
|
+
当前版本:`0.2.0`
|
|
10
10
|
|
|
11
11
|
DeepSeek Harness 插件:agent 每花掉一次 token,你的大肥鱼就**吃一顿饭**;一顿顿饭攒成**鱼粮币**,鱼粮币解锁 **21 件原创 SVG 穿搭**;`/fish report` 生成一张 **1080×1440 的饲养报告卡**,可以直接发小红书 / QQ 群。
|
|
12
12
|
|
|
@@ -14,11 +14,14 @@ DeepSeek Harness 插件:agent 每花掉一次 token,你的大肥鱼就**吃
|
|
|
14
14
|
- 🎨 **原创形象**:胖鲸 + 21 件手绘 SVG 单品(帽子 / 面部 / 颈部 / 身体 / 手持 / 背景),不打包任何画师二创素材
|
|
15
15
|
- 🔒 **纯本地**:零额外模型调用、零网络请求、不存聊天原文,只存聚合数字
|
|
16
16
|
- 📸 **可晒卡**:饲养天数、投喂金额、吃掉 token、亲密度、心情、近 7 天伙食、今日穿搭
|
|
17
|
+
- 🖼️ **可视化出图**:`/fish png` 或 `dsh-feiyu-report --png` 直接渲染 PNG(默认 768,带 repo 水印),无需浏览器,可直接发 QQ 群 / B站评论区 / 小红书
|
|
17
18
|
|
|
18
19
|

|
|
19
20
|
|
|
20
21
|

|
|
21
22
|
|
|
23
|
+

|
|
24
|
+
|
|
22
25
|
> 名字与形象都是原创,属于社区玩梗项目,**不是 DeepSeek 官方产品**;「大肥鱼」一词来自社区对 DeepSeek 蓝色鲸鱼标识的可爱误认。
|
|
23
26
|
|
|
24
27
|
---
|
|
@@ -51,6 +54,7 @@ dsh --profile web
|
|
|
51
54
|
| `/fish wear <名字\|id>` | 换上已拥有的单品 |
|
|
52
55
|
| `/fish takeoff <部位>` | 脱掉某个部位(`bg` / `body` / `neck` / `face` / `hand` / `hat`) |
|
|
53
56
|
| `/fish rename <名字>` | 给鱼改名 |
|
|
57
|
+
| `/fish png [尺寸]` | 渲染当前穿搭的 PNG(默认 768;可直接发群) |
|
|
54
58
|
| `/fish report` | 生成饲养报告卡(HTML,1080×1440) |
|
|
55
59
|
| `/fish help` | 帮助 |
|
|
56
60
|
|
|
@@ -67,13 +71,17 @@ dsh --profile web
|
|
|
67
71
|
## 报告卡 CLI
|
|
68
72
|
|
|
69
73
|
```sh
|
|
70
|
-
dsh-feiyu-report # 用本机 state
|
|
71
|
-
dsh-feiyu-report --
|
|
74
|
+
dsh-feiyu-report # 用本机 state 生成 HTML 卡片
|
|
75
|
+
dsh-feiyu-report --png fish.png # 直接出 PNG(QQ 群 / 评论区可用)
|
|
76
|
+
dsh-feiyu-report --png fish.png --size 1024
|
|
77
|
+
dsh-feiyu-report --demo --png demo.png
|
|
72
78
|
dsh-feiyu-report --open # 生成后用默认浏览器打开
|
|
73
|
-
dsh-feiyu-report --out card.html #
|
|
79
|
+
dsh-feiyu-report --out card.html # 自定义 HTML 输出路径
|
|
74
80
|
dsh-feiyu-report --sheet # 渲染整个衣柜目录页
|
|
75
81
|
```
|
|
76
82
|
|
|
83
|
+
出图是纯本地 SVG → PNG(`@resvg/resvg-js`,预编译二进制),不调用浏览器、不联网。
|
|
84
|
+
|
|
77
85
|
## 配置
|
|
78
86
|
|
|
79
87
|
在 profile 的 `cordis.patch.yml` 里覆盖(都是可选项):
|
|
@@ -99,11 +107,22 @@ dsh-feiyu-report --sheet # 渲染整个衣柜目录页
|
|
|
99
107
|
- **非官方**:本项目是社区插件,不属于 DeepSeek 官方项目;「大肥鱼」相关梗的归属属于社区。
|
|
100
108
|
- 后续开放「皮肤包」格式时,同样只支持**本地加载**用户自己的素材,不代分发未授权作品。
|
|
101
109
|
|
|
110
|
+
## 接 QQ / 聊天机器人(出图能力)
|
|
111
|
+
|
|
112
|
+
「换装」是视觉性的,所以核心能力是**出图**而不是出文字:
|
|
113
|
+
|
|
114
|
+
- 任何能执行命令的 QQ 机器人(LangBot、DSH + QQ 适配器等)都可以在 `wear` 之后调一次
|
|
115
|
+
`dsh-feiyu-report --png /tmp/fish.png`,把 PNG 直接发到群里;
|
|
116
|
+
- DSH 内也可以用 `/fish png` 生成文件,再由机器人发送;
|
|
117
|
+
- 图片带仓库水印,别人转发一次就是一次曝光。
|
|
118
|
+
|
|
119
|
+
> 注意:本项目只负责「渲染并给出 PNG 文件」,QQ 平台的接入、账号风控由你选用的机器人框架负责。
|
|
120
|
+
|
|
102
121
|
## 兼容性与测试
|
|
103
122
|
|
|
104
123
|
- DSH `>= 0.1.0`(本版在 `0.2.1-rc.2` 实测)
|
|
105
124
|
- Node.js `>= 22.5`,零运行时依赖
|
|
106
|
-
- `npm run verify` = `tsc --checkJs` 类型检查 +
|
|
125
|
+
- `npm run verify` = `tsc --checkJs` 类型检查 + 53 个单元/集成测试(定价、经济、状态迁移、渲染、PNG、命令、CLI)
|
|
107
126
|
|
|
108
127
|
```sh
|
|
109
128
|
npm run verify
|
|
@@ -111,7 +130,7 @@ npm run verify
|
|
|
111
130
|
|
|
112
131
|
## 路线图
|
|
113
132
|
|
|
114
|
-
- **v0.
|
|
133
|
+
- **v0.3**:DSH Web 面板(页内衣橱 UI)、皮肤包格式(`.dshskin`,本地加载)、心情联动穿搭
|
|
115
134
|
- **v0.3**:多鱼塘(多会话鱼)、每日小任务、社区衣服交换码
|
|
116
135
|
- 更远:把 `dsh-memory-gate` 的记忆做成「鱼记得你说过什么」,但依然只读聚合摘要
|
|
117
136
|
|
package/bin/feiyu-report.mjs
CHANGED
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
import { existsSync, readFileSync } from 'node:fs';
|
|
14
14
|
import { spawn } from 'node:child_process';
|
|
15
15
|
import { dirname, join, resolve } from 'node:path';
|
|
16
|
+
import { renderFishPng } from '../lib/image.js';
|
|
16
17
|
import { renderWardrobeSheetHtml } from '../lib/render.js';
|
|
17
18
|
import { createDemoState } from '../lib/demo.js';
|
|
18
19
|
import { validateConfig } from '../lib/config.js';
|
|
19
20
|
import { loadState } from '../lib/state.js';
|
|
20
21
|
import { defaultReportPath, writeReportCard } from '../lib/report.js';
|
|
21
|
-
import { atomicWriteFile } from '../lib/util.js';
|
|
22
|
+
import { atomicWriteBuffer, atomicWriteFile } from '../lib/util.js';
|
|
22
23
|
|
|
23
24
|
const PACKAGE = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
24
25
|
const VERSION = PACKAGE.version ?? '0.0.0';
|
|
@@ -29,7 +30,9 @@ const HELP = `dsh-feiyu-report — 大肥鱼衣橱饲养报告卡
|
|
|
29
30
|
dsh-feiyu-report 从本机 state 生成报告卡
|
|
30
31
|
dsh-feiyu-report --demo 用演示鱼生成一张预览卡
|
|
31
32
|
dsh-feiyu-report --sheet 渲染整个衣柜目录页
|
|
32
|
-
dsh-feiyu-report --
|
|
33
|
+
dsh-feiyu-report --png <path> 渲染当前穿搭的 PNG(可直接发 QQ 群)
|
|
34
|
+
dsh-feiyu-report --size <像素> PNG 边长(256–1600,默认 768)
|
|
35
|
+
dsh-feiyu-report --out <path> 指定 HTML 输出路径
|
|
33
36
|
dsh-feiyu-report --state <path> 指定 state.json
|
|
34
37
|
dsh-feiyu-report --open 生成后用默认浏览器打开
|
|
35
38
|
dsh-feiyu-report --version 版本号
|
|
@@ -47,6 +50,8 @@ function parseArgs(argv) {
|
|
|
47
50
|
help: false,
|
|
48
51
|
version: false,
|
|
49
52
|
out: null,
|
|
53
|
+
png: null,
|
|
54
|
+
size: null,
|
|
50
55
|
state: null,
|
|
51
56
|
};
|
|
52
57
|
for (let index = 0; index < argv.length; index += 1) {
|
|
@@ -74,6 +79,16 @@ function parseArgs(argv) {
|
|
|
74
79
|
index += 1;
|
|
75
80
|
break;
|
|
76
81
|
}
|
|
82
|
+
case '--png': {
|
|
83
|
+
options.png = argv[index + 1] ?? null;
|
|
84
|
+
index += 1;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case '--size': {
|
|
88
|
+
options.size = argv[index + 1] ?? null;
|
|
89
|
+
index += 1;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
77
92
|
case '--state': {
|
|
78
93
|
options.state = argv[index + 1] ?? null;
|
|
79
94
|
index += 1;
|
|
@@ -134,6 +149,20 @@ function main() {
|
|
|
134
149
|
const loaded = loadState(config.statePath, config);
|
|
135
150
|
state = loaded.state;
|
|
136
151
|
}
|
|
152
|
+
if (options.png) {
|
|
153
|
+
const sizeValue = options.size == null ? undefined : Number(options.size);
|
|
154
|
+
if (sizeValue !== undefined && (!Number.isFinite(sizeValue) || sizeValue < 256 || sizeValue > 1600)) {
|
|
155
|
+
throw new Error('--size 需要 256–1600 之间的整数');
|
|
156
|
+
}
|
|
157
|
+
const png = renderFishPng(state, config, {
|
|
158
|
+
...(sizeValue === undefined ? {} : { size: sizeValue }),
|
|
159
|
+
});
|
|
160
|
+
const pngPath = resolve(options.png);
|
|
161
|
+
atomicWriteBuffer(pngPath, png);
|
|
162
|
+
process.stdout.write(`${pngPath}\n`);
|
|
163
|
+
if (options.open) openInBrowser(pngPath);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
137
166
|
const outPath = writeReportCard(state, config, {
|
|
138
167
|
...(options.out ? { outPath: resolve(options.out) } : {}),
|
|
139
168
|
});
|
|
Binary file
|
package/lib/commands.js
CHANGED
|
@@ -6,8 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
import { ITEMS, RARITIES, SLOT_ORDER, findItem, rarityLabel, slotLabel } from './catalog.js';
|
|
8
8
|
import { summaryOf } from './economy.js';
|
|
9
|
+
import { renderFishPng } from './image.js';
|
|
9
10
|
import { writeReportCard } from './report.js';
|
|
10
|
-
import { formatCNY, formatCoins, formatTokens } from './util.js';
|
|
11
|
+
import { atomicWriteBuffer, formatCNY, formatCoins, formatTokens } from './util.js';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
11
13
|
|
|
12
14
|
const USAGE = [
|
|
13
15
|
'/fish 看鱼今天的状态',
|
|
@@ -16,6 +18,7 @@ const USAGE = [
|
|
|
16
18
|
'/fish wear <名字|id> 换上已拥有的衣服',
|
|
17
19
|
'/fish takeoff <部位> 脱掉某个部位(bg/body/neck/face/hand/hat)',
|
|
18
20
|
'/fish rename <名字> 给鱼改名',
|
|
21
|
+
'/fish png [尺寸] 渲染当前穿搭的 PNG(默认 768,可直接发群)',
|
|
19
22
|
'/fish report 生成一张可晒的饲养报告卡',
|
|
20
23
|
'/fish help 显示这份说明',
|
|
21
24
|
].join('\n');
|
|
@@ -114,6 +117,20 @@ export function executeFishCommand(runtime, rawInput, options = {}) {
|
|
|
114
117
|
const result = runtime.rename(tokens.join(' '), now);
|
|
115
118
|
return { kind: result.ok ? 'success' : 'error', text: result.message };
|
|
116
119
|
}
|
|
120
|
+
case 'png':
|
|
121
|
+
case 'image':
|
|
122
|
+
case 'img': {
|
|
123
|
+
const requested = Number(tokens[0]);
|
|
124
|
+
const size = Number.isFinite(requested) && requested >= 256 ? Math.min(1600, Math.round(requested)) : undefined;
|
|
125
|
+
const png = renderFishPng(runtime.state, runtime.config, { now, ...(size ? { size } : {}) });
|
|
126
|
+
const stamp = new Date(now).toISOString().replace(/[:.]/g, '-').slice(0, 19);
|
|
127
|
+
const outPath = join(dirname(runtime.config.statePath), `fish-${stamp}.png`);
|
|
128
|
+
atomicWriteBuffer(outPath, png);
|
|
129
|
+
return {
|
|
130
|
+
kind: 'success',
|
|
131
|
+
text: `出图了:${outPath}\n直接把这张 PNG 发到 QQ 群 / B站评论区即可。`,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
117
134
|
case 'report':
|
|
118
135
|
case 'card': {
|
|
119
136
|
const path = writeReportCard(runtime.state, runtime.config, { now });
|
package/lib/image.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PNG rendering: turns the 360×360 scene into a shareable image with no
|
|
3
|
+
* browser and no network. This is the "visual" half of the wardrobe — the
|
|
4
|
+
* output can be dropped into a QQ group, a B站 comment or a phone album.
|
|
5
|
+
*
|
|
6
|
+
* Uses @resvg/resvg-js (prebuilt Rust binding) so rendering is deterministic
|
|
7
|
+
* and fast; the only external input is the local state file.
|
|
8
|
+
* @module dsh-feiyu-wardrobe/image
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Resvg } from '@resvg/resvg-js';
|
|
12
|
+
import { moodOf } from './economy.js';
|
|
13
|
+
import { CANVAS, sceneInner } from './render.js';
|
|
14
|
+
|
|
15
|
+
export const DEFAULT_PNG_SIZE = 768;
|
|
16
|
+
export const FOOTER_RATIO = 0.085;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @param {string} text
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
function escapeXml(text) {
|
|
23
|
+
return String(text)
|
|
24
|
+
.replaceAll('&', '&')
|
|
25
|
+
.replaceAll('<', '<')
|
|
26
|
+
.replaceAll('>', '>')
|
|
27
|
+
.replaceAll('"', '"')
|
|
28
|
+
.replaceAll("'", ''');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Build the full PNG-ready SVG: the scene square plus an optional footer strip
|
|
33
|
+
* carrying the repo URL and the fish's name.
|
|
34
|
+
* @param {import('./state.js').FishState} state
|
|
35
|
+
* @param {import('./config.js').FeiyuConfig} config
|
|
36
|
+
* @param {{ now?: number, size?: number, watermark?: boolean }} [options]
|
|
37
|
+
* @returns {{ svg: string, width: number, height: number, footerHeight: number }}
|
|
38
|
+
*/
|
|
39
|
+
export function buildPngSvg(state, config, options = {}) {
|
|
40
|
+
const size = Math.max(256, Math.min(1600, Math.round(options.size ?? DEFAULT_PNG_SIZE)));
|
|
41
|
+
const watermark = options.watermark !== false;
|
|
42
|
+
const now = options.now ?? Date.now();
|
|
43
|
+
const mood = moodOf(state, now, config);
|
|
44
|
+
const scale = size / CANVAS;
|
|
45
|
+
const footerHeight = watermark ? Math.round(size * FOOTER_RATIO) : 0;
|
|
46
|
+
const height = size + footerHeight;
|
|
47
|
+
const fontSize = Math.max(12, Math.round(size * 0.024));
|
|
48
|
+
const inner = sceneInner(state, { face: mood.face });
|
|
49
|
+
const footer = watermark
|
|
50
|
+
? `<g font-family="'Noto Sans CJK SC','PingFang SC','Microsoft YaHei',sans-serif">
|
|
51
|
+
<rect x="0" y="${size}" width="${size}" height="${footerHeight}" fill="#0D1524"/>
|
|
52
|
+
<text x="${Math.round(size * 0.035)}" y="${size + Math.round(footerHeight * 0.62)}"
|
|
53
|
+
font-size="${fontSize}" fill="#9FB0C8">大肥鱼衣橱 · github.com/GIT121995/dsh-feiyu-wardrobe</text>
|
|
54
|
+
<text x="${size - Math.round(size * 0.035)}" y="${size + Math.round(footerHeight * 0.62)}"
|
|
55
|
+
font-size="${fontSize}" fill="#F5C542" text-anchor="end">${escapeXml(state.fishName)} · 第 ${Math.max(1, Math.ceil((now - state.bornAt) / 86_400_000))} 天</text>
|
|
56
|
+
</g>`
|
|
57
|
+
: '';
|
|
58
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${height}" viewBox="0 0 ${size} ${height}">
|
|
59
|
+
<rect width="${size}" height="${height}" fill="#0D1524"/>
|
|
60
|
+
<g transform="scale(${scale})">${inner}</g>
|
|
61
|
+
${footer}
|
|
62
|
+
</svg>`;
|
|
63
|
+
return { svg, width: size, height, footerHeight };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Render the dressed fish as a PNG buffer.
|
|
68
|
+
* @param {import('./state.js').FishState} state
|
|
69
|
+
* @param {import('./config.js').FeiyuConfig} config
|
|
70
|
+
* @param {{ now?: number, size?: number, watermark?: boolean }} [options]
|
|
71
|
+
* @returns {Buffer}
|
|
72
|
+
*/
|
|
73
|
+
export function renderFishPng(state, config, options = {}) {
|
|
74
|
+
const { svg, width, height } = buildPngSvg(state, config, options);
|
|
75
|
+
const renderer = new Resvg(svg, {
|
|
76
|
+
fitTo: { mode: 'width', value: width },
|
|
77
|
+
background: '#0D1524',
|
|
78
|
+
font: { loadSystemFonts: true, defaultFontFamily: 'Noto Sans CJK SC' },
|
|
79
|
+
});
|
|
80
|
+
return Buffer.from(renderer.render().asPng());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* PNG IHDR dimensions (for tests and CLI logs).
|
|
85
|
+
* @param {Buffer} png
|
|
86
|
+
* @returns {{ width: number, height: number }}
|
|
87
|
+
*/
|
|
88
|
+
export function pngSize(png) {
|
|
89
|
+
if (!Buffer.isBuffer(png) || png.length < 24) return { width: 0, height: 0 };
|
|
90
|
+
const signature = png.subarray(0, 8).toString('hex');
|
|
91
|
+
if (signature !== '89504e470d0a1a0a') return { width: 0, height: 0 };
|
|
92
|
+
return { width: png.readUInt32BE(16), height: png.readUInt32BE(20) };
|
|
93
|
+
}
|
package/lib/util.js
CHANGED
|
@@ -50,6 +50,18 @@ export function atomicWriteFile(path, text) {
|
|
|
50
50
|
renameSync(tmp, path);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Write a Buffer atomically (temp file + rename).
|
|
55
|
+
* @param {string} path
|
|
56
|
+
* @param {Buffer} buffer
|
|
57
|
+
*/
|
|
58
|
+
export function atomicWriteBuffer(path, buffer) {
|
|
59
|
+
ensureParent(path);
|
|
60
|
+
const tmp = `${path}.${process.pid}.${Math.random().toString(36).slice(2, 8)}.tmp`;
|
|
61
|
+
writeFileSync(tmp, buffer);
|
|
62
|
+
renameSync(tmp, path);
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
/**
|
|
54
66
|
* Serialize and write JSON atomically.
|
|
55
67
|
* @param {string} path
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-feiyu-wardrobe",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "大肥鱼衣橱 —
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "大肥鱼衣橱 — DSH 插件:token 花销变鱼粮,解锁 21 件原创换装,一键出 PNG 可发 QQ 群 / 1080×1440 饲养报告卡(纯本地,零额外模型调用)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./lib/index.js",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"README.md",
|
|
23
23
|
"CHANGELOG.md",
|
|
24
24
|
"LICENSE",
|
|
25
|
-
"docs/preview"
|
|
25
|
+
"docs/preview",
|
|
26
|
+
"screenshots.json",
|
|
27
|
+
"docs/preview/fish-demo.png"
|
|
26
28
|
],
|
|
27
29
|
"scripts": {
|
|
28
30
|
"typecheck": "tsc -p tsconfig.json",
|
|
@@ -32,6 +34,7 @@
|
|
|
32
34
|
"preview": "node scripts/preview.mjs"
|
|
33
35
|
},
|
|
34
36
|
"keywords": [
|
|
37
|
+
"qq-bot",
|
|
35
38
|
"deepseek",
|
|
36
39
|
"deepseek-harness",
|
|
37
40
|
"dsh",
|
|
@@ -70,5 +73,8 @@
|
|
|
70
73
|
"homepage": "https://github.com/GIT121995/dsh-feiyu-wardrobe#readme",
|
|
71
74
|
"bugs": {
|
|
72
75
|
"url": "https://github.com/GIT121995/dsh-feiyu-wardrobe/issues"
|
|
76
|
+
},
|
|
77
|
+
"dependencies": {
|
|
78
|
+
"@resvg/resvg-js": "^2.6.2"
|
|
73
79
|
}
|
|
74
80
|
}
|