dsh-structured 0.7.4 → 0.8.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 +10 -0
- package/README.md +1 -1
- package/docs/ACCEPTANCE-0.8.1.md +3 -0
- package/docs/CARD-SYSTEM.md +1 -0
- package/docs/METRICS.md +2 -1
- package/docs/TROUBLESHOOT-VISUAL.md +78 -78
- package/lib/index.js +3 -3
- package/package.json +2 -1
- package/src/index.js +3 -3
- package/test/structured.test.mjs +11 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.8.1 — 2026-10-22
|
|
4
|
+
|
|
5
|
+
- 规则文本从“500 字硬上限”改为清晰度约束:标题即结论、按信息类型选组件、一段一主题、证据优先、短答不套卡、长答不设硬性篇幅上限。
|
|
6
|
+
- 表格优先 ≤5 行;信息确实多时用 `dsh-ui` 大表或拆表,不硬砍内容;不为了格式加内容,也不为了字数删信息。
|
|
7
|
+
- 同步 README、`docs/METRICS.md`、`docs/CARD-SYSTEM.md` 与测试断言;无运行时截断、无字数统计、无长度预算;不改 client/注入通道。
|
|
8
|
+
|
|
9
|
+
## Unreleased
|
|
10
|
+
|
|
11
|
+
- 新增 `docs/MAINTENANCE.md`(每日巡检手册)与 `docs/MAINTENANCE-LOG.md`(巡检记录);两者不进 npm 包(`files` 增加 `!docs/MAINTENANCE*.md`,打包仍为 34 文件)。
|
|
12
|
+
|
|
3
13
|
## 0.7.4 — 2026-10-21
|
|
4
14
|
|
|
5
15
|
- 发布准备:加入 `assets/screenshots/`(4 张)、`screenshots.json`、README Screenshots 与 npm/市场/GitHub Release 安装说明。
|
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ pnpm add $tgz
|
|
|
95
95
|
- 开关按会话独立,状态落在 `$DSH_HOME/dsh-structured/state.json`(tmp + rename 原子写)。
|
|
96
96
|
- 新会话默认开启;`defaultEnabled: false` 可改默认值(见配置)。
|
|
97
97
|
- 自定义规则:写 `$DSH_HOME/dsh-structured/style.md`,**非空即整份覆盖**内置文本,保存后下一轮生效;文件为空或删除时回落内置。
|
|
98
|
-
- 内置文本与 `~/.dsh/AGENTS.md` 第 7
|
|
98
|
+
- 内置文本与 `~/.dsh/AGENTS.md` 第 7 节同源:首句结论、组件化正文、一段一主题、禁过程叙事与复述、证据优先、短答不套卡;清晰优先,不设硬性篇幅上限。
|
|
99
99
|
|
|
100
100
|
### 视觉层(desktop 主目标;web 兼容)
|
|
101
101
|
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
[AC-001/002] `npm test` 30/30、`node scripts/desktop-check.mjs` 全 PASS;`BUILTIN_STYLE_TEXT`/`TAIL_REMINDER_TEXT` 不再含 `500 字`、`≤500`、`字数上限`,仍含标题即结论、组件、去过程叙事、去重复、证据、短答不套卡。
|
|
2
|
+
[AC-003] 12 条固定 prompt 全部 completed;首屏标题卡 12/12;`> **结论` 0;最大强调块 2;表格结论 12/12;散文 0;过程叙事命中 0;3 条最长回复(08/04/01,2453/1306/1265 字)人工抽查信息完整,未因字数删信息。
|
|
3
|
+
[AC-005/006] README、METRICS、CARD-SYSTEM 明确清晰优先、不设硬性篇幅上限;未改 client/注入通道、无运行时截断;未 push、未 publish、未提市场 PR;本地提交见 `git log -1`。
|
package/docs/CARD-SYSTEM.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
2. **热点预算**:每条实质回复最多 **1 个主卡 + 1 个行动/风险卡**;全文强调块 ≤2。
|
|
7
7
|
3. **卡片必须可回退**:没有 GenUI 时用原生 markdown + 我们的 CSS;有 GenUI 时交互/图表卡片走 `dsh-ui`,普通卡片仍走 fallback。
|
|
8
8
|
4. **颜色不超过 3 个语义色**:品牌色(结论/判断/指标/下一步)、warn(风险)、success(验收)。不用第四种装饰色。
|
|
9
|
+
5. **清晰优先,不设硬性篇幅上限**:按信息量组织,不为了字数删信息;表格优先 ≤5 行,信息确实多时拆表或用 `dsh-ui` 大表,不硬砍内容。
|
|
9
10
|
|
|
10
11
|
## 卡片类型
|
|
11
12
|
|
package/docs/METRICS.md
CHANGED
|
@@ -34,7 +34,7 @@ node scripts/measure-prose.mjs --since-days 30 --before "2026-10-20T21:35:00+08:
|
|
|
34
34
|
|
|
35
35
|
## 2. 改后样本(插件开启,测试 profile)
|
|
36
36
|
|
|
37
|
-
- profile:`structured-test`(`dsh-base` + `dsh-headless` + `dsh-structured@0.1.2`)。测试构建是 0.1.2
|
|
37
|
+
- profile:`structured-test`(`dsh-base` + `dsh-headless` + `dsh-structured@0.1.2`)。测试构建是 0.1.2;0.8.1 只改规则文本(清晰度约束,无运行时截断/字数统计),host 注入与统计口径未变;0.7.4 为上一发布版。
|
|
38
38
|
- 模型:headless 默认 `deepseek-flash`。
|
|
39
39
|
- 样本:12 个新会话,同一组 12 条问题;**12/12 会话的 `system/message` 都同时命中主规则段与尾部提醒**。
|
|
40
40
|
- 命令:
|
|
@@ -82,6 +82,7 @@ node scripts/measure-prose.mjs --since-days 30 --before "2026-10-20T21:35:00+08:
|
|
|
82
82
|
node scripts/measure-prose.mjs --sessions session-xxxx
|
|
83
83
|
|
|
84
84
|
# 换首屏阈值 / 换整篇口径
|
|
85
|
+
# 500 是视口高度像素,不是字数;0.8.1 起不设硬性篇幅上限
|
|
85
86
|
node scripts/measure-prose.mjs --first-screen 500
|
|
86
87
|
node scripts/measure-prose.mjs --whole
|
|
87
88
|
```
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
# 宿主升级后 markdown class 改名:影响与排查
|
|
2
|
-
|
|
3
|
-
## 结论
|
|
4
|
-
|
|
5
|
-
视觉层全部依赖宿主内部标记(`[class*="_markdown_"]`、`.md-code-block`、`[data-code-block-banner]`)。宿主把这些 token 改名后,插件**不报错、静默降级**:CSS 0 命中、JS 半死、文字半区照常。现有测试与验收都拦不住它,只能靠渲染进程内的探针确认。
|
|
6
|
-
|
|
7
|
-
## 会发生什么
|
|
8
|
-
|
|
9
|
-
| 半区 | 依赖 | 改名后 |
|
|
10
|
-
| --- | --- | --- |
|
|
11
|
-
| CSS(`src/client.js` 内 `CSS` 常量,全部规则) | `[class*="_markdown_"]` | 0 命中:字号层级、表格、代码块、引用卡、状态色、语言色全部回退宿主原生样式 |
|
|
12
|
-
| JS 装饰(6 处 `querySelectorAll`,行 276/300/310/320/330/339) | `[class*="_markdown_"] …` | 全部返回空:标题图标、状态属性、状态表、表格结论条、代码语言色都不再加 |
|
|
13
|
-
| JS 装饰(1 处,行 283) | 裸 `blockquote` | **仍然生效**:会给引用块加 `data-dsh-structured-card`,但没有任何 CSS 消费它 → 「属性在、样式无」 |
|
|
14
|
-
| 文字半区(`ctx.systemPrompt.section`) | 无 DOM 依赖 | 完全不受影响:注入、`/structured status`、开关都正常,模型仍按结构化输出 |
|
|
15
|
-
|
|
16
|
-
三个后果值得单独记住:
|
|
17
|
-
|
|
18
|
-
1. **没有错误信号。** `console.info('[dsh-structured] visual layer active')` 照样打印,`<style>` 标签也在 DOM 里;这两条只能证明插件加载了,不能证明选择器命中了。
|
|
19
|
-
2. **检测盲区。** 测试只 grep 源码里的标记(`test/structured.test.mjs:470`),验收只看 system prompt 注入;选择器命中失败没有任何断言覆盖。
|
|
20
|
-
3. **边界。** `[class*="_markdown_"]` 对 CSS Module 的 hash 后缀(`_markdown_1a2b3` → `_markdown_9x8y7`)免疫,只有 **token 本身**改了(`_markdownBody_`、`_md_`、`_prose_`、`markdown-body`)才断。所以「升级后样式全丢」基本等于 token 改名,不是 hash 变化。
|
|
21
|
-
|
|
22
|
-
## 怎么排查(3 分钟)
|
|
23
|
-
|
|
24
|
-
1. Desktop 打开 DevTools(`Ctrl+Shift+I`;被禁用时走窗口菜单的开发者工具)。
|
|
25
|
-
2. 在 Console 粘贴探针:
|
|
26
|
-
|
|
27
|
-
```js
|
|
28
|
-
(() => {
|
|
29
|
-
const roots = document.querySelectorAll('[class*="_markdown_"]');
|
|
30
|
-
const n = (s) => document.querySelectorAll(s).length;
|
|
31
|
-
const tokens = new Set();
|
|
32
|
-
for (const el of document.querySelectorAll('[class*="markdown" i], [class*="message" i]')) {
|
|
33
|
-
String(el.className).split(/\s+/).filter((t) => /markdown|md|prose/i.test(t)).forEach((t) => tokens.add(t));
|
|
34
|
-
}
|
|
35
|
-
console.table({
|
|
36
|
-
styleTag: !!document.getElementById('dsh-structured-skin-style'),
|
|
37
|
-
rootFlag: document.documentElement.getAttribute('data-dsh-structured'),
|
|
38
|
-
markdownRoots: roots.length,
|
|
39
|
-
cardAttrs: n('blockquote[data-dsh-structured-card]'),
|
|
40
|
-
headingIcons: n('[data-dsh-structured-icon]'),
|
|
41
|
-
statusAttrs: n('[data-dsh-structured-status]'),
|
|
42
|
-
codeLang: n('[data-dsh-structured-lang]'),
|
|
43
|
-
accentVar: roots[0] ? getComputedStyle(roots[0]).getPropertyValue('--ds-accent').trim() : '(no root)',
|
|
44
|
-
});
|
|
45
|
-
console.log('class tokens:', [...tokens]);
|
|
46
|
-
})()
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
3. 按表判定:
|
|
50
|
-
|
|
51
|
-
| 探针结果 | 判定 | 下一步 |
|
|
52
|
-
| --- | --- | --- |
|
|
53
|
-
| `styleTag=false` | 插件没加载 | 查 profile bundle 行、`cordis.patch.yml`、安装完整性,与改名无关 |
|
|
54
|
-
| `styleTag=true`、`markdownRoots=0`、`cardAttrs>0` | **改名确诊**:JS 半挂、CSS 全挂 | 取新 token 修选择器 |
|
|
55
|
-
| `styleTag=true`、`markdownRoots=0`、`cardAttrs=0` | 改名确诊(当前屏没有引用块) | 同上 |
|
|
56
|
-
| `markdownRoots>0`、`headingIcons=0` | 选择器没问题,是装饰链路没跑/抛错 | 看 Console 报错、确认 `apply` 执行过 |
|
|
57
|
-
| 全部 >0、`accentVar` 为空 | 样式被覆盖或优先级不足 | 查宿主/其他插件的 `!important` |
|
|
58
|
-
|
|
59
|
-
4. 取新 token(在普通 PowerShell 里跑,不在沙箱内):
|
|
60
|
-
|
|
61
|
-
```powershell
|
|
62
|
-
rg -a -o --no-filename '_[A-Za-z]*[Mm]arkdown_[A-Za-z0-9_-]{0,12}' "$env:DSH_APP_ASAR" | Sort-Object -Unique
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
5. 定因:把新 token 与 `src/client.js` 里的 `_markdown_` 对照,再看应用版本(关于页 / `navigator.userAgent`)是否刚升级;`package.json` 的 `dsh.compatibility.dshReleases` 目前只声明到 `0.2.1-rc.2`,新版本一律算未验证。
|
|
66
|
-
|
|
67
|
-
## 修法(推荐,尚未实施)
|
|
68
|
-
|
|
69
|
-
- **别再把 CSS 挂在宿主类名上。** JS 先用候选选择器 + 结构启发式(同时含 `h1–h6`、`table`、`blockquote`、`pre` 的最近公共容器)定位 markdown 根,打上 `data-dsh-structured-root`,CSS 全部改挂这个属性。宿主改名只影响「找容器」这一处,失败可观测。
|
|
70
|
-
- **加启动自检。** 命中 0 → 打一次 `console.warn('[dsh-structured] markdown root not found, selectors drifted')`,并把 `<html>` 的 `data-dsh-structured` 置为 `degraded`,让退化可见。
|
|
71
|
-
- 改 `src/client.js` 后必须 `npm run build`:`lib/client.js` = banner + `src/client.js`,有测试校验(`test/structured.test.mjs:480`)。
|
|
72
|
-
|
|
73
|
-
## 修完回归
|
|
74
|
-
|
|
75
|
-
1. 探针表:`markdownRoots>0`、`headingIcons>0`、`accentVar` 非空。
|
|
76
|
-
2. 四类元素目检:标题层级 + 图标、表格(表头/斑马纹/状态列)、代码块(banner 贴合 + 语言色)、引用卡(结论/风险/验收三色)。
|
|
77
|
-
3. 明暗两主题各一遍;窄窗(<720px)不横向溢出。
|
|
78
|
-
4. 流式输出 30 秒不冻结(MutationObserver 只在 rAF 后扫一次)。
|
|
1
|
+
# 宿主升级后 markdown class 改名:影响与排查
|
|
2
|
+
|
|
3
|
+
## 结论
|
|
4
|
+
|
|
5
|
+
视觉层全部依赖宿主内部标记(`[class*="_markdown_"]`、`.md-code-block`、`[data-code-block-banner]`)。宿主把这些 token 改名后,插件**不报错、静默降级**:CSS 0 命中、JS 半死、文字半区照常。现有测试与验收都拦不住它,只能靠渲染进程内的探针确认。
|
|
6
|
+
|
|
7
|
+
## 会发生什么
|
|
8
|
+
|
|
9
|
+
| 半区 | 依赖 | 改名后 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| CSS(`src/client.js` 内 `CSS` 常量,全部规则) | `[class*="_markdown_"]` | 0 命中:字号层级、表格、代码块、引用卡、状态色、语言色全部回退宿主原生样式 |
|
|
12
|
+
| JS 装饰(6 处 `querySelectorAll`,行 276/300/310/320/330/339) | `[class*="_markdown_"] …` | 全部返回空:标题图标、状态属性、状态表、表格结论条、代码语言色都不再加 |
|
|
13
|
+
| JS 装饰(1 处,行 283) | 裸 `blockquote` | **仍然生效**:会给引用块加 `data-dsh-structured-card`,但没有任何 CSS 消费它 → 「属性在、样式无」 |
|
|
14
|
+
| 文字半区(`ctx.systemPrompt.section`) | 无 DOM 依赖 | 完全不受影响:注入、`/structured status`、开关都正常,模型仍按结构化输出 |
|
|
15
|
+
|
|
16
|
+
三个后果值得单独记住:
|
|
17
|
+
|
|
18
|
+
1. **没有错误信号。** `console.info('[dsh-structured] visual layer active')` 照样打印,`<style>` 标签也在 DOM 里;这两条只能证明插件加载了,不能证明选择器命中了。
|
|
19
|
+
2. **检测盲区。** 测试只 grep 源码里的标记(`test/structured.test.mjs:470`),验收只看 system prompt 注入;选择器命中失败没有任何断言覆盖。
|
|
20
|
+
3. **边界。** `[class*="_markdown_"]` 对 CSS Module 的 hash 后缀(`_markdown_1a2b3` → `_markdown_9x8y7`)免疫,只有 **token 本身**改了(`_markdownBody_`、`_md_`、`_prose_`、`markdown-body`)才断。所以「升级后样式全丢」基本等于 token 改名,不是 hash 变化。
|
|
21
|
+
|
|
22
|
+
## 怎么排查(3 分钟)
|
|
23
|
+
|
|
24
|
+
1. Desktop 打开 DevTools(`Ctrl+Shift+I`;被禁用时走窗口菜单的开发者工具)。
|
|
25
|
+
2. 在 Console 粘贴探针:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
(() => {
|
|
29
|
+
const roots = document.querySelectorAll('[class*="_markdown_"]');
|
|
30
|
+
const n = (s) => document.querySelectorAll(s).length;
|
|
31
|
+
const tokens = new Set();
|
|
32
|
+
for (const el of document.querySelectorAll('[class*="markdown" i], [class*="message" i]')) {
|
|
33
|
+
String(el.className).split(/\s+/).filter((t) => /markdown|md|prose/i.test(t)).forEach((t) => tokens.add(t));
|
|
34
|
+
}
|
|
35
|
+
console.table({
|
|
36
|
+
styleTag: !!document.getElementById('dsh-structured-skin-style'),
|
|
37
|
+
rootFlag: document.documentElement.getAttribute('data-dsh-structured'),
|
|
38
|
+
markdownRoots: roots.length,
|
|
39
|
+
cardAttrs: n('blockquote[data-dsh-structured-card]'),
|
|
40
|
+
headingIcons: n('[data-dsh-structured-icon]'),
|
|
41
|
+
statusAttrs: n('[data-dsh-structured-status]'),
|
|
42
|
+
codeLang: n('[data-dsh-structured-lang]'),
|
|
43
|
+
accentVar: roots[0] ? getComputedStyle(roots[0]).getPropertyValue('--ds-accent').trim() : '(no root)',
|
|
44
|
+
});
|
|
45
|
+
console.log('class tokens:', [...tokens]);
|
|
46
|
+
})()
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
3. 按表判定:
|
|
50
|
+
|
|
51
|
+
| 探针结果 | 判定 | 下一步 |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| `styleTag=false` | 插件没加载 | 查 profile bundle 行、`cordis.patch.yml`、安装完整性,与改名无关 |
|
|
54
|
+
| `styleTag=true`、`markdownRoots=0`、`cardAttrs>0` | **改名确诊**:JS 半挂、CSS 全挂 | 取新 token 修选择器 |
|
|
55
|
+
| `styleTag=true`、`markdownRoots=0`、`cardAttrs=0` | 改名确诊(当前屏没有引用块) | 同上 |
|
|
56
|
+
| `markdownRoots>0`、`headingIcons=0` | 选择器没问题,是装饰链路没跑/抛错 | 看 Console 报错、确认 `apply` 执行过 |
|
|
57
|
+
| 全部 >0、`accentVar` 为空 | 样式被覆盖或优先级不足 | 查宿主/其他插件的 `!important` |
|
|
58
|
+
|
|
59
|
+
4. 取新 token(在普通 PowerShell 里跑,不在沙箱内):
|
|
60
|
+
|
|
61
|
+
```powershell
|
|
62
|
+
rg -a -o --no-filename '_[A-Za-z]*[Mm]arkdown_[A-Za-z0-9_-]{0,12}' "$env:DSH_APP_ASAR" | Sort-Object -Unique
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
5. 定因:把新 token 与 `src/client.js` 里的 `_markdown_` 对照,再看应用版本(关于页 / `navigator.userAgent`)是否刚升级;`package.json` 的 `dsh.compatibility.dshReleases` 目前只声明到 `0.2.1-rc.2`,新版本一律算未验证。
|
|
66
|
+
|
|
67
|
+
## 修法(推荐,尚未实施)
|
|
68
|
+
|
|
69
|
+
- **别再把 CSS 挂在宿主类名上。** JS 先用候选选择器 + 结构启发式(同时含 `h1–h6`、`table`、`blockquote`、`pre` 的最近公共容器)定位 markdown 根,打上 `data-dsh-structured-root`,CSS 全部改挂这个属性。宿主改名只影响「找容器」这一处,失败可观测。
|
|
70
|
+
- **加启动自检。** 命中 0 → 打一次 `console.warn('[dsh-structured] markdown root not found, selectors drifted')`,并把 `<html>` 的 `data-dsh-structured` 置为 `degraded`,让退化可见。
|
|
71
|
+
- 改 `src/client.js` 后必须 `npm run build`:`lib/client.js` = banner + `src/client.js`,有测试校验(`test/structured.test.mjs:480`)。
|
|
72
|
+
|
|
73
|
+
## 修完回归
|
|
74
|
+
|
|
75
|
+
1. 探针表:`markdownRoots>0`、`headingIcons>0`、`accentVar` 非空。
|
|
76
|
+
2. 四类元素目检:标题层级 + 图标、表格(表头/斑马纹/状态列)、代码块(banner 贴合 + 语言色)、引用卡(结论/风险/验收三色)。
|
|
77
|
+
3. 明暗两主题各一遍;窄窗(<720px)不横向溢出。
|
|
78
|
+
4. 流式输出 30 秒不冻结(MutationObserver 只在 rAF 后扫一次)。
|
package/lib/index.js
CHANGED
|
@@ -58,9 +58,9 @@ export const BUILTIN_STYLE_TEXT = [
|
|
|
58
58
|
'面向用户的实质回复按下面的形状组织。这是硬约束,不是风格建议。',
|
|
59
59
|
'',
|
|
60
60
|
'1. **首句给结论,并把它做成卡片**:第一段固定两行——`> **一句标题**`(加粗放大,≤60 个汉字或一句短句)→ `> 1–2 行正文`;标题即结论,细节放正文,不要写「结论」标签,不要再用普通段落重复。',
|
|
61
|
-
'2.
|
|
61
|
+
'2. **按信息类型选组件**:3 条以上要点用清单或表格;每条实质回复 1 个主卡(首段标题无标签);判断/指标/重点卡用 `> **判断**` / `> **指标**` / `> **重点**`;最多再 1 个行动卡(`风险` / `下一步` / `验收`);表格前先给一行 `**表格结论:** ...`;状态行/状态单元格用 `✅ 完成` / `⚠️ 待做` / `❌ 阻塞` 开头;表格优先 ≤5 行;信息确实多时拆表或使用宿主支持的大表,不硬砍内容;不为了格式加内容,也不为了字数删信息;短答不套卡,其余保持中性。',
|
|
62
62
|
'3. **一段一个主题**:同一信息只出现一次,不要正文和组件各说一遍;不写过程叙事(我先…/已经…/接下来…),不写收尾总结,不加「还需要我…吗?」。',
|
|
63
|
-
'4.
|
|
63
|
+
'4. **清晰优先,不设硬性篇幅上限**:组件是帮读者快速定位结论的工具,不是加信息的借口;短答不套卡,长答按信息量组织;判断标准是读者只看首段标题 + 表格首列/列表首句,就能知道结论和下一步;细节写文件,回复保留结论与路径。',
|
|
64
64
|
'5. **支撑信息带证据**:每条支撑尽量带数字、路径或结果;没有证据的判断明确标成推断。',
|
|
65
65
|
'6. **可复制内容用代码块**:提示词、命令、配置、JSON、SQL 等需要复制的文本,用带语言标签的代码块包裹(如 `text` / `powershell`),不要用引用块或普通段落;代码块右上角有复制按钮。',
|
|
66
66
|
].join('\n')
|
|
@@ -72,7 +72,7 @@ export const GENUI_ROUTING_TEXT = [
|
|
|
72
72
|
|
|
73
73
|
/** 尾部提醒:一句话重复契约中最容易衰减的四件事,长度控制在几十个 token。 */
|
|
74
74
|
export const TAIL_REMINDER_TEXT = [
|
|
75
|
-
'提醒:本轮最终回复第一段用无标签标题卡:加粗标题(≤60 字)/ 正文两行;表格前给 `**表格结论:**`;状态用 `✅ 完成` / `⚠️
|
|
75
|
+
'提醒:本轮最终回复第一段用无标签标题卡:加粗标题(≤60 字)/ 正文两行;表格前给 `**表格结论:**`;状态用 `✅ 完成` / `⚠️ 待做`;全文最多两个强调块;表格优先 ≤5 行;不设硬性篇幅上限;清晰优先;可复制内容用代码块。',
|
|
76
76
|
].join('\n')
|
|
77
77
|
|
|
78
78
|
/** DSH home:优先 DSH_HOME,缺省 ~/.dsh。 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-structured",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Structured output for DSH: no-label title card first, then tables/lists/steps; per-session switch and style.md override. 让 DSH 的每条实质回复默认结构化。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"!docs/RE-AUDIT-REPORT.md",
|
|
62
62
|
"!docs/PUBLISH-READY.md",
|
|
63
63
|
"!docs/RELEASE-NOTES-0.7.4.md",
|
|
64
|
+
"!docs/MAINTENANCE*.md",
|
|
64
65
|
"assets/screenshots",
|
|
65
66
|
"screenshots.json",
|
|
66
67
|
"test",
|
package/src/index.js
CHANGED
|
@@ -56,9 +56,9 @@ export const BUILTIN_STYLE_TEXT = [
|
|
|
56
56
|
'面向用户的实质回复按下面的形状组织。这是硬约束,不是风格建议。',
|
|
57
57
|
'',
|
|
58
58
|
'1. **首句给结论,并把它做成卡片**:第一段固定两行——`> **一句标题**`(加粗放大,≤60 个汉字或一句短句)→ `> 1–2 行正文`;标题即结论,细节放正文,不要写「结论」标签,不要再用普通段落重复。',
|
|
59
|
-
'2.
|
|
59
|
+
'2. **按信息类型选组件**:3 条以上要点用清单或表格;每条实质回复 1 个主卡(首段标题无标签);判断/指标/重点卡用 `> **判断**` / `> **指标**` / `> **重点**`;最多再 1 个行动卡(`风险` / `下一步` / `验收`);表格前先给一行 `**表格结论:** ...`;状态行/状态单元格用 `✅ 完成` / `⚠️ 待做` / `❌ 阻塞` 开头;表格优先 ≤5 行;信息确实多时拆表或使用宿主支持的大表,不硬砍内容;不为了格式加内容,也不为了字数删信息;短答不套卡,其余保持中性。',
|
|
60
60
|
'3. **一段一个主题**:同一信息只出现一次,不要正文和组件各说一遍;不写过程叙事(我先…/已经…/接下来…),不写收尾总结,不加「还需要我…吗?」。',
|
|
61
|
-
'4.
|
|
61
|
+
'4. **清晰优先,不设硬性篇幅上限**:组件是帮读者快速定位结论的工具,不是加信息的借口;短答不套卡,长答按信息量组织;判断标准是读者只看首段标题 + 表格首列/列表首句,就能知道结论和下一步;细节写文件,回复保留结论与路径。',
|
|
62
62
|
'5. **支撑信息带证据**:每条支撑尽量带数字、路径或结果;没有证据的判断明确标成推断。',
|
|
63
63
|
'6. **可复制内容用代码块**:提示词、命令、配置、JSON、SQL 等需要复制的文本,用带语言标签的代码块包裹(如 `text` / `powershell`),不要用引用块或普通段落;代码块右上角有复制按钮。',
|
|
64
64
|
].join('\n')
|
|
@@ -70,7 +70,7 @@ export const GENUI_ROUTING_TEXT = [
|
|
|
70
70
|
|
|
71
71
|
/** 尾部提醒:一句话重复契约中最容易衰减的四件事,长度控制在几十个 token。 */
|
|
72
72
|
export const TAIL_REMINDER_TEXT = [
|
|
73
|
-
'提醒:本轮最终回复第一段用无标签标题卡:加粗标题(≤60 字)/ 正文两行;表格前给 `**表格结论:**`;状态用 `✅ 完成` / `⚠️
|
|
73
|
+
'提醒:本轮最终回复第一段用无标签标题卡:加粗标题(≤60 字)/ 正文两行;表格前给 `**表格结论:**`;状态用 `✅ 完成` / `⚠️ 待做`;全文最多两个强调块;表格优先 ≤5 行;不设硬性篇幅上限;清晰优先;可复制内容用代码块。',
|
|
74
74
|
].join('\n')
|
|
75
75
|
|
|
76
76
|
/** DSH home:优先 DSH_HOME,缺省 ~/.dsh。 */
|
package/test/structured.test.mjs
CHANGED
|
@@ -76,12 +76,21 @@ function fakeCtx() {
|
|
|
76
76
|
return { ctx, sections, commands, warnings }
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
test('
|
|
79
|
+
test('内置规则覆盖首句结论、组件、清晰度三件事', () => {
|
|
80
80
|
assert.match(BUILTIN_STYLE_TEXT, /首句给结论/)
|
|
81
81
|
assert.match(BUILTIN_STYLE_TEXT, /清单或表格/)
|
|
82
|
-
assert.match(BUILTIN_STYLE_TEXT,
|
|
82
|
+
assert.match(BUILTIN_STYLE_TEXT, /标题即结论/)
|
|
83
|
+
assert.match(BUILTIN_STYLE_TEXT, /表格优先 ≤5 行/)
|
|
84
|
+
assert.match(BUILTIN_STYLE_TEXT, /不设硬性篇幅上限/)
|
|
85
|
+
assert.match(BUILTIN_STYLE_TEXT, /不为了字数删信息/)
|
|
86
|
+
assert.match(BUILTIN_STYLE_TEXT, /过程叙事/)
|
|
87
|
+
assert.match(BUILTIN_STYLE_TEXT, /推断/)
|
|
88
|
+
assert.match(BUILTIN_STYLE_TEXT, /短答不套卡/)
|
|
89
|
+
assert.doesNotMatch(BUILTIN_STYLE_TEXT, /500\s*字|≤\s*500|字数上限/)
|
|
83
90
|
assert.match(BUILTIN_STYLE_TEXT, /可复制内容用代码块/)
|
|
84
91
|
assert.match(TAIL_REMINDER_TEXT, /加粗标题/)
|
|
92
|
+
assert.match(TAIL_REMINDER_TEXT, /清晰优先/)
|
|
93
|
+
assert.doesNotMatch(TAIL_REMINDER_TEXT, /500\s*字|≤\s*500|字数上限/)
|
|
85
94
|
assert.match(BUILTIN_STYLE_TEXT, /判断/)
|
|
86
95
|
assert.match(BUILTIN_STYLE_TEXT, /指标/)
|
|
87
96
|
assert.match(BUILTIN_STYLE_TEXT, /风险/)
|