dsh-fish-soul 0.13.4 → 0.13.5

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  让一个 QQ 小号背后有"同一个人":固定人格、按人记记忆、有自己的生活节奏、会主动开口;同一个"她"同时出现在 QQ、B站、抖音。
4
4
 
5
- DSH 插件(单角色 `feiyu`)。版本 **0.13.4**。
5
+ DSH 插件(单角色 `feiyu`)。版本 **0.13.5**。
6
6
 
7
7
  ## 能力
8
8
 
@@ -125,7 +125,7 @@ window.__ModuleLoader__.load({
125
125
 
126
126
  /** 每日日记 */
127
127
  function Diary({ data, save, api, notify, load, relTime, ui }) {
128
- const { h, Group, Row, Switch, Muted, Button, Empty, Tag } = ui;
128
+ const { h, Group, Row, Switch, Muted, Button, Empty, Tag, IconButton } = ui;
129
129
  const d = data.diary;
130
130
  const [busy, setBusy] = react.useState(false);
131
131
  if (!d) return null;
@@ -145,7 +145,11 @@ window.__ModuleLoader__.load({
145
145
  Row({ title: "发到 QQ 空间", desc: "默认关;SnowLuma 不支持的话会在动态里记一条失败" },
146
146
  h(Switch, { label: "发到 QQ 空间", checked: c.qzone, onChange: (v) => save({ diary: { qzone: v } }) })),
147
147
  topics.length === 0 ? null : h("div", { className: "fs-list" }, topics.map((x, i) => h("div", { className: "fs-item", key: `t${i}` },
148
- Tag("想聊", "info"), h("span", { className: "fs-item-main" }, `${x.who ? `${x.who}:` : ""}${x.topic}`)))),
148
+ Tag("想聊", "info"), h("span", { className: "fs-item-main" }, `${x.who ? `${x.who}:` : ""}${x.topic}`),
149
+ h("span", { className: "fs-item-meta" }, IconButton("close", "删除", async () => {
150
+ const r = await api("POST", "/diary/topic-remove", { who: x.who ?? "", topic: x.topic });
151
+ if (r?.ok) { notify("删掉了"); load(); } else notify(r?.error ?? "删除失败");
152
+ }))))),
149
153
  h("div", { className: "fs-list" }, (d.entries ?? []).length === 0 ? Empty("还没写过日记")
150
154
  : d.entries.map((e) => h("div", { className: "fs-item", key: e.id, title: e.content },
151
155
  h("span", { className: "fs-item-main" }, e.content.replace(/^\d{4}-\d{2}-\d{2} 的日记:/, "")),
package/lib/client.js CHANGED
@@ -161,8 +161,9 @@ window.__ModuleLoader__.load({
161
161
  h("select", { ...props, className: "fs-input" }, ...options), Icon("chevron", 12));
162
162
 
163
163
  const Empty = (text) => h("div", { className: "fs-empty" }, text);
164
- const Item = ({ key, lead, text, title, meta }) => h("div", { className: "fs-item", key },
165
- lead ?? null, h("span", { className: "fs-item-main", title: title ?? text }, text), meta ? h("span", { className: "fs-item-meta" }, ...meta) : null);
164
+ const Item = ({ key, lead, text, title, meta, onRemove }) => h("div", { className: "fs-item", key },
165
+ lead ?? null, h("span", { className: "fs-item-main", title: title ?? text }, text), meta ? h("span", { className: "fs-item-meta" }, ...meta) : null,
166
+ onRemove ? IconButton("close", "删除", onRemove) : null);
166
167
 
167
168
  /** 表单:服务端数据到了才初始化一次,之后本地编辑、失焦保存。 */
168
169
  function useForm(data, init) {
@@ -350,6 +350,10 @@ window.__ModuleLoader__.load({
350
350
  const [sel, setSel] = react.useState(() => new Set());
351
351
  const qs = new URLSearchParams({ ...(owner !== "all" ? { ownerId: owner } : {}), ...(qApplied ? { q: qApplied } : {}), ...(source ? { source } : {}), ...(bulk ? { limit: "500" } : {}) }).toString();
352
352
  const [data, load] = usePoll(api, `/inspector/overview${qs ? `?${qs}` : ""}`, 0);
353
+ async function dropPending(id) {
354
+ const r = await api("POST", "/inspector/forget", { targetType: "pending", id });
355
+ if (r?.ok) { notify("已删掉这条待办"); load(); } else notify(r?.error ?? "删除失败");
356
+ }
353
357
  const [adding, setAdding] = react.useState("");
354
358
  react.useEffect(() => { setSel(new Set()); }, [owner, qApplied, source, bulk]);
355
359
  if (!data) return null;
@@ -409,7 +413,7 @@ window.__ModuleLoader__.load({
409
413
  h("div", { className: "fs-list" }, memories.length === 0 ? Empty("还没有记忆")
410
414
  : memories.map((m) => h(MemoryItem, { key: m.id, m, ui, api, notify, refresh: load, curGen: data.currentGenerationId ?? 1, selectable: bulk, selected: sel.has(m.id), onSelect })))),
411
415
  pendings.length === 0 ? null : Group({ title: "待办", aside: Tag(String(pendings.length), "outline") },
412
- h("div", { className: "fs-list" }, pendings.map((p) => Item({ key: p.id, lead: Muted(props.fmtDueAt(p.dueAt), { className: "fs-unit num" }), text: p.reason, meta: [p.channelId ?? ""] })))),
416
+ h("div", { className: "fs-list" }, pendings.map((p) => Item({ key: p.id, lead: Muted(props.fmtDueAt(p.dueAt), { className: "fs-unit num" }), text: p.reason, meta: [p.channelId ?? ""], onRemove: () => dropPending(p.id) })))),
413
417
  h(ImportBackup, { ui, api, notify, relTime: props.relTime, onDone: load }));
414
418
  }
415
419
 
package/lib/routes-v09.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * 习惯开关(心情影响行为 / 去 AI 味 / 合并转发 / 群里冷热 / 小互动 / 每轮判断心情 / 日记)、
4
4
  * 每个群的群设定和冷热、按聊天选模型、记忆调试器、现在写一篇日记。
5
5
  */
6
- import { listChatSessions } from './db.js';
6
+ import { listChatSessions, getKv, setKv } from './db.js';
7
7
  import { behaviorConfig, chatModelsConfig, resolveChatModel, groupNotes, setGroupNote } from './behavior.js';
8
8
 
9
9
  const BODY_MAX = 64 * 1024;
@@ -102,6 +102,19 @@ export async function handleV09Route({ method, path, req, send, readBody, sameOr
102
102
  send(200, { ok: true, ...(await debugRecall({ ownerId, text, inGroup: b.inGroup === true })) });
103
103
  return true;
104
104
  }
105
+ // ── 契约 42:删掉一条日记里「想聊的」──
106
+ if (path === '/diary/topic-remove' && post) {
107
+ if (!guard()) return true;
108
+ const b = await body();
109
+ const t = getKv(db, 'diary.topics', null);
110
+ if (!t || !Array.isArray(t.items)) { send(200, { ok: false, error: '没有想聊的' }); return true; }
111
+ const idx = t.items.findIndex((x) => (x.who ?? '') === String(b.who ?? '') && x.topic === String(b.topic ?? ''));
112
+ if (idx === -1) { send(200, { ok: false, error: '这条不在了' }); return true; }
113
+ t.items.splice(idx, 1);
114
+ setKv(db, 'diary.topics', t);
115
+ send(200, { ok: true });
116
+ return true;
117
+ }
105
118
  // ── 契约 41:现在写一篇日记 ──
106
119
  if (path === '/diary/write-now' && post) {
107
120
  if (!guard()) return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-fish-soul",
3
- "version": "0.13.4",
3
+ "version": "0.13.5",
4
4
  "description": "鱼 · 人格、按人记忆(可纠正、有印象、能导入旧聊天记录)、日程自走与主动开口,直连 SnowLuma 收发 QQ(群里会自己插话),B站 / 抖音小号私信与自己刷视频;按功能选模型并统计用量花费,能听会说 QQ 语音、收藏表情包、学群里的梗,可选上网查;心情影响说话、去 AI 味、每个群的设定、按聊天选模型、每晚写日记(DSH 插件,单角色 feiyu)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",