dsh-better-display 0.3.9 → 0.3.12

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.en.md +5 -5
  3. package/README.md +5 -5
  4. package/compat/harness-rc2.json +17 -13
  5. package/docs/extension-points.md +36 -0
  6. package/docs/official-rendering-bridge.md +1 -1
  7. package/lib/client.js +2405 -2411
  8. package/lib/client.js.map +1 -1
  9. package/lib/dsh-better-display.js +9 -18
  10. package/lib/types/client/Blocks.js +4 -4
  11. package/lib/types/client/Blocks.js.map +1 -1
  12. package/lib/types/client/OfficialContent.js +6 -7
  13. package/lib/types/client/OfficialContent.js.map +1 -1
  14. package/lib/types/client/Reader.d.ts.map +1 -1
  15. package/lib/types/client/Reader.js +5 -6
  16. package/lib/types/client/Reader.js.map +1 -1
  17. package/lib/types/client/composer-seat.d.ts +24 -0
  18. package/lib/types/client/composer-seat.d.ts.map +1 -0
  19. package/lib/types/client/composer-seat.js +23 -0
  20. package/lib/types/client/composer-seat.js.map +1 -0
  21. package/lib/types/client/official-slots.d.ts +15 -3
  22. package/lib/types/client/official-slots.d.ts.map +1 -1
  23. package/lib/types/client/official-slots.js +37 -4
  24. package/lib/types/client/official-slots.js.map +1 -1
  25. package/lib/types/client/primitive-labels.d.ts.map +1 -1
  26. package/lib/types/client/primitive-labels.js +1 -0
  27. package/lib/types/client/primitive-labels.js.map +1 -1
  28. package/package.json +21 -20
  29. package/scripts/check-harness-compat.mjs +4 -2
  30. package/scripts/link-harness-dependencies.mjs +48 -11
  31. package/src/client/Blocks.tsx +5 -5
  32. package/src/client/OfficialContent.tsx +7 -7
  33. package/src/client/Reader.module.css +11 -0
  34. package/src/client/Reader.tsx +5 -6
  35. package/src/client/composer-seat.ts +28 -0
  36. package/src/client/official-slots.tsx +38 -5
  37. package/src/client/primitive-labels.ts +1 -0
  38. package/tests/browser-official-bridge.tsx +2 -1
  39. package/tests/fixtures/reader-user-bubble.tsx +37 -15
  40. package/tests/reader-composer-seat.test.ts +61 -0
  41. package/tests/reader-official-users.test.ts +1 -1
  42. package/tests/reader-theme-overlap.test.ts +1 -1
  43. package/tests/reader-user-bubble.test.ts +1 -0
  44. package/tests/reasoning-block-key.test.ts +129 -0
  45. package/tests/stock-install.test.ts +10 -6
  46. package/tsdown.config.ts +12 -3
@@ -1,4 +1,6 @@
1
+ import { type RefObject } from 'react';
1
2
  import type { Context } from '@deepseek-ai/cordis';
3
+ import type { UseGroupAction } from '@deepseek-ai/dsh-client-ui-chat/client';
2
4
  import type { SlotEntryDef, SlotMap, SlotSpec, StoredEntry } from '@deepseek-ai/dsh-client-ui-slots';
3
5
  /**
4
6
  * RC2 composition adapter. Only public registry operations are used. We lend
@@ -15,7 +17,8 @@ export declare const OFFICIAL_SLOTS: {
15
17
  readonly tools: "tool.call.toolview";
16
18
  readonly tail: "conversation.chat.turnTail";
17
19
  readonly nodes: "conversation.chat.node";
18
- readonly images: "conversation.message.images";
20
+ readonly messageImages: "conversation.chat.message.images";
21
+ readonly userImages: "conversation.chat.user.images";
19
22
  };
20
23
  export type OfficialFamily = keyof typeof OFFICIAL_SLOTS;
21
24
  export declare const OFFICIAL_SEATS: {
@@ -23,7 +26,8 @@ export declare const OFFICIAL_SEATS: {
23
26
  readonly tools: "dsh-better-display.official.tools/tool.call.toolview";
24
27
  readonly tail: "dsh-better-display.official.tail/conversation.chat.turnTail";
25
28
  readonly nodes: "dsh-better-display.official.nodes/conversation.chat.node";
26
- readonly images: "dsh-better-display.official.images/conversation.message.images";
29
+ readonly messageImages: "dsh-better-display.official.messageImages/conversation.chat.message.images";
30
+ readonly userImages: "dsh-better-display.official.userImages/conversation.chat.user.images";
27
31
  };
28
32
  export type OfficialSeat = typeof OFFICIAL_SEATS[OfficialFamily];
29
33
  export declare const officialSeat: (family: OfficialFamily, source?: string) => string;
@@ -45,9 +49,17 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
45
49
  'dsh-better-display.official.tools/tool.call.toolview': SlotMap['tool.call.toolview'];
46
50
  'dsh-better-display.official.tail/conversation.chat.turnTail': SlotMap['conversation.chat.turnTail'];
47
51
  'dsh-better-display.official.nodes/conversation.chat.node': SlotMap['conversation.chat.node'];
48
- 'dsh-better-display.official.images/conversation.message.images': SlotMap['conversation.message.images'];
52
+ 'dsh-better-display.official.messageImages/conversation.chat.message.images': SlotMap['conversation.chat.message.images'];
53
+ 'dsh-better-display.official.userImages/conversation.chat.user.images': SlotMap['conversation.chat.user.images'];
49
54
  }
50
55
  }
56
+ /**
57
+ * Searchable hide for official nodes drawn outside the Chat flow viewport.
58
+ * The flow's own `useGroupAction` is not in scope here; this keeps the same
59
+ * `hidden="until-found"` contract so browser find can still reveal the row.
60
+ */
61
+ export declare function useReaderGroupAction(hidden: boolean, reveal: () => void): RefObject<HTMLDivElement>;
62
+ export declare const readerGroupAction: UseGroupAction;
51
63
  /** Official `AssistantNodeView` registers at priority 0. Lower wins. */
52
64
  export declare const OFFICIAL_ASSISTANT_PRIORITY = 0;
53
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"official-slots.d.ts","sourceRoot":"","sources":["../../../src/client/official-slots.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAGrG;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,cAAc,CAAC;AACzD,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,OAAO,cAAc,CAAC,cAAc,CAAC,CAAC;AACjE,eAAO,MAAM,YAAY,GAAI,QAAQ,cAAc,EAAE,SAAQ,MAA+B,WACzC,CAAC;AAEpD,KAAK,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;AAGnC,KAAK,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3G,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAAC;IACnD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACzD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,IAAI,CAAC;CACjE;AAED,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,OAAO;QACf,yEAAyE,EAAE,OAAO,CAAC,qCAAqC,CAAC,CAAC;QAC1H,sDAAsD,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACtF,6DAA6D,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACrG,0DAA0D,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC9F,gEAAgE,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC;KAC1G;CACF;AAUD,wEAAwE;AACxE,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAIlE;AASD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAO3F;AAUD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG;KAAG,CAAC,IAAI,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CAAE,CAUxH;AAqBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAoB,GACnD,MAAM,IAAI,CA+CZ;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,IAAI,CAwB7D;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,cAAc,CAAC,cAAc,CAAC,GAAG,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"official-slots.d.ts","sourceRoot":"","sources":["../../../src/client/official-slots.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { createElement, memo, useMemo } from 'react';
1
+ import { createElement, memo, useEffect, useLayoutEffect, useMemo, useRef } from 'react';
2
2
  /**
3
3
  * RC2 composition adapter. Only public registry operations are used. We lend
4
4
  * registrations a Reader-owned seat, not a second implementation of their UI.
@@ -14,16 +14,48 @@ export const OFFICIAL_SLOTS = {
14
14
  tools: 'tool.call.toolview',
15
15
  tail: 'conversation.chat.turnTail',
16
16
  nodes: 'conversation.chat.node',
17
- images: 'conversation.message.images',
17
+ messageImages: 'conversation.chat.message.images',
18
+ userImages: 'conversation.chat.user.images',
18
19
  };
19
20
  export const OFFICIAL_SEATS = {
20
21
  actions: 'dsh-better-display.official.actions/conversation.chat.assistant-actions',
21
22
  tools: 'dsh-better-display.official.tools/tool.call.toolview',
22
23
  tail: 'dsh-better-display.official.tail/conversation.chat.turnTail',
23
24
  nodes: 'dsh-better-display.official.nodes/conversation.chat.node',
24
- images: 'dsh-better-display.official.images/conversation.message.images',
25
+ messageImages: 'dsh-better-display.official.messageImages/conversation.chat.message.images',
26
+ userImages: 'dsh-better-display.official.userImages/conversation.chat.user.images',
25
27
  };
26
28
  export const officialSeat = (family, source = OFFICIAL_SLOTS[family]) => `dsh-better-display.official.${family}/${source}`;
29
+ /**
30
+ * Searchable hide for official nodes drawn outside the Chat flow viewport.
31
+ * The flow's own `useGroupAction` is not in scope here; this keeps the same
32
+ * `hidden="until-found"` contract so browser find can still reveal the row.
33
+ */
34
+ export function useReaderGroupAction(hidden, reveal) {
35
+ const ref = useRef(null);
36
+ useLayoutEffect(() => {
37
+ const element = ref.current;
38
+ if (element === null)
39
+ return;
40
+ if (hidden && element.contains(element.ownerDocument.activeElement)) {
41
+ reveal();
42
+ return;
43
+ }
44
+ if (hidden)
45
+ element.setAttribute('hidden', 'until-found');
46
+ else
47
+ element.removeAttribute('hidden');
48
+ }, [hidden, reveal]);
49
+ useEffect(() => {
50
+ const element = ref.current;
51
+ if (element === null)
52
+ return;
53
+ element.addEventListener('beforematch', reveal);
54
+ return () => { element.removeEventListener('beforematch', reveal); };
55
+ }, [reveal]);
56
+ return ref;
57
+ }
58
+ export const readerGroupAction = useReaderGroupAction;
27
59
  // Reader draws these rows itself. Everything else, including future kinds, is
28
60
  // mirrored so the official renderer still runs inside the reading view.
29
61
  // 'user' and 'steering' stay mirrored (message-recall buttons and the like).
@@ -50,7 +82,8 @@ const EXPECTED = {
50
82
  tools: { kind: 'keyed', scope: 'session' },
51
83
  tail: { kind: 'list', scope: 'session' },
52
84
  nodes: { kind: 'keyed', scope: 'session' },
53
- images: { kind: 'single', scope: 'session' },
85
+ messageImages: { kind: 'single', scope: 'session' },
86
+ userImages: { kind: 'single', scope: 'session' },
54
87
  };
55
88
  /**
56
89
  * Reader already presents produced paths with its copy/reveal actions. RC2's
@@ -1 +1 @@
1
- {"version":3,"file":"official-slots.js","sourceRoot":"","sources":["../../../src/client/official-slots.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"official-slots.js","sourceRoot":"","sources":["../../../src/client/official-slots.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"primitive-labels.d.ts","sourceRoot":"","sources":["../../../src/client/primitive-labels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAE/C,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAK7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAKjC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAI7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAK/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAI5B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAAoC,CAAC"}
1
+ {"version":3,"file":"primitive-labels.d.ts","sourceRoot":"","sources":["../../../src/client/primitive-labels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAE/C,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAK7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,mBAMjC,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAI7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAK/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAG5B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,cAI5B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAAoC,CAAC"}
@@ -9,6 +9,7 @@ export const readBlockLabels = {
9
9
  expandAria: hidden => `展开其余 ${hidden} 行`, collapse: '收起', expand: hidden => `展开其余 ${hidden} 行`,
10
10
  };
11
11
  export const terminalBlockLabels = {
12
+ commandLine: line => `命令第 ${line} 行`,
12
13
  signal: signal => `信号 ${signal}`, exitCode: code => `退出码 ${code}`, noExitCode: '无退出码',
13
14
  running: '执行中', failed: '失败', done: '已完成', copy: '复制', copied: '已复制',
14
15
  noOutput: '没有输出', collapseAria: '收起命令输出', collapse: '收起',
@@ -1 +1 @@
1
- {"version":3,"file":"primitive-labels.js","sourceRoot":"","sources":["../../../src/client/primitive-labels.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"primitive-labels.js","sourceRoot":"","sources":["../../../src/client/primitive-labels.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-better-display",
3
- "version": "0.3.9",
3
+ "version": "0.3.12",
4
4
  "description": "A calmer reading view for DeepSeek Harness: native process details, live reasoning, and clean final answers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -56,30 +56,30 @@
56
56
  },
57
57
  "peerDependencies": {
58
58
  "@deepseek-ai/cordis": "~4.0.4",
59
- "@deepseek-ai/dsh-api-session-controller": ">=0.2.0-rc.1 <0.2.1",
60
- "@deepseek-ai/dsh-attachment": ">=0.2.0-rc.1 <0.2.1",
61
- "@deepseek-ai/dsh-client-store": ">=0.2.0-rc.1 <0.2.1",
62
- "@deepseek-ai/dsh-client-ui-chat": ">=0.2.0-rc.1 <0.2.1",
63
- "@deepseek-ai/dsh-client-ui-conversation": ">=0.2.0-rc.1 <0.2.1",
64
- "@deepseek-ai/dsh-client-ui-primitives": ">=0.2.0-rc.1 <0.2.1",
65
- "@deepseek-ai/dsh-client-ui-renderer": ">=0.2.0-rc.1 <0.2.1",
66
- "@deepseek-ai/dsh-client-ui-session": ">=0.2.0-rc.1 <0.2.1",
67
- "@deepseek-ai/dsh-client-ui-slots": ">=0.2.0-rc.1 <0.2.1",
68
- "@deepseek-ai/dsh-client-ui-tool": ">=0.2.0-rc.1 <0.2.1",
69
- "@deepseek-ai/dsh-session": ">=0.2.0-rc.1 <0.2.1",
70
- "@deepseek-ai/dsh-util-workspace-path": ">=0.2.0-rc.1 <0.2.1",
59
+ "@deepseek-ai/dsh-api-session-controller": ">=0.2.1-rc.1 <0.2.2",
60
+ "@deepseek-ai/dsh-attachment": ">=0.2.1-rc.1 <0.2.2",
61
+ "@deepseek-ai/dsh-client-store": ">=0.2.1-rc.1 <0.2.2",
62
+ "@deepseek-ai/dsh-client-ui-chat": ">=0.2.1-rc.1 <0.2.2",
63
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.2.1-rc.1 <0.2.2",
64
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.2.1-rc.1 <0.2.2",
65
+ "@deepseek-ai/dsh-client-ui-renderer": ">=0.2.1-rc.1 <0.2.2",
66
+ "@deepseek-ai/dsh-client-ui-session": ">=0.2.1-rc.1 <0.2.2",
67
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.2.1-rc.1 <0.2.2",
68
+ "@deepseek-ai/dsh-client-ui-tool": ">=0.2.1-rc.1 <0.2.2",
69
+ "@deepseek-ai/dsh-session": ">=0.2.1-rc.1 <0.2.2",
70
+ "@deepseek-ai/dsh-util-workspace-path": ">=0.2.1-rc.1 <0.2.2",
71
71
  "react": "^18.2.0"
72
72
  },
73
73
  "devDependencies": {
74
- "@deepseek-ai/dsh-api-remotes": "0.2.0-rc.2",
75
- "@deepseek-ai/dsh-api-session-controller": "0.2.0-rc.2",
76
- "@deepseek-ai/dsh-client-connection": "0.2.0-rc.2",
77
- "@deepseek-ai/dsh-session-turn-outline": "0.2.0-rc.2",
74
+ "@deepseek-ai/dsh-api-remotes": "0.2.1-rc.5",
75
+ "@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.5",
76
+ "@deepseek-ai/dsh-client-connection": "0.2.1-rc.5",
77
+ "@deepseek-ai/dsh-session-turn-outline": "0.2.1-rc.5",
78
78
  "@types/mdast": "^4.0.4",
79
79
  "@types/node": "^22.20.0",
80
80
  "@types/react": "~18.3.1",
81
81
  "lightningcss": "^1.33.0",
82
- "tsdown": "^0.22.2",
82
+ "tsdown": "^0.23.2",
83
83
  "tsx": "^4.22.4",
84
84
  "typescript": "^6.0.3",
85
85
  "semver": "^7.7.2",
@@ -96,7 +96,7 @@
96
96
  },
97
97
  "dependencies": {
98
98
  "clsx": "^2.0.0",
99
- "katex": "^0.16.47",
99
+ "katex": "^0.19.1",
100
100
  "mdast-util-from-markdown": "^2.0.3",
101
101
  "mdast-util-gfm": "^3.1.0",
102
102
  "mdast-util-math": "^3.0.0",
@@ -131,7 +131,8 @@
131
131
  "docs"
132
132
  ],
133
133
  "engines": {
134
- "node": "^22.19.0 || >=24.0.0"
134
+ "node": "^22.19.0 || >=24.0.0",
135
+ "dsh": ">=0.2.1-rc.1 <0.2.2"
135
136
  },
136
137
  "repository": {
137
138
  "type": "git",
@@ -51,8 +51,10 @@ for (const path of execFileSync('rg', ['--files', 'packages/client', '-g', '*.ts
51
51
  visit(file);
52
52
  }
53
53
  registrations.sort();
54
+ const harnessCommit = execFileSync('git', ['-C', harness, 'rev-parse', 'HEAD'], { encoding: 'utf8' }).trim();
54
55
  const current = {
55
56
  harnessVersion: JSON.parse(readFileSync(join(harness, 'packages/client/ui-chat/package.json'), 'utf8')).version,
57
+ harnessCommit,
56
58
  hashes, registrations,
57
59
  };
58
60
  if (process.argv.includes('--record')) {
@@ -63,8 +65,8 @@ if (process.argv.includes('--record')) {
63
65
  const changed = files.filter(file => current.hashes[file] !== baseline.hashes[file]);
64
66
  const added = registrations.filter(row => !baseline.registrations.includes(row));
65
67
  const removed = baseline.registrations.filter(row => !registrations.includes(row));
66
- if (current.harnessVersion !== baseline.harnessVersion || changed.length || added.length || removed.length) {
67
- console.error(JSON.stringify({ compatible: 'review-required', target: current.harnessVersion, changedContractsOrForkSources: changed, addedRegistrations: added, removedRegistrations: removed }, null, 2));
68
+ if (current.harnessVersion !== baseline.harnessVersion || current.harnessCommit !== baseline.harnessCommit || changed.length || added.length || removed.length) {
69
+ console.error(JSON.stringify({ compatible: 'review-required', target: current.harnessVersion, commit: current.harnessCommit, baselineCommit: baseline.harnessCommit, changedContractsOrForkSources: changed, addedRegistrations: added, removedRegistrations: removed }, null, 2));
68
70
  console.error('Review the differences and run the official bridge/visual tests. --record alone is not compatibility proof.');
69
71
  process.exitCode = 1;
70
72
  } else console.log(`Harness compatibility baseline passed (${current.harnessVersion}; ${registrations.length} official registrations).`);
@@ -1,9 +1,9 @@
1
- import { existsSync, mkdirSync, symlinkSync, realpathSync, readFileSync } from 'node:fs';
1
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, symlinkSync, unlinkSync } from 'node:fs';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
  import { createRequire } from 'node:module';
4
4
 
5
- const root = resolve(process.argv[2] || '');
6
- if (!process.argv[2] || !existsSync(join(root, 'tools/dshx/src/client-build.js'))) throw new Error('Pass a prepared Harness checkout.');
5
+ const root = resolve(process.argv[2] || process.env.DSH_REPO || '');
6
+ if (!root || !existsSync(join(root, 'tools/dshx/src/client-build.js'))) throw new Error('Pass a prepared Harness checkout, or set DSH_REPO.');
7
7
  const local = resolve('node_modules');
8
8
  mkdirSync(local, { recursive: true });
9
9
  const shared = {
@@ -24,23 +24,60 @@ const shared = {
24
24
  '@deepseek-ai/dsh-session': 'packages/core/session',
25
25
  '@deepseek-ai/dsh-util-workspace-path': 'packages/util/workspace-path',
26
26
  };
27
- function link(name, target) {
27
+ function link(name, target, replace = false) {
28
28
  if (!existsSync(target)) throw new Error(`Missing Harness dependency target: ${name} (${target})`);
29
29
  const destination = join(local, name);
30
30
  mkdirSync(dirname(destination), { recursive: true });
31
- if (existsSync(destination)) {
32
- if (realpathSync(destination) !== realpathSync(target)) throw new Error(`Dependency mismatch: ${name}`);
33
- return;
31
+ const stat = lstatSync(destination, { throwIfNoEntry: false });
32
+ if (stat) {
33
+ if (!replace && !stat.isSymbolicLink() && existsSync(destination)) return;
34
+ if (existsSync(destination) && realpathSync(destination) === realpathSync(target)) return;
35
+ rmSync(destination, { recursive: true, force: true });
34
36
  }
35
37
  symlinkSync(target, destination);
36
38
  }
37
- for (const [name, path] of Object.entries(shared)) link(name, join(root, path));
39
+ function packageDir(resolver, name) {
40
+ try { return dirname(resolver.resolve(`${name}/package.json`)); }
41
+ catch { /* pnpm may leave the package only in the store. */ }
42
+ const store = join(root, 'node_modules/.pnpm');
43
+ const prefix = name.startsWith('@') ? `${name.slice(1).replace('/', '+')}@` : `${name}@`;
44
+ const scoped = name.startsWith('@');
45
+ const match = existsSync(store) ? readdirSync(store).find(entry => entry.startsWith(prefix) || (scoped && entry.startsWith(name.replace('/', '+') + '@'))) : undefined;
46
+ if (!match) throw new Error(`Missing Harness dependency: ${name}`);
47
+ const nested = join(store, match, 'node_modules', name);
48
+ if (!existsSync(join(nested, 'package.json'))) throw new Error(`Missing Harness dependency: ${name} (${nested})`);
49
+ return nested;
50
+ }
51
+ function declaredTypesExist(pkgDir) {
52
+ const manifest = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8'));
53
+ const types = typeof manifest.types === 'string'
54
+ ? manifest.types
55
+ : manifest.exports?.['.']?.types;
56
+ return typeof types !== 'string' || existsSync(join(pkgDir, types));
57
+ }
58
+ function builtPackage(name) {
59
+ const runtime = process.env.DSH_RUNTIME || join(dirname(root), 'runtime-rc5');
60
+ const store = join(runtime, 'node_modules/.pnpm');
61
+ if (!existsSync(store)) return undefined;
62
+ const slug = `${name.replace('/', '+')}@`;
63
+ const match = readdirSync(store).find(entry => entry.startsWith(slug));
64
+ if (!match) return undefined;
65
+ const pkgDir = join(store, match, 'node_modules', name);
66
+ return existsSync(join(pkgDir, 'package.json')) && declaredTypesExist(pkgDir) ? pkgDir : undefined;
67
+ }
68
+ for (const [name, path] of Object.entries(shared)) {
69
+ const source = join(root, path);
70
+ const target = (name === '@deepseek-ai/cordis' || !declaredTypesExist(source)) ? (builtPackage(name) ?? source) : source;
71
+ link(name, target, true);
72
+ }
38
73
  const require = createRequire(join(root, 'packages/client/ui-conversation/package.json'));
39
74
  const rootRequire = createRequire(join(root, 'package.json'));
40
- for (const name of ['react', '@types/react']) link(name, dirname(require.resolve(`${name}/package.json`)));
41
- for (const name of ['@types/node', 'typescript', 'tsdown', 'tsx']) link(name, dirname(rootRequire.resolve(`${name}/package.json`)));
75
+ for (const name of ['react', '@types/react']) link(name, packageDir(require, name));
76
+ for (const name of ['@types/node', 'typescript', 'tsdown', 'tsx']) link(name, packageDir(rootRequire, name));
42
77
  for (const name of ['@types/mdast', 'clsx', 'katex', 'mdast-util-from-markdown', 'mdast-util-gfm', 'mdast-util-math', 'micromark-core-commonmark', 'micromark-extension-gfm', 'micromark-extension-math', 'micromark-factory-space', 'micromark-util-character', 'micromark-util-classify-character', 'micromark-util-sanitize-uri', 'micromark-util-symbol', 'micromark-util-types']) {
43
- link(name, join(root, 'packages/client/ui-primitives/node_modules', name));
78
+ const target = join(root, 'packages/client/ui-primitives/node_modules', name);
79
+ if (!existsSync(target)) continue;
80
+ link(name, target);
44
81
  }
45
82
  mkdirSync(join(local, '.bin'), { recursive: true });
46
83
  for (const name of ['typescript', 'tsdown']) {
@@ -120,11 +120,11 @@ function ReadingMarkdown({ blockKey, source, ...props }: MarkdownStreamProps & {
120
120
  return <MarkdownStream {...props} />;
121
121
  }
122
122
 
123
- type ReasoningStreamProps = { text: string; streaming: boolean; holdFormatting: boolean; transformed?: boolean } & TextPresentation;
123
+ type ReasoningStreamProps = { blockKey: string; text: string; streaming: boolean; holdFormatting: boolean; transformed?: boolean } & TextPresentation;
124
124
 
125
- function ReasoningStream({ text, streaming, holdFormatting, startedAt, interrupted = false, liveText = false, transformed = false }: ReasoningStreamProps) {
125
+ function ReasoningStream({ blockKey, text, streaming, holdFormatting, startedAt, interrupted = false, liveText = false, transformed = false }: ReasoningStreamProps) {
126
126
  const presentation = useStreamingText(text, streaming, { startedAt, interrupted: interrupted || !liveText, selected: holdFormatting });
127
- return <div className={css.readingText} data-reader-text data-reader-text-kind="reasoning" data-received-length={text.length} data-shown-length={presentation.text.length}
127
+ return <div className={css.readingText} data-reader-text data-reader-text-kind="reasoning" data-reader-reasoning-block-key={blockKey} data-received-length={text.length} data-shown-length={presentation.text.length}
128
128
  data-presentation-pending={presentation.pending || undefined} data-motion-style="opacity-blur" data-ud-motion="reader-text-arrival" data-ud-motion-type="reveal" data-ud-motion-no-flash="true"
129
129
  data-text-transform={transformed ? (streaming ? 'live' : 'final') : undefined}>
130
130
  <MotionPlainText text={presentation.text} enabled={liveText && presentation.reveal} revision={presentation.revision} />
@@ -133,13 +133,13 @@ function ReasoningStream({ text, streaming, holdFormatting, startedAt, interrupt
133
133
 
134
134
  function TransformedReasoning({ registry, blockKey, source, text, streaming, ...props }: ReasoningStreamProps & { registry: TextTransformRegistry; blockKey: string; source: ReaderBlockOwner['source'] }) {
135
135
  const shown = useDisplayText(registry, { text, streaming, blockKey, kind: 'reasoning', source });
136
- return <ReasoningStream {...props} text={shown.text} streaming={displayStreaming(streaming, shown, true)} transformed />;
136
+ return <ReasoningStream {...props} blockKey={blockKey} text={shown.text} streaming={displayStreaming(streaming, shown, true)} transformed />;
137
137
  }
138
138
 
139
139
  function ReadingReasoning({ blockKey, source, ...props }: ReasoningStreamProps & { blockKey: string; source: ReaderBlockOwner['source'] }) {
140
140
  const registry = activeTextTransform();
141
141
  if (registry?.has('reasoning')) return <TransformedReasoning registry={registry} blockKey={blockKey} source={source} {...props} />;
142
- return <ReasoningStream {...props} />;
142
+ return <ReasoningStream {...props} blockKey={blockKey} />;
143
143
  }
144
144
 
145
145
  function fallback(block: AssistantBlock, streaming: boolean, source: ReaderBlockOwner['source'], loadImage: BlockRenderProps['loadImage'], fillComposer: BlockRenderProps['fillComposer'], holdFormatting: boolean, presentation: TextPresentation, blockKey: string, fileMentions?: BlockRenderProps['fileMentions']): ReactNode {
@@ -3,7 +3,7 @@ import type { AssistantActionOwnerProps, ChatConversationViewNode, ChatNode, Cha
3
3
  import { createSnapshotStore } from '@deepseek-ai/dsh-client-store';
4
4
  import type { AssistantBlock, ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client';
5
5
  type MessageId = AssistantActionOwnerProps['messageId'];
6
- import { OFFICIAL_SEATS } from './official-slots.js';
6
+ import { OFFICIAL_SEATS, readerGroupAction } from './official-slots.js';
7
7
  import type { BlockRenderProps } from './types.js';
8
8
  import { chatSeatProps } from './chat-seat.js';
9
9
  import { Blocks } from './Blocks.js';
@@ -42,17 +42,17 @@ function chatNodeOwner(render: BlockRenderProps, official: NonNullable<BlockRend
42
42
  return {
43
43
  cwd: render.cwd,
44
44
  openFile: render.openFile ?? (() => {}),
45
- openSkill: () => {},
46
45
  forkAt: render.forkAt ?? (() => {}),
47
46
  inspectCall: callId => official.openView('trajectory', callId),
48
47
  loadImage: official.officialImageLoader,
49
- renderMessageImages: images => official.renderSlot(OFFICIAL_SEATS.images, {
50
- ...images, loadImage: official.officialImageLoader,
51
- }),
52
48
  fileMentions: official.officialFileMentions,
53
49
  };
54
50
  }
55
51
 
52
+ function nodeHookContext(turnData: unknown, disclosureReset: ReturnType<typeof createSnapshotStore<number>>) {
53
+ return { turnData, disclosureReset, useGroupAction: readerGroupAction };
54
+ }
55
+
56
56
  export function OfficialNode({ node, fallback, ...render }: BlockRenderProps & { node: ChatConversationViewNode; fallback: ReactNode }) {
57
57
  const official = render.official;
58
58
  const [disclosureReset] = useState(() => createSnapshotStore(0));
@@ -61,7 +61,7 @@ export function OfficialNode({ node, fallback, ...render }: BlockRenderProps & {
61
61
  // The runtime node domain is open; the public SlotMap enumerates the known kinds.
62
62
  const renderNode = official.renderSlot as unknown as (key: string, owner: object, options: object) => ReactNode;
63
63
  return <div data-reader-official-node={node.kind} {...(node.kind === 'user' || node.kind === 'steering' ? chatSeatProps(node.kind, node.key) : {})}>
64
- {renderNode(OFFICIAL_SEATS.nodes, { ...chatNodeOwner(render, official), node }, { entryKey: node.kind, hookContext: { turnData: turn?.data, disclosureReset }, fallback })}
64
+ {renderNode(OFFICIAL_SEATS.nodes, { ...chatNodeOwner(render, official), node }, { entryKey: node.kind, hookContext: nodeHookContext(turn?.data, disclosureReset), fallback })}
65
65
  </div>;
66
66
  }
67
67
 
@@ -95,7 +95,7 @@ export function OfficialAssistantBody({
95
95
  // slice is what a replacement that ignores groupPart actually receives.
96
96
  return renderNode(OFFICIAL_SEATS.nodes, { ...chatNodeOwner(render, official), node: view, groupPart: 'response' }, {
97
97
  entryKey: 'assistant-step',
98
- hookContext: { turnData: turn?.data, disclosureReset },
98
+ hookContext: nodeHookContext(turn?.data, disclosureReset),
99
99
  fallback,
100
100
  });
101
101
  }
@@ -752,3 +752,14 @@
752
752
  background: var(--dsw-alias-bg-module-platform, rgba(127, 127, 127, .1));
753
753
  border-color: var(--dsw-alias-border-l2, rgba(127, 127, 127, .28));
754
754
  }
755
+
756
+ /* Host rc.5 keeps [data-composer-seat] mounted on every conversation tab and
757
+ pins it to the scrollport. dsh-claude-style 0.19.x hides that seat whenever
758
+ the first tab is not 对话 (`display: none !important` under
759
+ [data-dsh-claude-composer-hidden]). This rule wins only while the reader
760
+ root is mounted, so opening on 阅读 can type immediately. Switching to
761
+ 轨迹 unmounts the reader and the skin's rule applies again. The seat's own
762
+ display is flex. Keep this selector in sync with READER_COMPOSER_RESTORE. */
763
+ :global(html body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-dsh-claude-composer-hidden]:has([data-dsh-better-display]) [data-composer-seat]) {
764
+ display: flex !important;
765
+ }
@@ -9,7 +9,7 @@ import { BlockBoundary, Blocks, contentBlocks, UserMessageActions } from './Bloc
9
9
  import { AssistantNode } from './AssistantNode.js';
10
10
  import { ToolActivity, ToolMedia } from './ToolActivity.js';
11
11
  import { OfficialNode, OfficialTail } from './OfficialContent.js';
12
- import { OFFICIAL_SEATS } from './official-slots.js';
12
+ import { OFFICIAL_SEATS, readerGroupAction } from './official-slots.js';
13
13
  import { preparingLabel, readerFlow } from './tool-activity.js';
14
14
  import { Disclosure, ProcessFragment, RetiringTurns, StatusText, useMotionAllowed, usePinnedSelection, useReadingScroll } from './motion.js';
15
15
  import { StreamMotionContext } from './streaming.js';
@@ -198,17 +198,13 @@ const MainNode = memo(function MainNode({ useChat, nodeKey, boundary, pinned, pr
198
198
  const owner: ChatNodeOwnerProps & Pick<ReaderProps, 'sessionId'> = {
199
199
  cwd: render.cwd,
200
200
  openFile: render.openFile ?? (() => {}),
201
- openSkill: () => {},
202
201
  forkAt: render.forkAt ?? (() => {}),
203
202
  inspectCall: callId => official.openView('trajectory', callId),
204
203
  loadImage: official.officialImageLoader,
205
- renderMessageImages: images => official.renderSlot(OFFICIAL_SEATS.images, {
206
- ...images, loadImage: official.officialImageLoader,
207
- }),
208
204
  fileMentions: official.officialFileMentions,
209
205
  sessionId: render.sessionId,
210
206
  };
211
- const options = { hookContext: { turnData: turn?.data, disclosureReset }, fallback };
207
+ const options = { hookContext: { turnData: turn?.data, disclosureReset, useGroupAction: readerGroupAction }, fallback };
212
208
  rendered = node.kind === 'user'
213
209
  ? official.renderSlot(OFFICIAL_SEATS.nodes, { ...owner, node }, { ...options, entryKey: 'user' })
214
210
  : official.renderSlot(OFFICIAL_SEATS.nodes, { ...owner, node }, { ...options, entryKey: 'steering' });
@@ -847,6 +843,9 @@ export function Reader(props: ReaderProps) {
847
843
 
848
844
  // ChatView publishes data-chat-flow="" on its column. Skins treat a
849
845
  // scrollport without that hook as inspect-only and hide [data-composer-seat].
846
+ // dsh-claude-style 0.19.x also hides the host seat whenever the first tab
847
+ // is not 对话. Reader.module.css restores that seat only while this root
848
+ // (data-dsh-better-display) is mounted.
850
849
  return <StreamMotionContext.Provider value={streamMotion}><ReaderLaneScope><div ref={root} className={css.root} data-reader-build="0.3.4" data-dsh-better-display="0.3.4" data-reader-wait-clock-version="input-v1" data-reader-wait-start={waitAnchor.time ?? undefined} data-motion={motion ? 'on' : 'off'} data-reader-glass={frostedGlass || undefined} data-reader-auto-fold={autoFold ? 'on' : 'off'}>
851
850
  <TimelineRail items={timelineItems} activeTurn={activeTurn} busyTurn={busyTurn} onNavigate={onNavigateTurn} />
852
851
  <div className={css.column} data-chat-flow="" tabIndex={-1}>
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Whether the host composer seat stays usable for the view that is on screen.
3
+ *
4
+ * Harness 0.2.1-rc.5 always mounts `[data-composer-seat]` beside the active
5
+ * conversation view (`ConversationContent`). `dsh-claude-style` 0.19.x then
6
+ * sets `data-dsh-claude-composer-hidden` on that conversation root whenever
7
+ * the first tab (对话 / `chat`) is not selected, and hides the seat with
8
+ * `display: none !important`. Reader is the only view this package mounts, so
9
+ * the restore rule in `Reader.module.css` matches only while 阅读 is showing.
10
+ * 轨迹 and other tabs keep the skin's own choice.
11
+ */
12
+ export function hostComposerUsable(input: {
13
+ /** The skin has marked this conversation root hidden. */
14
+ skinHidesSeat: boolean;
15
+ /** The reader root is mounted. The host renders only the active view. */
16
+ readerMounted: boolean;
17
+ }): boolean {
18
+ if (!input.skinHidesSeat) return true;
19
+ return input.readerMounted;
20
+ }
21
+
22
+ /**
23
+ * Beats the skin rule
24
+ * `body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-dsh-claude-composer-hidden] [data-composer-seat]`
25
+ * and only while `[data-dsh-better-display]` is under that root.
26
+ */
27
+ export const READER_COMPOSER_RESTORE =
28
+ 'html body[data-dsh-claude-style][data-dsh-claude-composer-active] [data-dsh-claude-composer-hidden]:has([data-dsh-better-display]) [data-composer-seat]';
@@ -1,5 +1,6 @@
1
- import { createElement, memo, useMemo, type ComponentType, type ReactNode } from 'react';
1
+ import { createElement, memo, useEffect, useLayoutEffect, useMemo, useRef, type ComponentType, type ReactNode, type RefObject } from 'react';
2
2
  import type { Context } from '@deepseek-ai/cordis';
3
+ import type { UseGroupAction } from '@deepseek-ai/dsh-client-ui-chat/client';
3
4
  import type { SlotEntryDef, SlotMap, SlotSpec, StoredEntry } from '@deepseek-ai/dsh-client-ui-slots';
4
5
  import type {} from '@deepseek-ai/dsh-client-ui-renderer/client';
5
6
 
@@ -18,7 +19,8 @@ export const OFFICIAL_SLOTS = {
18
19
  tools: 'tool.call.toolview',
19
20
  tail: 'conversation.chat.turnTail',
20
21
  nodes: 'conversation.chat.node',
21
- images: 'conversation.message.images',
22
+ messageImages: 'conversation.chat.message.images',
23
+ userImages: 'conversation.chat.user.images',
22
24
  } as const;
23
25
  export type OfficialFamily = keyof typeof OFFICIAL_SLOTS;
24
26
  export const OFFICIAL_SEATS = {
@@ -26,7 +28,8 @@ export const OFFICIAL_SEATS = {
26
28
  tools: 'dsh-better-display.official.tools/tool.call.toolview',
27
29
  tail: 'dsh-better-display.official.tail/conversation.chat.turnTail',
28
30
  nodes: 'dsh-better-display.official.nodes/conversation.chat.node',
29
- images: 'dsh-better-display.official.images/conversation.message.images',
31
+ messageImages: 'dsh-better-display.official.messageImages/conversation.chat.message.images',
32
+ userImages: 'dsh-better-display.official.userImages/conversation.chat.user.images',
30
33
  } as const;
31
34
  export type OfficialSeat = typeof OFFICIAL_SEATS[OfficialFamily];
32
35
  export const officialSeat = (family: OfficialFamily, source: string = OFFICIAL_SLOTS[family]) =>
@@ -52,10 +55,39 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
52
55
  'dsh-better-display.official.tools/tool.call.toolview': SlotMap['tool.call.toolview'];
53
56
  'dsh-better-display.official.tail/conversation.chat.turnTail': SlotMap['conversation.chat.turnTail'];
54
57
  'dsh-better-display.official.nodes/conversation.chat.node': SlotMap['conversation.chat.node'];
55
- 'dsh-better-display.official.images/conversation.message.images': SlotMap['conversation.message.images'];
58
+ 'dsh-better-display.official.messageImages/conversation.chat.message.images': SlotMap['conversation.chat.message.images'];
59
+ 'dsh-better-display.official.userImages/conversation.chat.user.images': SlotMap['conversation.chat.user.images'];
56
60
  }
57
61
  }
58
62
 
63
+ /**
64
+ * Searchable hide for official nodes drawn outside the Chat flow viewport.
65
+ * The flow's own `useGroupAction` is not in scope here; this keeps the same
66
+ * `hidden="until-found"` contract so browser find can still reveal the row.
67
+ */
68
+ export function useReaderGroupAction(hidden: boolean, reveal: () => void): RefObject<HTMLDivElement> {
69
+ const ref = useRef<HTMLDivElement>(null);
70
+ useLayoutEffect(() => {
71
+ const element = ref.current;
72
+ if (element === null) return;
73
+ if (hidden && element.contains(element.ownerDocument.activeElement)) {
74
+ reveal();
75
+ return;
76
+ }
77
+ if (hidden) element.setAttribute('hidden', 'until-found');
78
+ else element.removeAttribute('hidden');
79
+ }, [hidden, reveal]);
80
+ useEffect(() => {
81
+ const element = ref.current;
82
+ if (element === null) return;
83
+ element.addEventListener('beforematch', reveal);
84
+ return () => { element.removeEventListener('beforematch', reveal); };
85
+ }, [reveal]);
86
+ return ref;
87
+ }
88
+
89
+ export const readerGroupAction: UseGroupAction = useReaderGroupAction;
90
+
59
91
  // Reader draws these rows itself. Everything else, including future kinds, is
60
92
  // mirrored so the official renderer still runs inside the reading view.
61
93
  // 'user' and 'steering' stay mirrored (message-recall buttons and the like).
@@ -83,7 +115,8 @@ const EXPECTED: Record<OfficialFamily, Spec> = {
83
115
  tools: { kind: 'keyed', scope: 'session' },
84
116
  tail: { kind: 'list', scope: 'session' },
85
117
  nodes: { kind: 'keyed', scope: 'session' },
86
- images: { kind: 'single', scope: 'session' },
118
+ messageImages: { kind: 'single', scope: 'session' },
119
+ userImages: { kind: 'single', scope: 'session' },
87
120
  };
88
121
 
89
122
  /**