dsh-sidecard-ask 1.2.0 → 1.2.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 +23 -0
- package/README.md +31 -2
- package/client.js +48 -11
- package/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.1
|
|
4
|
+
|
|
5
|
+
**主题:核对 DSH 0.2.0-rc.1 的适配性,并修掉由此暴露的一个真实缺陷。**
|
|
6
|
+
|
|
7
|
+
核对(本机运行中的就是 0.2.0-rc.1,`@deepseek-ai/dsh` 的 `next` 通道):
|
|
8
|
+
|
|
9
|
+
- 包内容层面:`node tools/compat-probe.mjs 0.1.7-rc.2 0.2.0-rc.1` → 16 项能力**逐项一致**,没有任何依赖被移除或改名;
|
|
10
|
+
- 运行实例上:宿主半 `v1.2.0` 正常(`sideEngine`、provider `spawn,fork`、`capabilities.parent` 均可用);
|
|
11
|
+
客户端半在 `shell.overlay` / `conversation.input.right` 都已注册;`standardProps` 仍含 `sessionId` 与 `inputActions`;
|
|
12
|
+
真机端到端作答 `start→delta×31→status→done`(1.36 s)通过。新增的 `sessions.fork`/`uiWorkspace.forkSession`
|
|
13
|
+
可选参数 `onCreated` 是纯增量,不影响既有调用。
|
|
14
|
+
|
|
15
|
+
**修掉的缺陷**:`sidebar.right.pane.tab` 的运行清单里只有 `dsh-better-sidebar:sidecard-ask:card`,
|
|
16
|
+
没有本插件原生右侧栏的 `sidecard-ask:card`——两个适配器用了同一个 tab kind,而 better-sidebar 会把每个 tab 描述符
|
|
17
|
+
镜像注册进**同一个**原生注册表(band `extension`),该注册表对同 band 同 kind 的二次注册抛错,后注册的一方静默失败。
|
|
18
|
+
|
|
19
|
+
- better-sidebar 承载面改用独立类型 `sidecard-ask:card:workbench`(`CARD_KIND_BETTER`),两端不再重叠;
|
|
20
|
+
- `contract-test` 新增"surface kinds must not collide"一节:**在测试里模拟该注册表的重复 kind 抛错规则**
|
|
21
|
+
与 better-sidebar 的镜像注册行为,若两者再共用 kind,测试立即失败;
|
|
22
|
+
- 设置页自检行改为同时报告**两个适配器**(原先原生适配器的错误在界面上不可见,只能靠翻槽位清单发现)。
|
|
23
|
+
|
|
24
|
+
自测 289 → **295 项**(verify 53 / contract 124 / smoke 118)。
|
|
25
|
+
|
|
3
26
|
## 1.2.0
|
|
4
27
|
|
|
5
28
|
**主题:核对并加固与 dsh-better-sidebar 0.22.1 的适配。**
|
package/README.md
CHANGED
|
@@ -183,6 +183,35 @@ plugin_manager(action="install_bundle", target="D:\\Users\\34332\\AI\\dsh-sideca
|
|
|
183
183
|
|
|
184
184
|
> 注意:`version` 是加载到浏览器里的那份模块报告的版本。页面刷新后即可用它确认"跑的是不是 0.22.1"。
|
|
185
185
|
|
|
186
|
+
### 5.2 与 DSH 0.2.0-rc.1 的适配核对(2026-09-29)
|
|
187
|
+
|
|
188
|
+
本机实际运行的就是 **0.2.0-rc.1**(`@deepseek-ai/dsh` 的 `next` 通道;`latest` 仍是 0.1.7-rc.2)。核对分两层:
|
|
189
|
+
|
|
190
|
+
**① 包内容层面**(`node tools/compat-probe.mjs 0.1.7-rc.2 0.2.0-rc.1`):
|
|
191
|
+
16 项能力**逐项与 0.1.7-rc.2 完全一致**——`shell.overlay`、`conversation.input.right`、`settings.section`、
|
|
192
|
+
`data-slot` 锚点、原生右侧栏、`sessions.using/retain`、归档门、`agent/assistant-stream`、子代理、`tools.schemas`、
|
|
193
|
+
`webServer` 路由……全部 ✅。
|
|
194
|
+
|
|
195
|
+
**② 在运行中的实例上实测**:
|
|
196
|
+
|
|
197
|
+
| 检查 | 结果 |
|
|
198
|
+
|---|---|
|
|
199
|
+
| 宿主半是否加载 | ✅ `/sidecard-ask/api/state` 返回 `dsh-sidecard-ask v1.2.0`,`sideEngine=true`(provider `spawn,fork`)、`capabilities.parent` 正常 |
|
|
200
|
+
| 客户端半是否注册 | ✅ `shell.overlay` 有 `sidecard-ask`(order 45、active)、`conversation.input.right` 有 `sidecard-ask-session-probe`、`settings.section` 有设置页 |
|
|
201
|
+
| 依赖的槽位与标准 prop | ✅ `conversation.input.right` 仍是 list/session,`standardProps` 仍含 **`sessionId`** 与 **`inputActions`** |
|
|
202
|
+
| 依赖的客户端服务 | ✅ `sessions`(`retain`/`using`/`scope`)、`slots`、`locale`、`layout`、`theme` 全在;`sessions.fork`/`uiWorkspace.forkSession` 只是**新增**了可选 `onCreated`,不影响既有调用 |
|
|
203
|
+
| 端到端作答 | ✅ 真机 `start→delta×31→status→done`(1.36 s,`streamSource=frames`),只读工具白名单照常生效 |
|
|
204
|
+
|
|
205
|
+
**③ 由此发现并修掉的真实缺陷(1.2.1)**:运行中的 `sidebar.right.pane.tab` 清单里只有
|
|
206
|
+
`dsh-better-sidebar:sidecard-ask:card`,**没有我的原生 `sidecard-ask:card`**。原因是两个适配器用了**同一个 tab kind**:
|
|
207
|
+
better-sidebar 会把收到的每个 tab 描述符**镜像注册进同一个原生注册表**(`sidebarRightTabs.register`,band `extension`),
|
|
208
|
+
而该注册表对*同 band 同 kind 的二次注册直接抛错*(源码注释:*"Everything else colliding on a kind throws"*)——
|
|
209
|
+
后注册的那一方就此失败,而且**在界面上不可见**。修法:
|
|
210
|
+
|
|
211
|
+
1. better-sidebar 承载面改用独立类型 **`sidecard-ask:card:workbench`**,两端 kind 不再重叠;
|
|
212
|
+
2. `contract-test` **模拟该注册表的"重复 kind 抛错"规则**,此类冲突今后会直接让测试失败;
|
|
213
|
+
3. 设置页自检行改为**同时报告两个适配器**的状态(此前原生适配器的错误压根看不到)。
|
|
214
|
+
|
|
186
215
|
---
|
|
187
216
|
|
|
188
217
|
## 六、未知 DSH API:占位接口与替换方式
|
|
@@ -353,7 +382,7 @@ node test/smoke-test.mjs # 端到端:流式/截断/取消/持久化/失
|
|
|
353
382
|
```
|
|
354
383
|
|
|
355
384
|
三个脚本都以 `process.exitCode` 反映结果,失败会列出具体条目;测试会把 `DSH_HOME` 指向临时目录,不会污染真实配置。
|
|
356
|
-
当前规模:verify 53 项 + contract
|
|
385
|
+
当前规模:verify 53 项 + contract 118 项 + smoke 118 项 = **289 项全部通过**。
|
|
357
386
|
|
|
358
387
|
### 10.2 版本能力探测(§7 矩阵的来源)
|
|
359
388
|
|
|
@@ -471,5 +500,5 @@ npm deprecate "<旧包名>@*" "Renamed to <新包名> - <原因>" # 旧名
|
|
|
471
500
|
本仓库当前文件比运行中的宿主模块新(1.0.1 的「归档父会话不再一刀切 / 持久化 chunk 流式源 / 能力门控 / 路由降级」),
|
|
472
501
|
**重启后**这些改动才生效;`/state` 的 `version` 与 `capabilities.parent` 字段可以直接确认是否已加载新版。
|
|
473
502
|
6. **除 0.1.7-rc.2 外,其余版本只做了产物层验证**:见 §7.3——插件在 0.1.2-rc.1 … 0.1.6-alpha.2 上安装启动过**没有**得到验证,
|
|
474
|
-
验证到的是"这些版本缺哪些 API + 插件对每个缺失都有分支",分支本身由
|
|
503
|
+
验证到的是"这些版本缺哪些 API + 插件对每个缺失都有分支",分支本身由 289 项自测覆盖。
|
|
475
504
|
|
package/client.js
CHANGED
|
@@ -42,9 +42,27 @@ window.__ModuleLoader__.load({
|
|
|
42
42
|
settings: 'sidecard-ask-settings',
|
|
43
43
|
sessionProbe: 'sidecard-ask-session-probe',
|
|
44
44
|
}
|
|
45
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Tab kind served by the DSH native right rail (also its implementation id).
|
|
47
|
+
*/
|
|
46
48
|
const CARD_KIND = 'sidecard-ask:card'
|
|
47
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Tab type served by the dsh-better-sidebar plugin.
|
|
52
|
+
*
|
|
53
|
+
* It MUST differ from {@link CARD_KIND}: better-sidebar mirrors every tab
|
|
54
|
+
* descriptor it is given into the SAME native registry
|
|
55
|
+
* (`sidebarRightTabs.register`, id `dsh-better-sidebar:<id>`, band
|
|
56
|
+
* `extension`), and that registry THROWS when a kind already has a
|
|
57
|
+
* registration in the same band ("Everything else colliding on a kind
|
|
58
|
+
* throws"). Sharing one kind made the two adapters collide: whichever
|
|
59
|
+
* registered second failed — observed live on 0.2.0-rc.1, where the pane
|
|
60
|
+
* listed `dsh-better-sidebar:sidecard-ask:card` and no native
|
|
61
|
+
* `sidecard-ask:card` at all. `test/contract-test.mjs` now emulates that
|
|
62
|
+
* registry rule so the collision cannot come back.
|
|
63
|
+
*/
|
|
64
|
+
const CARD_KIND_BETTER = 'sidecard-ask:card:workbench'
|
|
65
|
+
|
|
48
66
|
/**
|
|
49
67
|
* Client-side mirror of the Host `DEFAULT_CONFIG`. The client needs values
|
|
50
68
|
* before `/state` answers (first paint) and when the Host is unreachable;
|
|
@@ -170,6 +188,7 @@ window.__ModuleLoader__.load({
|
|
|
170
188
|
diagSidecard: '侧边卡片插件(dsh-better-sidebar)',
|
|
171
189
|
diagFeatures: '项能力',
|
|
172
190
|
diagNoTabMeta: '版本过旧:没有 tabMeta 能力,已跳过它改用其它承载面',
|
|
191
|
+
diagNativeKind: 'kind',
|
|
173
192
|
toolGuardUnavailable: '该 provider 不支持工具白名单,本次作答继承了当前会话的工具',
|
|
174
193
|
toolGuardInherited: '按配置继承当前会话的工具',
|
|
175
194
|
diagUnreachable: '宿主接口不可达:{msg}',
|
|
@@ -272,6 +291,7 @@ window.__ModuleLoader__.load({
|
|
|
272
291
|
diagSidecard: 'Side-card plugin (dsh-better-sidebar)',
|
|
273
292
|
diagFeatures: 'capabilities',
|
|
274
293
|
diagNoTabMeta: 'too old: no tabMeta capability, skipped in favour of another surface',
|
|
294
|
+
diagNativeKind: 'kind',
|
|
275
295
|
toolGuardUnavailable: 'This provider supports no tool allow-list, so the answer inherited the session tools',
|
|
276
296
|
toolGuardInherited: 'Inherits the session tools, as configured',
|
|
277
297
|
diagUnreachable: 'Host API unreachable: {msg}',
|
|
@@ -889,20 +909,20 @@ window.__ModuleLoader__.load({
|
|
|
889
909
|
},
|
|
890
910
|
open(card) {
|
|
891
911
|
if (!this.available() || typeof this.service.openTab !== 'function') return false
|
|
892
|
-
const tabId = `${
|
|
912
|
+
const tabId = `${CARD_KIND_BETTER}:${card.id}`
|
|
893
913
|
// `meta` is the transport for the card id (feature `tabMeta`), and
|
|
894
914
|
// `dedupeKey` on our descriptor is what collapses repeat opens onto
|
|
895
915
|
// the same tab; both are part of the stable consumer contract
|
|
896
916
|
// (`lib/types/client/service.d.ts`, unchanged across 0.22.0 → 0.22.1).
|
|
897
917
|
this.service.openTab(
|
|
898
|
-
{ type:
|
|
918
|
+
{ type: CARD_KIND_BETTER, id: tabId, title: card.question.slice(0, 32), meta: { cardId: card.id } },
|
|
899
919
|
store.state.sessionId === null ? undefined : { sessionId: store.state.sessionId },
|
|
900
920
|
)
|
|
901
921
|
return true
|
|
902
922
|
},
|
|
903
923
|
close(card) {
|
|
904
924
|
if (!this.available() || typeof this.service.closeTab !== 'function') return false
|
|
905
|
-
this.service.closeTab(`${
|
|
925
|
+
this.service.closeTab(`${CARD_KIND_BETTER}:${card.id}`)
|
|
906
926
|
return true
|
|
907
927
|
},
|
|
908
928
|
},
|
|
@@ -1554,7 +1574,7 @@ window.__ModuleLoader__.load({
|
|
|
1554
1574
|
h('div', { key: 'slots' }, `${t('diagSlots')}: ${Object.entries(state.slots).map(([k, v]) => `${k}=${v}`).join(' · ')}`),
|
|
1555
1575
|
// The side-card plugin's own report: which version is loaded and
|
|
1556
1576
|
// whether it advertises the capability this adapter needs.
|
|
1557
|
-
h('div', { key: 'sidecard' }, `${t('diagSidecard')}: ${
|
|
1577
|
+
h('div', { key: 'sidecard' }, `${t('diagSidecard')}: ${describeSurfaces()}`),
|
|
1558
1578
|
h('div', { key: 'path' }, `${t('settingsTitle')} → ${diag.provenance?.persistedPath ?? ''}`),
|
|
1559
1579
|
])
|
|
1560
1580
|
: null)
|
|
@@ -1582,10 +1602,22 @@ window.__ModuleLoader__.load({
|
|
|
1582
1602
|
}
|
|
1583
1603
|
|
|
1584
1604
|
/**
|
|
1585
|
-
* One line describing how
|
|
1586
|
-
* settings page's capability check.
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1605
|
+
* One line describing how each optional side-card surface resolved, for the
|
|
1606
|
+
* settings page's capability check. Both adapters are reported, because a
|
|
1607
|
+
* failing NATIVE registration was previously invisible here (it only showed
|
|
1608
|
+
* up as a missing entry in the pane's own slot inventory).
|
|
1609
|
+
* @returns {string} human-readable state.
|
|
1610
|
+
*/
|
|
1611
|
+
function describeSurfaces() {
|
|
1612
|
+
const native = surfaces.native.available()
|
|
1613
|
+
? `${t('yes')} · ${t('diagNativeKind')}=${CARD_KIND}`
|
|
1614
|
+
: `${t('no')}${surfaces.native.error === null ? '' : `(${surfaces.native.error})`}`
|
|
1615
|
+
return `${t('surfaceNative')}: ${native} / ${t('surfaceBetter')}: ${describeSidecardAdapter()}`
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
/**
|
|
1619
|
+
* The optional side-card plugin's own report: which version is loaded and
|
|
1620
|
+
* whether it advertises the capability this adapter needs.
|
|
1589
1621
|
* @returns {string} human-readable state.
|
|
1590
1622
|
*/
|
|
1591
1623
|
function describeSidecardAdapter() {
|
|
@@ -2245,7 +2277,11 @@ window.__ModuleLoader__.load({
|
|
|
2245
2277
|
return
|
|
2246
2278
|
}
|
|
2247
2279
|
const off = service.registerTab({
|
|
2248
|
-
|
|
2280
|
+
// A DIFFERENT type from the native rail's: better-sidebar mirrors
|
|
2281
|
+
// this descriptor into `sidebarRightTabs` as an `extension`-band
|
|
2282
|
+
// registration, and a second registration of the same kind in
|
|
2283
|
+
// that band throws (see CARD_KIND_BETTER).
|
|
2284
|
+
id: CARD_KIND_BETTER,
|
|
2249
2285
|
title: () => t('answerTitle'),
|
|
2250
2286
|
description: () => t('settingsDesc'),
|
|
2251
2287
|
order: 120,
|
|
@@ -2337,13 +2373,14 @@ window.__ModuleLoader__.load({
|
|
|
2337
2373
|
* `window` and exercises these without a browser.
|
|
2338
2374
|
*/
|
|
2339
2375
|
api: Object.freeze({
|
|
2340
|
-
version: '1.2.
|
|
2376
|
+
version: '1.2.1',
|
|
2341
2377
|
/** Read-only state accessor for diagnostics and the test harness. */
|
|
2342
2378
|
snapshot: () => store.state,
|
|
2343
2379
|
pure: Object.freeze({
|
|
2344
2380
|
CLIENT_DEFAULTS,
|
|
2345
2381
|
IDS,
|
|
2346
2382
|
CARD_KIND,
|
|
2383
|
+
CARD_KIND_BETTER,
|
|
2347
2384
|
parseSseBlock,
|
|
2348
2385
|
truncateSelection,
|
|
2349
2386
|
parseShortcut,
|
package/index.js
CHANGED
|
@@ -42,7 +42,7 @@ export const name = 'dsh-sidecard-ask'
|
|
|
42
42
|
export const inject = ['webServer']
|
|
43
43
|
|
|
44
44
|
/** Version of this plugin (kept in step with package.json by test/verify.mjs). */
|
|
45
|
-
export const PLUGIN_VERSION = '1.2.
|
|
45
|
+
export const PLUGIN_VERSION = '1.2.1'
|
|
46
46
|
|
|
47
47
|
/** Route prefix of the plugin's own API. */
|
|
48
48
|
export const ROUTE_PREFIX = '/sidecard-ask/api'
|