@jiugeqqqqq/dsh-house 0.1.2 → 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/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # dsh-house
2
+
3
+ > 一份**常驻的资产清单** + 一个侧边栏页面。
4
+ > 清单每轮自动进系统提示(装了就生效),页面里能搜、能增、能改、能删;
5
+ > 被上下文压缩掉的旧原文还能按关键词翻回来。
6
+
7
+ "房子"是一个比喻:每个大能力/设备/工具算一座房子,只记**有没有、到哪一步、怎么用一句话**。
8
+ 细节不写在这里 —— 需要时用页面底部的「搜历史」去会话存档里翻原话。
9
+
10
+ ## 装
11
+
12
+ ```powershell
13
+ dsh plugin --profile desktop add @jiugeqqqqq/dsh-house
14
+ # 或 web profile
15
+ dsh plugin --profile web add @jiugeqqqqq/dsh-house
16
+ ```
17
+
18
+ 重启 DSH。
19
+
20
+ > 包名带 `@jiugeqqqqq/` 是因为 npm 上裸名 `dsh-house` 已被别人占用。
21
+
22
+ ## 装完什么样
23
+
24
+ 1. **第一次打开侧边栏「房子」** → 如果 `<DSH_HOME>/house.md` 不存在,会自动建一份模板,页面直接能看能改。
25
+ 2. **每一步请求** → 清单全文以 `【资产清单】` 注入系统提示。改了立刻生效,不用重启。
26
+ 3. **页面**:
27
+ - 顶部搜索框:按条目/分组名过滤
28
+ - `+ 新增`:选分组 + 写一行
29
+ - 每条右边 `改` / `删`(删除要二次确认)
30
+ - 底部「搜历史」:按关键词翻会话存档里被压缩掉的原文
31
+ 4. **写回有备份**:每次改动前把 `house.md` 复制成 `house.md.bak-<时间戳>`。
32
+
33
+ 确认装好:
34
+
35
+ ```
36
+ <DSH_HOME>\house.md # 清单本体
37
+ <DSH_HOME>\logs\... # 启动日志里会有 dsh-house: 房子清单 = ...
38
+ ```
39
+
40
+ ## 清单格式
41
+
42
+ 只有两种语法,够用就好:
43
+
44
+ ```markdown
45
+ # 标题(随便写)
46
+
47
+ > 引用块随便写,不进解析
48
+
49
+ ## 分组名
50
+
51
+ - 🏠 **条目名** ✅ 一句话说明
52
+ - 缩进的子项挂在上面那条下面(不算独立条目)
53
+ - 🚧 **在做的东西** 到哪一步了
54
+ ```
55
+
56
+ - `## ` 开一个分组
57
+ - `- ` 开一个条目
58
+ - **缩进的 `- `** 算上一条的子说明(比如「入口:…」「限制:…」),不单独占一条
59
+
60
+ ## 配置
61
+
62
+ ```yaml
63
+ - id: house
64
+ config:
65
+ assetsPath: '' # 留空 = <DSH_HOME>/house.md
66
+ knowledgeDir: '' # 留空 = <DSH_HOME>/knowledge(页面只显示路径,不读内容)
67
+ sessionsDir: '' # 留空 = <DSH_HOME>/sessions(「搜历史」去这里翻)
68
+ autoRotate: false # 默认关,见下
69
+ bridgeUrl: 'http://127.0.0.1:3100'
70
+ bridgeTokenPath: ''
71
+ rotateKeys: ''
72
+ pendingGroup: '正在长出来的'
73
+ rotateCooldownMs: 600000
74
+ ```
75
+
76
+ ## autoRotate(可选,默认关)
77
+
78
+ 如果你有一条能重置会话的桥接(本项目的 QQ 桥接有 `POST /api/session/reset`),
79
+ 可以打开它:**清单被改过、且 `pendingGroup` 那组清空了**,插件就调桥接换新会话,省上下文。
80
+
81
+ ```yaml
82
+ - id: house
83
+ config:
84
+ autoRotate: true
85
+ bridgeUrl: 'http://127.0.0.1:3100'
86
+ bridgeTokenPath: 'D:/path/to/console-token'
87
+ rotateKeys: 'private:123456789'
88
+ pendingGroup: '正在长出来的'
89
+ ```
90
+
91
+ 没有桥接就保持 `false` —— 它不会自己乱换会话。
92
+
93
+ ## 和 dsh-session-rotate 的关系
94
+
95
+ `dsh-house` 自己注入资产清单。如果你同时装了 `dsh-session-rotate`:
96
+
97
+ ```yaml
98
+ - id: session-rotate
99
+ config:
100
+ assetsPath: '' # ← 留空,否则清单在提示词里出现两遍
101
+ ```
102
+
103
+ 默认就是空的,正常不用动。
104
+
105
+ ## 常见问题
106
+
107
+ **Q:页面空白 / 显示"解析不出条目"?**
108
+ 说明 `house.md` 被外部程序写坏了结构(比如少了 `## ` 或 `- `)。页面会直接把原文摊开显示,照着补回格式即可。原文件也有 `.bak-*` 备份。
109
+
110
+ **Q:改了清单,模型没反应?**
111
+ 注入是每一步重新读文件的 —— 检查 `assetsPath` 指对了没,以及文件是不是空的。
112
+
113
+ **Q:搜历史搜不到?**
114
+ 它只翻 `sessionsDir` 下最近 30 天、小于 80MB 的 `session.v4.jsonl.zstd`。刚聊的内容可能还没落盘,等一会儿再搜。
115
+
116
+ **Q:「搜历史」会不会很慢?**
117
+ 会扫文件,但只解压匹配的那些行,一般几秒内。对话特别多时可以把 `days` 限定小一点(页面暂固定 30 天)。
118
+
119
+ ## License
120
+
121
+ MIT
package/cordis.patch.yml CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  - insert:
8
8
  - id: house
9
- name: '@jiugeqqqqq/dsh-house'
9
+ name: dsh-house
10
10
  config:
11
11
  # 房子清单:Markdown,按 "## 分组" 和 "- 条目" 解析。留空 = <DSH_HOME>/house.md
12
12
  assetsPath: ''
package/lib/client.js CHANGED
@@ -225,7 +225,7 @@ window.__ModuleLoader__.load({
225
225
  React.createElement(
226
226
  'div', { key: 'head', style: styles.head },
227
227
  React.createElement('h1', { style: styles.title }, '房子'),
228
- React.createElement('span', { style: styles.sub }, '她的资产与能力清单 · 常驻'),
228
+ React.createElement('span', { style: styles.sub }, '常驻的资产与能力清单'),
229
229
  React.createElement('span', { style: styles.note }, '共 ' + String(total) + ' 条'),
230
230
  ),
231
231
  );
@@ -286,7 +286,24 @@ window.__ModuleLoader__.load({
286
286
  children.push(React.createElement('div', { key: 'loading', style: styles.note }, '读取中…'));
287
287
  }
288
288
  if (!s.loading && !s.error && shown.length === 0) {
289
- children.push(React.createElement('div', { key: 'empty', style: styles.note }, needle ? '没有匹配的房子。' : '还没有房子。'));
289
+ if (needle) {
290
+ children.push(React.createElement('div', { key: 'empty', style: styles.note }, '没有匹配的房子。'));
291
+ } else if (s.data && s.data.raw) {
292
+ // 解析不出任何条目,但文件非空 —— 多半是结构被写坏了。把原文摊开,
293
+ // 至少能看见内容,不至于以为整份清单丢了。
294
+ children.push(
295
+ React.createElement('div', { key: 'rawhead', style: styles.err }, '清单解析不出条目(格式可能被改坏了),下面是原文:'),
296
+ );
297
+ children.push(
298
+ React.createElement(
299
+ 'pre',
300
+ { key: 'raw', style: { whiteSpace: 'pre-wrap', wordBreak: 'break-word', fontSize: '12px', opacity: 0.8, margin: 0 } },
301
+ s.data.raw,
302
+ ),
303
+ );
304
+ } else {
305
+ children.push(React.createElement('div', { key: 'empty', style: styles.note }, '还没有房子。点上面的「+ 新增」写第一条。'));
306
+ }
290
307
  }
291
308
 
292
309
  shown.forEach(function (g, gi) {
@@ -378,7 +395,7 @@ window.__ModuleLoader__.load({
378
395
  return;
379
396
  }
380
397
  var when = new Date(h.time).toLocaleString('zh-CN', { hour12: false });
381
- var who = h.role === 'user' ? '粑粑' : '她';
398
+ var who = h.role === 'user' ? '你' : 'AI';
382
399
  histChildren.push(
383
400
  React.createElement(
384
401
  'div', { key: 'h' + String(i), style: styles.row },
package/lib/host/index.js CHANGED
@@ -107,14 +107,18 @@ export function apply(ctx, config = {}) {
107
107
  const TEMPLATE = [
108
108
  '# 房子(资产清单)',
109
109
  '',
110
- '> 每个大操作一行:任务名 + 到哪一步 + 一句话 + 能搜到的词(工具名/时间)。',
111
- '> 只记「有/没有、到哪一步」;细节留在别处,需要时按关键词搜历史。',
110
+ '> 一行一个:**名字** 状态 一句话。',
111
+ '> 只记「有/没有、到哪一步、怎么用一句话」;细节留在别处,需要时用页面底部的「搜历史」翻。',
112
+ '> 这份文件每一轮都会自动进系统提示 —— 改完立刻生效,不用重启。',
112
113
  '',
113
- '## 住着的地方',
114
- '- 🏠 **示例条目** ✅ 这是自动生成的模板,改成你自己的第一条房子',
114
+ '## 已经有的',
115
+ '- 🏠 **第一条** ✅ 把这条改成你真正能用的东西(工具、设备、账号、脚本都算)',
115
116
  '',
116
117
  '## 正在长出来的',
117
- '- 🚧 **把这条删掉** 这组空了,配合 autoRotate 才会在任务收尾后自动换会话',
118
+ '- 🚧 **还没做完的** 写在这组;这组清空后,配合 autoRotate 才会在任务收尾时换会话',
119
+ '',
120
+ '---',
121
+ '更新:' + new Date().toISOString().slice(0, 10),
118
122
  '',
119
123
  ].join('\n');
120
124
 
@@ -166,7 +170,7 @@ export function apply(ctx, config = {}) {
166
170
  const total = groups.reduce((n, g) => n + g.items.length, 0);
167
171
  return {
168
172
  ok: true,
169
- data: { path: assetsPath, missing: false, created: true, note: '已自动创建一份模板清单', groups, total },
173
+ data: { path: assetsPath, missing: false, created: true, note: '已自动创建一份模板清单', groups, total, raw: '' },
170
174
  };
171
175
  } catch {}
172
176
  }
@@ -182,7 +186,10 @@ export function apply(ctx, config = {}) {
182
186
  }
183
187
  const { groups } = parseWithLines(text);
184
188
  const total = groups.reduce((n, g) => n + g.items.length, 0);
185
- return { ok: true, data: { path: assetsPath, missing: false, groups, total } };
189
+ // 2026-10-27:解析出 0 条但文件非空 → 多半是被外部程序写坏了结构。
190
+ // 这时候把原文带回去,页面直接显示,总比"空白一片"让人以为文件丢了强。
191
+ const raw = total === 0 && text.trim() ? text.slice(0, 20000) : '';
192
+ return { ok: true, data: { path: assetsPath, missing: false, groups, total, raw } };
186
193
  }
187
194
 
188
195
  // ── 搜历史原话 ────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
- {
1
+ {
2
2
  "name": "@jiugeqqqqq/dsh-house",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "房子 — 常驻的资产/能力清单,配一个侧边栏页面。清单会自动进系统提示(装了就生效);房子只记有没有、到哪一步,细节放 knowledge 和日志里。",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,8 +27,18 @@
27
27
  },
28
28
  "manifestVersion": 1
29
29
  },
30
+ "keywords": [
31
+ "dsh",
32
+ "deepseek-harness",
33
+ "assets",
34
+ "capabilities",
35
+ "sidebar",
36
+ "memory"
37
+ ],
38
+ "author": "jiuge",
30
39
  "files": [
31
40
  "lib/**/*.js",
32
- "cordis.patch.yml"
41
+ "cordis.patch.yml",
42
+ "README.md"
33
43
  ]
34
44
  }