dsh-quick-actions 0.2.0-rc.2 → 0.2.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -28,7 +28,7 @@ This release has **no insert action** (insert at the selection, keep the editing
28
28
  | DSH UI primitives (browser side) | `>=0.1.7-alpha.2`, also supplied by the module table |
29
29
  | Platform | `web` profile only |
30
30
 
31
- Nothing is capability-detected at install or at runtime, so there is no feature tiering that varies with the DSH version: either the whole plugin installs and runs, or it does not.
31
+ The send and Settings contracts have no legacy compatibility layer. **`0.2.0-rc.3`** also supports the optional `conversation.composer.footer`: a locally patched core places the bar below the statistics row, with the action group centered within the input's width; an unpatched core keeps the existing placement. Official `0.1.7-rc.2` does not include this slot, and installing the plugin alone does not add it.
32
32
 
33
33
  The floor is the DSH release whose Settings form this plugin reads. **Do not run it against anything older**: `0.1.7-alpha.1` rewrote Settings — plugins no longer register namespaces of their own, and user data became the plugin's own Config, written into the profile. This release reads and writes the new model only, and on the `0.1.5` and `0.1.6` lines its Client never starts. For those lines, install this plugin's `0.1.0`.
34
34
 
@@ -45,7 +45,7 @@ No upper bound is declared, but **that is not a promise of forward compatibility
45
45
  dsh plugin --profile web add dsh-quick-actions@next
46
46
  ```
47
47
 
48
- **Keep the `@next`.** DSH's own npm `latest` still points at the `0.1.5` line, so this release is published under the `next` dist-tag. Without the tag you get `0.1.0` from `latest`, which supports only the `0.1.5` and `0.1.6` lines and fails to activate on `0.1.7`. Once DSH moves `0.1.7` to `latest`, this plugin moves back to `latest` with it.
48
+ **Keep the `@next`.** The plugin's `0.2.0` line remains a prerelease and uses the `next` dist-tag. Without the tag you get the plugin's `0.1.0` from `latest`, which supports only DSH `0.1.5` and `0.1.6` and fails to activate on `0.1.7`. DSH's own `latest` is now `0.1.7-rc.2`, but that does not automatically change this plugin's release channel. This release has not been verified against the DSH `0.2.0` prerelease line.
49
49
 
50
50
  Then restart the web profile. One package is the whole thing: it carries `dsh.bundle.patch`, which inserts its Host half into the profile, while its `dsh.client` declaration makes the web app load the browser half.
51
51
 
@@ -54,7 +54,7 @@ Then restart the web profile. One package is the whole thing: it carries `dsh.bu
54
54
  ```sh
55
55
  mkdir -p /tmp/quick-actions
56
56
  pnpm --filter dsh-quick-actions pack --pack-destination /tmp/quick-actions
57
- dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.2.0-rc.2.tgz
57
+ dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.2.0-rc.3.tgz
58
58
  ```
59
59
 
60
60
  The `--filter` form works from anywhere in the repository; from the package directory itself, `pnpm pack --pack-destination /tmp/quick-actions` is the same thing.
@@ -134,7 +134,7 @@ Layout is a global persisted setting, switched in the management panel:
134
134
  | Value | Name | Where |
135
135
  |---|---|---|
136
136
  | `ribbon` (default) | Action ribbon | One row above the input, matching its width |
137
- | `bar` | Action bar | One row under the input, beside DSH's own usage info, as wide as its content and at most as wide as the input card; whatever does not fit folds into "more" |
137
+ | `bar` | Action bar | With the footer core patch: a separate row below statistics, with controls centered within the input's width. Without it: the existing placement beside usage info. Actions that do not fit fold into "more" |
138
138
  | `launcher` | Single launcher | One entry button opening a searchable panel |
139
139
 
140
140
  `bar` and `launcher` share the same searchable panel, and the search matches labels and texts only. The management panel is where you reorder, hide, restore and clone presets, create, edit, enable and delete custom actions, and switch layout.
package/README.md CHANGED
@@ -28,7 +28,7 @@
28
28
  | DSH UI primitives(浏览器侧) | `>=0.1.7-alpha.2`,同样由模块表提供 |
29
29
  | 平台 | 只支持 `web` profile |
30
30
 
31
- 安装与运行都不检测 DSH 能力,因此不存在随版本变化的功能分档:要么整个插件能装能跑,要么装不上。
31
+ 发送与 Settings 契约不做旧版兼容。**`0.2.0-rc.3`** 另支持可选的 `conversation.composer.footer`:带本地核心补丁的 DSH 将 bar 放到统计行下方、动作组水平居中;未打补丁的核心保留原位置。该挂载点不是官方 `0.1.7-rc.2` 自带能力,也不会仅因安装插件而出现。
32
32
 
33
33
  下界取的是本插件读取其 Settings 表单的那个 DSH 版本。**不要在更低版本上使用**:`0.1.7-alpha.1` 重写了 Settings——插件不再自己注册命名空间,用户数据改为插件自己的 Config、写进 profile。本版只按新模型读写,在 `0.1.5`、`0.1.6` 线上 Client 根本不会启动。要在那两条线上用,请装本插件的 `0.1.0`。
34
34
 
@@ -45,7 +45,7 @@
45
45
  dsh plugin --profile web add dsh-quick-actions@next
46
46
  ```
47
47
 
48
- **`@next` 不能省。** DSH 自己的 npm `latest` 还停在 `0.1.5` 线,所以本版发在 `next` dist-tag 上;不带 tag 装到的是 `latest` 上的 `0.1.0`,它只支持 `0.1.5`、`0.1.6` 线,在 `0.1.7` 上激活失败。等 DSH 把 `0.1.7` 推上 `latest`,本插件跟着回到 `latest`。
48
+ **`@next` 不能省。** 插件 `0.2.0` 仍处于预发布阶段,本版使用 `next` dist-tag;不带 tag 装到的是插件 `latest` 上的 `0.1.0`,它只支持 DSH `0.1.5`、`0.1.6` 线,在 `0.1.7` 上激活失败。DSH 的 `latest` 已是 `0.1.7-rc.2`,但这不会自动改变插件的发布通道。本版尚未验证 DSH `0.2.0` 预发布线。
49
49
 
50
50
  然后重启 web profile。一个包就是全部:它自带 `dsh.bundle.patch` 把自己的 Host 半边插进 profile,`dsh.client` 声明让 web 端加载浏览器半边。
51
51
 
@@ -54,7 +54,7 @@ dsh plugin --profile web add dsh-quick-actions@next
54
54
  ```sh
55
55
  mkdir -p /tmp/quick-actions
56
56
  pnpm --filter dsh-quick-actions pack --pack-destination /tmp/quick-actions
57
- dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.2.0-rc.2.tgz
57
+ dsh plugin --profile web add /tmp/quick-actions/dsh-quick-actions-0.2.0-rc.3.tgz
58
58
  ```
59
59
 
60
60
  上面的 `--filter` 形式在仓库任意位置都能用;如果你已经在包目录里,`pnpm pack --pack-destination /tmp/quick-actions` 即可。
@@ -134,7 +134,7 @@ pnpm 有一条供应链策略:拒绝发布时间在冷却窗口内(默认 24
134
134
  | 值 | 名称 | 位置 |
135
135
  |---|---|---|
136
136
  | `ribbon`(默认) | 上方动作带 | 输入框上方一行,与输入框等宽 |
137
- | `bar` | 下方操作栏 | 输入框下方一行,与 DSH 自己的用量信息并排,宽度随内容、最多与输入卡片同宽,装不下的折进「更多」 |
137
+ | `bar` | 下方操作栏 | 带 footer 核心补丁时:统计行下方独占新行,动作组在输入框宽度内居中;未打补丁时:保留与用量信息并排的原位置。装不下的动作折进「更多」 |
138
138
  | `launcher` | 单入口面板 | 一个入口按钮,点开可搜索的动作面板 |
139
139
 
140
140
  `bar` 与 `launcher` 共用同一个可搜索面板,搜索只匹配标签和文本。管理面板里可以给预置排序、隐藏、恢复、克隆,增删改自定义动作并启停它们,以及切换布局。
package/lib/client.js CHANGED
@@ -2058,7 +2058,7 @@ window.__ModuleLoader__.load({
2058
2058
  * | layout | Slot | body |
2059
2059
  * |------------|-----------------------------|-------------------------------------------------------------|
2060
2060
  * | `ribbon` | `conversation.input.dock` | title, the actions in shared order, and "manage" on one line |
2061
- * | `bar` | `conversation.composer.dock`| the leading actions that fit, then "more", then "manage" |
2061
+ * | `bar` | composer footer (dock fallback) | the leading actions that fit, then "more", then "manage" |
2062
2062
  * | `launcher` | `conversation.input.dock` | one compact entry carrying the Composer projection's count |
2063
2063
  *
2064
2064
  * Three rules hold across all of them:
@@ -3273,7 +3273,7 @@ window.__ModuleLoader__.load({
3273
3273
  //#endregion
3274
3274
  //#region src/client/surfaces/entries.tsx
3275
3275
  /**
3276
- * The two dock Slot entries (spec 7.3, 8.1).
3276
+ * The dock entries and optional composer footer (spec 7.3, 8.1, 23).
3277
3277
  *
3278
3278
  * Both are always registered; which one renders the layout is decided at render
3279
3279
  * time from the authoritative Settings snapshot, and both render nothing at all
@@ -3281,12 +3281,14 @@ window.__ModuleLoader__.load({
3281
3281
  *
3282
3282
  * - `conversation.composer.dock` is the residency beacon. Its mount is DSH's own
3283
3283
  * statement that this Session's composer is in its resident variant, so it
3284
- * marks the Session while mounted and additionally renders the `bar` layout.
3284
+ * marks the Session while mounted and renders `bar` only without a footer.
3285
+ * - `conversation.composer.footer`, when provided by the local core patch,
3286
+ * renders `bar` on its own row and suppresses that Session's dock fallback.
3285
3287
  * - `conversation.input.dock` renders `ribbon` or `launcher`, but only while the
3286
3288
  * beacon's mark stands — that Slot also mounts on the blank-session hero, and
3287
3289
  * the first release must never appear there.
3288
3290
  *
3289
- * A third entry rides the same input dock: the centralized management overlay,
3291
+ * Another entry rides the same input dock: the centralized management overlay,
3290
3292
  * which spec 8.1 requires to be registered independently of the layout entries.
3291
3293
  * It is a separate Slot cell with its own id, order and error boundary, so a
3292
3294
  * failure in the management panel cannot take a Composer layout down with it and
@@ -3387,8 +3389,9 @@ window.__ModuleLoader__.load({
3387
3389
  }
3388
3390
  /** Build both Slot entry components over one set of fiber-owned dependencies. */
3389
3391
  function createQuickActionDockEntries(deps) {
3392
+ const footers = createResidentComposerRegistry();
3390
3393
  function Body(props) {
3391
- const { owns, ...slot } = props;
3394
+ const { owns, footer, ...slot } = props;
3392
3395
  const client = useControllerState(deps.controller);
3393
3396
  const projection = client.projection;
3394
3397
  const onRetry = (0, react.useCallback)(() => {
@@ -3400,12 +3403,16 @@ window.__ModuleLoader__.load({
3400
3403
  onRetry
3401
3404
  }) : null;
3402
3405
  if (!owns.includes(projection.layout)) return null;
3403
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionSurface, {
3406
+ const surface = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionSurface, {
3404
3407
  ...slot,
3405
3408
  deps,
3406
3409
  layout: projection.layout,
3407
3410
  actions: projection.composer
3408
3411
  });
3412
+ return footer ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3413
+ className: "dsh-cqa-footer",
3414
+ children: surface
3415
+ }) : surface;
3409
3416
  }
3410
3417
  function InputDock(props) {
3411
3418
  const resident = useResident(deps.residency, props.sessionId);
@@ -3419,15 +3426,29 @@ window.__ModuleLoader__.load({
3419
3426
  }
3420
3427
  function ComposerDock(props) {
3421
3428
  const { sessionId } = props;
3429
+ const hasFooter = useResident(footers, sessionId);
3422
3430
  (0, react.useLayoutEffect)(() => deps.residency.mark(sessionId), [sessionId]);
3423
3431
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceErrorBoundary, {
3424
3432
  t: props.t,
3425
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Body, {
3433
+ children: hasFooter ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Body, {
3426
3434
  ...props,
3427
3435
  owns: COMPOSER_DOCK_LAYOUTS
3428
3436
  })
3429
3437
  });
3430
3438
  }
3439
+ function FooterDock(props) {
3440
+ const { sessionId } = props;
3441
+ const ready = useResident(footers, sessionId);
3442
+ (0, react.useLayoutEffect)(() => footers.mark(sessionId), [sessionId]);
3443
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceErrorBoundary, {
3444
+ t: props.t,
3445
+ children: ready ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Body, {
3446
+ ...props,
3447
+ owns: COMPOSER_DOCK_LAYOUTS,
3448
+ footer: true
3449
+ }) : null
3450
+ });
3451
+ }
3431
3452
  /**
3432
3453
  * The centralized management overlay (spec 8.1, 8.3).
3433
3454
  *
@@ -3450,6 +3471,7 @@ window.__ModuleLoader__.load({
3450
3471
  return {
3451
3472
  InputDock,
3452
3473
  ComposerDock,
3474
+ FooterDock,
3453
3475
  ManagerDock
3454
3476
  };
3455
3477
  }
@@ -3481,7 +3503,11 @@ window.__ModuleLoader__.load({
3481
3503
  * — the same cap the composer card uses — and is centred, so its left and right
3482
3504
  * edges coincide with the input box exactly rather than approximately.
3483
3505
  *
3484
- * `.dsh-cqa-bar` makes no such claim. Since DSH 0.1.6-alpha.2 the composer dock is
3506
+ * In the optional composer footer, the core owns card alignment and the bar
3507
+ * fills that row; its control group is centred (spec 23.1). The rules below
3508
+ * still apply to the fallback for unpatched cores.
3509
+ *
3510
+ * `.dsh-cqa-bar` in that fallback makes no such claim. Since DSH 0.1.6-alpha.2 the composer dock is
3485
3511
  * a row under the card that DSH centres and sizes to its content, shared with
3486
3512
  * DSH's own stats pills and context meter, so the bar is a content-sized member of
3487
3513
  * that row (spec 22.9). It only has to stay inside it: `min-width: 0` lets it
@@ -3510,6 +3536,24 @@ window.__ModuleLoader__.load({
3510
3536
  width: var(--dsh-composer-card-max-width);
3511
3537
  }
3512
3538
 
3539
+ /* The optional footer is already aligned to the card by its core owner.
3540
+ Only this plugin's row shrinks and centres the whole control group. */
3541
+ .dsh-cqa-footer {
3542
+ width: 100%;
3543
+ min-width: 0;
3544
+ }
3545
+ .dsh-cqa-footer > .dsh-cqa-bar {
3546
+ width: 100%;
3547
+ }
3548
+ .dsh-cqa-footer .dsh-cqa-row {
3549
+ width: fit-content;
3550
+ max-width: 100%;
3551
+ margin-inline: auto;
3552
+ }
3553
+ .dsh-cqa-footer [data-quick-actions-overflow] .dsh-cqa-row {
3554
+ width: 100%;
3555
+ }
3556
+
3513
3557
  .dsh-cqa-row {
3514
3558
  display: flex;
3515
3559
  align-items: center;
@@ -4016,7 +4060,7 @@ window.__ModuleLoader__.load({
4016
4060
  }, "composer-quick-actions: client controller");
4017
4061
  ctx.effect(() => ctx.locale.register(QUICK_ACTIONS_LOCALE_NAMESPACE, quickActionsDictionaries), "composer-quick-actions: dictionaries");
4018
4062
  ctx.effect(installQuickActionStyles, "composer-quick-actions: surface styles");
4019
- const { InputDock, ComposerDock, ManagerDock } = createQuickActionDockEntries({
4063
+ const { InputDock, ComposerDock, FooterDock, ManagerDock } = createQuickActionDockEntries({
4020
4064
  controller,
4021
4065
  sessions,
4022
4066
  residency,
@@ -4039,6 +4083,12 @@ window.__ModuleLoader__.load({
4039
4083
  order: DOCK_ORDER,
4040
4084
  locale: QUICK_ACTIONS_LOCALE_NAMESPACE
4041
4085
  }, ComposerDock));
4086
+ ctx.slots.inject("conversation.composer.footer", () => ctx.slots.register({
4087
+ name: "conversation.composer.footer",
4088
+ id: "composer-quick-actions",
4089
+ order: DOCK_ORDER,
4090
+ locale: QUICK_ACTIONS_LOCALE_NAMESPACE
4091
+ }, FooterDock));
4042
4092
  }
4043
4093
  //#endregion
4044
4094
  exports.apply = apply;