dsh-quick-toc 0.7.6 → 0.7.7

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.en.md CHANGED
@@ -2,20 +2,23 @@
2
2
 
3
3
  All notable changes to **dsh-quick-toc** are documented here. Chinese version: [CHANGELOG.md](CHANGELOG.md).
4
4
 
5
+ ## [0.7.7] - 2026-09-27
6
+
7
+ ### Fixed
8
+ - **On the 0.1.7 line the settings card had disappeared**: 0.1.7 removed the whole Settings → Plugins → Plugin configuration page (that line has only the sidebar's Plugins page), and the card was registered on the bundle page alone, so the Plugins page's Official group had nothing to click. The plugin now has its own entry there (`plugins.item`, titled after the panel), and opening it shows the card already expanded; the card on the bundle page is unchanged.
9
+ - **On a long session the curtain's drop could be over before it was ever seen**: opening the curtain re-lays out the whole list at the curtain's width, and on a long session that commit is a long task in itself, so an animation clock started inside it had already run its 0.46s before the first frame painted. The animation is now re-armed once the open state is in the DOM (paying that layout first, then starting the clock).
10
+
5
11
  ## [0.7.6] - 2026-09-24
6
12
 
7
13
  ### Fixed
8
- - **On the 0.1.7 line the settings card's writes only reached the browser**: on a profile whose entry id differs from the first candidate name (the real profile names the entry `dsh-quick-toc` while the first candidate is `quick-toc`), the `configForms.describe()` view was still EMPTY at the moment the plugin applied, so the code that looks up the settings namespace guessed a candidate name the host does not serve and bound a form that never became ready. The card still opened and still took clicks, but every write fell back to this browser's mirror while the settings document (the profile's `cordis.patch.yml` on 0.1.7) stayed untouched — and the console stayed silent. Now an empty view means "the document has not arrived", not "the host serves nothing": the plugin no longer guesses, it subscribes to `describe()` and binds once the document is there, and only then registers the card; a host that never serves a document still gets the card after 4 seconds, reading and writing the browser mirror (the documented fallback layer). Verified on both lines: on 0.1.7-rc.1 the profile's `cordis.patch.yml` gained `lang: en`, on 0.1.5-rc.3 `settings.yaml`'s `dsh-quick-toc:` became `{ handle: 0.6, autoLoad: false, lang: en }`.
14
+ - **On the 0.1.7 line the settings card's writes only reached the browser**: before the host's settings document had arrived (on a profile whose entry id differs from the candidate names) the plugin bound a form that does not exist — the card opened and took clicks, but every write fell back to the browser mirror with the settings document untouched and no console error. It now waits for the document, and a host that never serves one still gets the card after 4 seconds (the browser mirror, its documented fallback layer).
9
15
 
10
16
  ## [0.7.5] - 2026-09-24
11
17
 
12
18
  ### Changed
13
- - **DSH 0.1.7-rc.1 is supported**: it is the 0.1.7 interface set moved onto the rc channel (`settingsScope`, `settings.plugin.item`, `sessions.open` and `installSection` are all gone; it shares `configForms`, `plugins.bundle.config`, `uiWorkspace` and `settings.configure` with 0.1.7-alpha.x), and no code change was needed. Measured in an isolated environment: the host booted with no error, and the panel, the curtain, Esc, the dock switch and the collapse were all exercised on a real session with no browser error. `dsh.compatibility.dshReleases` records it.
19
+ - **DSH 0.1.7-rc.1 is supported**: it is the 0.1.7 interface set moved onto the rc channel and shares its settings service and configuration-card slots with 0.1.7-alpha.x, so no code change was needed; it was exercised point by point in an isolated environment (host boot, panel, curtain, Esc, dock switch and collapse).
14
20
  - **The declared compatibility floor moved to 0.1.5-rc.3**: the older 0.1.5-rc.1 and 0.1.5-rc.2 are no longer declared (`engines.dsh` and both peer ranges follow), and the README's compatibility table matches.
15
- - **The loader row id shipped in this package now equals the settings namespace** (`quick-toc` to `dsh-quick-toc`): from DSH 0.1.7 on, the settings document is a set of forms addressed by **profile entry id**, and the old `settings.yaml` is renamed to an import source whose sections are matched to entries of the same name; an id that does not match the namespace the plugin registered leaves an existing installation's saved preferences behind in that import file (the plugin then reads empty values). With matching names this package can live in the profile's `dsh.profile.bundles` (0.1.7's plugin manager only offers a configuration page for packages listed there), and on 0.1.5-rc.3 the id is only a loader key, so the same value is harmless. **Being in `bundles` and a profile patch `insert:` are mutually exclusive**: the same entry id twice makes the host refuse to boot.
16
-
17
- ### Fixed
18
- - **A binding fallback for the settings scope**: the host's settings document can still be loading when a plugin applies (0.1.7-rc.1 answers `status: "loading"` for that form), and the code used to accept only a one-shot "ready" snapshot; it now falls back to the first candidate form that EXISTS and lets the subscription take over once the document arrives.
21
+ - **The loader row id now equals the settings namespace** (`quick-toc` to `dsh-quick-toc`): from DSH 0.1.7 on, settings are addressed by profile entry id, and an id that does not match the namespace the plugin registered leaves an existing installation's saved preferences unreadable in the import file. With matching names this package can also live in the profile's `dsh.profile.bundles` (0.1.7's plugin manager only offers a configuration page for packages listed there), but **never together with a profile-patch `insert:` of the same name** (that makes the host refuse to boot).
19
22
 
20
23
  ## [0.7.4] - 2026-09-23
21
24
 
package/CHANGELOG.md CHANGED
@@ -2,20 +2,23 @@
2
2
 
3
3
  **dsh-quick-toc** 的重要变更都记录在这里。英文版见 [CHANGELOG.en.md](CHANGELOG.en.md)。
4
4
 
5
+ ## [0.7.7] - 2026-09-27
6
+
7
+ ### 修复
8
+ - **0.1.7 线上设置卡片不见了**:0.1.7 把「设置 → 插件 → 插件配置」整块从宿主里去掉(那条线上只有侧边栏「插件」页),卡片原本只挂在 bundle 页上,读者在插件页的「官方」分组里找不到它。现在插件在那里有自己的条目(`plugins.item`,标题取面板名),点进去卡片直接展开;bundle 页上的卡片照旧。
9
+ - **长会话里幕布的展开动画可能整段跑完才被看到**:打开幕布会让列表按幕布的宽度整体重排,这一次提交本身就是一段长任务,动画时钟若从这次提交里开始计时,0.46 秒会在首帧画出来之前走完。现在动画在打开状态写入 DOM 之后重新点火一次(先付掉这次布局,再开始计时)。
10
+
5
11
  ## [0.7.6] - 2026-09-24
6
12
 
7
13
  ### 修复
8
- - **0.1.7 线上设置卡片的写入只落在浏览器里**:入口 id 与候选名不一致的 profile 上(例如真实 profile 把入口命名为 `dsh-quick-toc`,而候选表第一个是 `quick-toc`),插件加载的那一刻 `configForms.describe()` 的视图**还没到**(实测返回空表),于是找设置命名空间的那段代码按候选名猜了一个**宿主并不服务**的名字,绑上一个永远不就绪的表单——卡片照常能开能点,但所有写入都退回本浏览器的镜像,设置文档(0.1.7 上是 profile 的 `cordis.patch.yml`)永远不动,而且控制台没有任何报错。现在:视图为空时**不再猜名字**(空 ≠ 宿主不服务),改为订阅 `describe()` 并在文档到位后绑定,绑定成功才注册卡片;宿主始终不给文档时 4 秒后仍注册卡片、退回本地镜像这个既有的降级层。0.1.7-rc.1 与 0.1.5-rc.3 两条线都实测确认写入落盘(前者 `cordis.patch.yml` 新增 `lang: en`,后者 `settings.yaml` 的 `dsh-quick-toc:` 变成 `{ handle: 0.6, autoLoad: false, lang: en }`)。
14
+ - **0.1.7 线上配置卡片的写入只落在浏览器里**:宿主设置文档还没到位时(入口 id 与候选名不一致的 profile 上)插件绑到了一个并不存在的表单——卡片能开能点,但写入都退回本地镜像、设置文档不动,控制台也没有报错。现在等文档到位再绑定,宿主始终不给文档时 4 秒后仍提供卡片(退回本地镜像这个既有降级层)。
9
15
 
10
16
  ## [0.7.5] - 2026-09-24
11
17
 
12
18
  ### 变更
13
- - **支持 DSH 0.1.7-rc.1**:它是 0.1.7 那套接口搬到 rc 通道(`settingsScope`、`settings.plugin.item`、`sessions.open`、`installSection` 都已不存在,与 0.1.7-alpha.x 共用 `configForms`、`plugins.bundle.config`、`uiWorkspace`、`settings.configure`),代码不需要改动。隔离环境实测:宿主启动无报错,面板、幕布、Esc、停靠切换与收起在一段真实会话上逐项通过,浏览器无报错。`dsh.compatibility.dshReleases` 随之增加该版本。
19
+ - **支持 DSH 0.1.7-rc.1**:它是 0.1.7 那套接口搬到 rc 通道,与 0.1.7-alpha.x 共用同一套设置服务与配置卡片槽位,代码无需改动;隔离环境里逐项实测通过(宿主启动、面板、幕布、Esc、停靠切换与收起)。
14
20
  - **声明的兼容下限收到 0.1.5-rc.3**:更早的 0.1.5-rc.1、0.1.5-rc.2 不再声明(`engines.dsh` 与两条 peer 区间同步收紧),README 兼容表跟上。
15
- - **插件自带的 loader 行 id 与设置命名空间对齐**(`quick-toc` → `dsh-quick-toc`):DSH 0.1.7 起设置文档改为按**入口 id** 寻址的表单,旧 `settings.yaml` 被改名为导入源、按同名把旧配置映射到入口;id 与插件注册的命名空间不一致时,已保存的偏好会被留在导入文件里(插件读到空值)。同名之后本插件可以放进 profile 的 `dsh.profile.bundles`(0.1.7 的插件管理页只在 bundles 里的包上给出配置页),0.1.5-rc.3 上 id 只是加载器键、同样无害。**装进 `bundles` 与 profile patch 的 `insert:` 不能同时存在**(同名 entry id 会让宿主直接启动失败)。
16
-
17
- ### 修复
18
- - **设置作用域的绑定兜底**:宿主设置文档在插件加载时可能仍在载入(0.1.7-rc.1 实测该表单的 `status` 为 `loading`),原先只认一次「就绪」快照;现在会退到第一个存在的候选表单,由订阅在文档到位后接续。
21
+ - **加载行 id 与设置命名空间对齐**(`quick-toc` → `dsh-quick-toc`):DSH 0.1.7 起设置按入口 id 寻址,名字与插件注册的命名空间不一致时,已保存的偏好会留在导入文件里读不到。同名之后本插件也可以放进 profile 的 `dsh.profile.bundles`(0.1.7 的插件管理页只在 bundles 里的包上给出配置页),但**不能与 profile patch 里的同名 `insert:` 并存**(会让宿主启动失败)。
19
22
 
20
23
  ## [0.7.4] - 2026-09-23
21
24
 
package/README.en.md CHANGED
@@ -42,7 +42,7 @@ A conversation TOC plugin for [DeepSeek Harness](https://github.com/deepseek-ai/
42
42
 
43
43
  | Plugin | Supported DSH |
44
44
  | --- | --- |
45
- | **0.7.x** (latest, 0.7.6) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1 |
45
+ | **0.7.x** (latest, 0.7.7) | 0.1.5-rc.3, 0.1.7-alpha.1, 0.1.7-alpha.2, 0.1.7-rc.1 |
46
46
  | 0.6.x (0.6.3) | 0.1.5-rc.1, 0.1.5-rc.2 |
47
47
  | 0.5.x (0.5.1) | 0.1.5-rc.1, 0.1.5-rc.2 |
48
48
  | 0.4.x (0.4.1) | 0.1.5-rc.1, 0.1.5-rc.2 |
@@ -115,7 +115,7 @@ A missing `turnOutline` means the host has no such projection, and the staged `j
115
115
  - Interface text lives in one string table at the top of `lib/client.js` (`DICTS`, one Chinese and one English copy) and the language setting picks between them: on `follow the host` the host's translate function (`ctx.locale.bind("dsh-quick-toc")`, fed by the same `DICTS` tables) is asked first and the built-in table is only the fallback. The two tables must stay key-aligned; the only Chinese-only entry is `time.beforeYesterday` (English carries the date for anything older than yesterday), while `time.yesterday` exists in both (`yesterday`).
116
116
  - Preferences sit in two layers behind one module-level store: the Host settings document (language, docked edge, levels, scale, handle position, remembered reading position, fuzzy, hover and diagnostic; authoritative on a loopback page) and `localStorage` (the mirror, plus the real storage for top offset / width / height, which describe this screen and are saved per browser). **The host layer itself is one of two dialects, whichever the running host offers**: on 0.1.5-rc.3 it is `ctx.settingsScope.bind({ namespace: "dsh-quick-toc" })` (addressed by namespace), while on either 0.1.7 line (alpha and rc) it is `ctx.configForms.get(<profile entry id>)` (addressed by profile entry id, the client recognising its own entry by the schema the host serves). Both expose the same methods over the same snapshot fields, so the store stays one. Writes are routed per field: host fields go through `scope.mutate` (folded in locally, reconciled when the host answers), everything else goes to `localStorage`; a value that IS the field's default is written by removing that entry from the user layer instead (the same thing as "not customized"). On a non-loopback page DSH marks settings read-only, so those nine preferences fall back to the mirror and behave exactly as in 0.5.x; values left by a 0.5.x install are imported into the host layer once, the first time it answers (and only while the user layer is empty). Once the host has answered, that layer is authoritative — which is why a local key such as `localStorage['dsh-quick-toc.debug']` no longer takes effect on a loopback page: use the switch in the card.
117
117
  - The curtain and the docked panel **share one list DOM**: the curtain only moves the panel itself into a full-width container that drops from the lower edge of the tab strip (in curtain mode the panel swaps to a different geometry — relative positioning, 100% width and height, no panel scale), and that container stays mounted as a zero-size pass-through while the curtain is up, so opening or closing it never rebuilds the list or loses the scroll position. Cross-session search goes through the client `ctx.get("sessions")` service's `search(query, signal)` (the host's session full-text index, at most 20 hits per search); each session's reading position lives in this browser (`dsh-quick-toc.readPos.v1`, valid for half an hour).
118
- - The configuration card is registered into one of two slots, whichever the running host offers: on 0.1.5-rc.3 it is `settings.plugin.item` (keyed on the plugin's namespace; the slot is dispatched only for namespaces the Host actually serves, so a deployment without the host half simply shows no card and the panel is unaffected), and on either 0.1.7 line (alpha and rc) it is `plugins.bundle.config` (keyed on the npm package name, so the card appears on that bundle's page in the sidebar's Plugins list). Both registrations happen only once a settings scope has bound, and the card and the panel share the store above, which is what makes the two live in both directions.
118
+ - The configuration card is registered into all three seats at once, and which one it lands in is the running host's business: on 0.1.5-rc.3 it is `settings.plugin.item` (keyed on the plugin's namespace; the slot is dispatched only for namespaces the Host actually serves, so a deployment without the host half simply shows no card and the panel is unaffected); on either 0.1.7 line (alpha and rc) it is two places on the sidebar's Plugins page — the plugin's own entry in the Official group (`plugins.item`, `id` `quick-toc`, `label` from "Conversation Outline", `order` 50) and the configuration area of its bundle page (`plugins.bundle.config`, keyed on the npm package name). Both 0.1.7 seats hand the card a `view`, so it starts expanded there (opening the entry or the bundle page IS the expansion gesture); the rc line's configuration cell passes no props at all and keeps the collapsed list shape. Every registration happens only once a settings scope has bound, and the card and the panel share the store above, which is what makes the two live in both directions.
119
119
  - Changes to `lib/client.js` show up after a page refresh (client modules are served under a content hash and DSH's client HMR pushes reloads); changes to `lib/index.js` (the host half) need a DSH restart
120
120
 
121
121
  ## License
package/README.md CHANGED
@@ -42,7 +42,7 @@
42
42
 
43
43
  | 插件版本 | 支持的 DSH 版本 |
44
44
  | --- | --- |
45
- | **0.7.x**(最新,0.7.6) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1 |
45
+ | **0.7.x**(最新,0.7.7) | 0.1.5-rc.3、0.1.7-alpha.1、0.1.7-alpha.2、0.1.7-rc.1 |
46
46
  | 0.6.x(0.6.3) | 0.1.5-rc.1、0.1.5-rc.2 |
47
47
  | 0.5.x(0.5.1) | 0.1.5-rc.1、0.1.5-rc.2 |
48
48
  | 0.4.x(0.4.1) | 0.1.5-rc.1、0.1.5-rc.2 |
@@ -115,7 +115,7 @@ dsh plugin --profile web add <插件目录路径>
115
115
  - 界面文字来自 `lib/client.js` 顶部的一张字符串表(`DICTS`,中英各一份),语言设置决定用哪一份:`跟随宿主` 时优先问宿主的翻译函数(`ctx.locale.bind("dsh-quick-toc")`,注册的表就来自 `DICTS`),拿不到才回退到内置表。中英两份表的键必须对齐(仅 `time.beforeYesterday`(前天)是中文独有——英文对更早的时间直接用日期;`time.yesterday` 两语言都有,英文作 `yesterday`)。
116
116
  - 偏好存储分两层,由一个模块级 store 统一读出:宿主设置文档(语言/停靠边/层级/缩放/把手位置/记住阅读位置/模糊/悬停/诊断九项,回环页面上是权威层)与 `localStorage`(镜像 + 顶边距/宽度/高度三项的正式存储——它们描述"这一块屏幕",按浏览器保存)。**宿主那一层按运行中的宿主二选一**:0.1.5-rc.3 上是 `ctx.settingsScope.bind({ namespace: "dsh-quick-toc" })`(按命名空间寻址),0.1.7 两条线(alpha 与 rc)上改成 `ctx.configForms.get(<profile entry id>)`(按 profile 条目 id 寻址,客户端按宿主实际服务的 schema 认出自己那一条);两者暴露的方法与快照字段相同,所以 store 只有一套。写入按字段路由:宿主字段走 `scope.mutate`(本地同步折叠、宿主应答后对账),其余写 `localStorage`;写入的值若正好是该字段的默认值,则改为把用户层里的这一项删掉(等同于"未自定义")。非回环页面 DSH 将设置标记为只读,此时这九项偏好退回本地镜像,行为与 0.5.x 一致;0.5.x 留下的本地值会在宿主层首次应答时导入一次(仅当用户层为空)。宿主应答之后宿主层就是权威层,因此 `localStorage['dsh-quick-toc.debug']` 这类本地键在回环页面上不再生效——诊断开关请用卡片里那一条。
117
117
  - 幕布与停靠面板**共用同一份列表 DOM**:幕布只是把面板本体搬进一个从标签条下沿落下的整宽容器(面板在幕布态换一套几何:相对定位、宽高 100%、不套用面板缩放),容器本身常驻挂载、收起时是一个 0×0 的直通盒,所以开关幕布不会重建列表、也不会丢掉滚动位置。跨会话检索走客户端 `ctx.get("sessions")` 的 `search(query, signal)`(走宿主的会话全文索引,一次最多 20 条);每个会话的阅读位置存在浏览器本地(`dsh-quick-toc.readPos.v1`,半小时内有效)。
118
- - 插件配置卡片也按宿主二选一注册:0.1.5-rc.3 上挂 `settings.plugin.item` 槽(`key` 为插件命名空间,该槽按宿主实际提供的命名空间派发,宿主半未加载时卡片自然不出现,面板不受影响);0.1.7 两条线(alpha 与 rc)上改挂 `plugins.bundle.config` 槽(`key` 为 npm 包名,卡片出现在侧边栏「插件」页该 bundle 的页面上)。两条注册都只在设置作用域绑定成功后才做,卡片与面板共享上面那个 store,因此两边实时互通。
118
+ - 插件配置卡片按宿主实际提供的槽位注册,三处一起挂、装上哪一处由宿主决定:0.1.5-rc.3 上是 `settings.plugin.item`(`key` 为插件命名空间,该槽按宿主实际服务的命名空间派发,宿主半未加载时卡片自然不出现,面板不受影响);0.1.7 两条线(alpha 与 rc)上是侧边栏「插件」页的两处——「官方」分组里插件自己的条目(`plugins.item`,`id` 为 `quick-toc`,`label` 取「对话大纲」,`order` 50)与该 bundle 页面上的配置区(`plugins.bundle.config`,`key` 为 npm 包名)。0.1.7 的插件页渲染这两处时都会带上 `view`,卡片因此默认展开(点进条目或 bundle 页本身就是展开动作);rc 线的配置单元不带任何 props,卡片保持收拢的列表形态。所有注册都只在设置作用域绑定成功后才做,卡片与面板共享上面那个 store,因此两边实时互通。
119
119
  - 修改 `lib/client.js` 后刷新页面即可看到变化(客户端模块按内容哈希发版,DSH 的客户端 HMR 也会推送重载);改 `lib/index.js`(宿主半)需重启 DSH
120
120
 
121
121
  ## License
package/lib/client.js CHANGED
@@ -2174,6 +2174,21 @@ window.__ModuleLoader__.load({
2174
2174
  setSheetOpen(true);
2175
2175
  }
2176
2176
  };
2177
+ // The drop is armed by the class the open commit writes, so its clock starts inside
2178
+ // that commit. On a long outline the commit is a long task of its own (the whole list
2179
+ // re-laid out at the curtain's width), and an animation whose 0.46s runs while its own
2180
+ // first frame is still being laid out is over before anything is painted — the failure
2181
+ // 0.7.4 fixed for the host-driven load, and the same shape of failure when the cost is
2182
+ // ours. Re-arming it here, with the open state already in the DOM and before the
2183
+ // browser paints it, puts the layout and the animation on the same frame.
2184
+ react.useLayoutEffect(function () {
2185
+ if (!sheetOpen) return;
2186
+ var node = sheetRef.current;
2187
+ if (!node || !node.style) return;
2188
+ node.style.animation = "none";
2189
+ void node.offsetWidth; // pay the commit's layout HERE, before the drop starts
2190
+ node.style.animation = "";
2191
+ }, [sheetOpen]);
2177
2192
  // "return" only needs to exist for one painted frame: the panel renders at
2178
2193
  // its collapsed spot, and releasing it lets the left/clip transition carry
2179
2194
  // it back open. The tuck must NOT be released here — it is held until the
@@ -6963,13 +6978,17 @@ window.__ModuleLoader__.load({
6963
6978
  // live in both directions. The chrome mirrors the section's own card (radii,
6964
6979
  // borders, spacing, tokens) because a plugin bundle cannot import the section's
6965
6980
  // CSS module.
6966
- function TocSettingsCard() {
6981
+ function TocSettingsCard(props) {
6967
6982
  var prefs = usePrefs();
6968
6983
  setLanguage(prefs.lang, hostLanguage());
6969
6984
  var snap = prefsStore.host();
6970
6985
  var writable = !!snap && snap.writable === true;
6971
6986
  var user = snap && snap.user && typeof snap.user === "object" ? snap.user : {};
6972
- var openState = react.useState(false);
6987
+ // Start open where the seat already opened the section: the 0.1.7 plugin pages hand the
6988
+ // card a `view` (the reader clicked into the entry or the bundle page to get here), so
6989
+ // making them click the card's own header after that was a second expansion for nothing.
6990
+ // The rc line's configuration cell passes no props and keeps the collapsed list shape.
6991
+ var openState = react.useState(!!(props && (props.defaultOpen === true || props.view === "page")));
6973
6992
  var open = openState[0];
6974
6993
  var setOpen = openState[1];
6975
6994
  var commit = function (patch) { prefsStore.set(patch); };
@@ -7184,6 +7203,16 @@ window.__ModuleLoader__.load({
7184
7203
  });
7185
7204
  }
7186
7205
 
7206
+ // The 0.1.7 Plugins page's own entry for this plugin (`plugins.item`). That seat asks one
7207
+ // component for two views: a one-line `summary` for the entry in its Official group, and
7208
+ // the `page` body once the entry is opened. The summary answers with the card's own
7209
+ // description and every other view is the card itself, already open — the click that
7210
+ // opened the entry IS the expansion gesture.
7211
+ function TocCardPage(props) {
7212
+ if (props && props.view === "summary") return T("settings.desc");
7213
+ return react_jsx_runtime.jsx(TocSettingsCard, { defaultOpen: true });
7214
+ }
7215
+
7187
7216
  // Declared client services only. `slots` and `locale` exist on every supported line;
7188
7217
  // the settings service is looked up with `ctx.get` instead (see `pickSettingsScope`),
7189
7218
  // because declaring a name a host does not provide parks the whole package.
@@ -7396,6 +7425,21 @@ window.__ModuleLoader__.load({
7396
7425
  locale: "dsh-quick-toc"
7397
7426
  }, TocSettingsCard);
7398
7427
  });
7428
+ // 0.1.7's Plugins page lists one entry per plugin in its Official group
7429
+ // (`plugins.item`), which is where the reader looks for our settings there — the
7430
+ // earlier line's keyed configuration cell (`settings.plugin.item`) no longer exists
7431
+ // on that host, so without this seat the card had nowhere to appear. `id` names the
7432
+ // entry, `label` is its line in the group, and `order` places it after the host's
7433
+ // own pages (shell 10 / agent loop 20 / subagent 30 / web search 40).
7434
+ ctx.slots.inject("plugins.item", function () {
7435
+ return ctx.slots.register({
7436
+ name: "plugins.item",
7437
+ id: "quick-toc",
7438
+ order: 50,
7439
+ label: function () { return T("panel.title"); },
7440
+ locale: "dsh-quick-toc"
7441
+ }, TocCardPage);
7442
+ });
7399
7443
  ctx.slots.inject("settings.plugin.item", function () {
7400
7444
  return ctx.slots.register({
7401
7445
  name: "settings.plugin.item",
@@ -7444,13 +7488,14 @@ window.__ModuleLoader__.load({
7444
7488
  // The plugin-configuration card, in whichever seat the running host offers:
7445
7489
  // * up to rc.2 it is a keyed `settings.plugin.item` cell under
7446
7490
  // Settings → Plugins → Plugin configuration, keyed by the settings namespace;
7447
- // * on the alpha the plugin's own page in the sidebar's Plugins list carries it,
7448
- // as the bundle's configuration keyed by the npm package name
7449
- // (`plugins.bundle.config`). A row-level cell (`plugins.row.config`, keyed
7450
- // `<package>#<row id>`) exists too, but a registration there did not reach that
7451
- // page in 0.1.7-alpha.1 while the bundle cell did — and these preferences are the
7452
- // plugin's, not one row's, so the bundle page is the right seat anyway.
7453
- // Registering into a slot a given host never declares is inert, so both are
7491
+ // * on 0.1.7 the Plugins page's Official group lists one entry per plugin
7492
+ // (`plugins.item`) and the bundle page carries the bundle's own configuration
7493
+ // (`plugins.bundle.config`, keyed by the npm package name). A row-level cell
7494
+ // (`plugins.row.config`, keyed `<package>#<row id>`) exists too, but a
7495
+ // registration there did not reach that page in 0.1.7-alpha.1 while the bundle
7496
+ // cell did — and these preferences are the plugin's, not one row's, so the
7497
+ // bundle page is the right seat for them.
7498
+ // Registering into a slot a given host never declares is inert, so all three are
7454
7499
  // offered together, once the host layer bound (or the fallback timer fired).
7455
7500
  }
7456
7501
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-quick-toc",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "Conversation TOC for DeepSeek Harness (DSH): a whole-session, turn-grouped Markdown outline with hover previews, a level filter, a full-width curtain, jump-to-end buttons, title/full-text/cross-session search and a Chinese/English interface.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",