@senguoyun/dsh-arkme 0.1.71 → 0.1.72

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.
@@ -0,0 +1,38 @@
1
+ # DSH 嵌入右侧栏边界修复
2
+
3
+ ## 原因与范围
4
+
5
+ Arkme 将原生 DSH iframe 保持为整个浏览器大小,以便任务菜单越过对话区域显示;实际对话通过 AppFrame 定位和 iframe clip-path 限定在第三栏。
6
+
7
+ 原生右侧栏在 AppFrame 宽度小于 768px 时切到 `position: fixed; inset: 0; width: 100%` 的全屏模式,其定位仍相对于整个 iframe。1100px 窗口中第三栏从 x=344 开始、宽 756px,原生面板却从 x=0 开始、宽 1100px。文件列表因此被外层裁掉,造成空白、会话消失的观感;会话实际没有卸载。
8
+
9
+ 本次只在嵌入适配器内限制原生 fullscreen 面板的边界:横向与第三栏一致,纵向位于当前任务标题下方。标题变化通过尺寸观察同步,不写死高度。宽屏 push 并排布局不变,不替换上游面板、消息、输入框或状态存储。
10
+
11
+ ## 验证
12
+
13
+ - 类型检查、构建及本地打包通过。
14
+ - 9 个相关测试文件,78 项通过,覆盖嵌入区域、原生任务下拉、标题、菜单、拖拽与前一轮添加菜单。
15
+ - 独立 Web 预览 3098 安装包与本地 client.js SHA256 一致:`96f62c9b5c8920c554cca275608701cf5ed9c44cee389fdd5289754c36227397`。
16
+ - Chromium 浏览器验证:1440px 为并排面板;1100、900、720px 为第三栏内展开。标题与文件列表可见,开关后保持同一会话、输入组件和任务标题,无页面异常。
17
+ - 面板打开期间,1440 → 1100 → 720 → 420 → 1440 缩放通过,任务下拉仍能打开。
18
+ - 经用户确认继续修复后,420、500、575px 均通过:顶部名称、任务选择及工具按钮不越界,侧栏完整约束在第三栏且可关闭。打开按钮不再触发外层横向滚动;标题与会话输入组件保持原位和身份。
19
+ - 420px 和 1440px 的原生「更多操作」菜单均可打开、位于窗口边界内,Escape 可关闭。所有宽度无 pageerror。
20
+ - 已人工检查 1440、1100、720、420px 截图。未发送消息、创建会话、执行文件操作或调用通话。
21
+
22
+ ## 极窄窗口补充修复(已确认并完成)
23
+
24
+ 420px 窗口下第三栏仅 236px。打开面板前 header.scrollWidth 为 276px,外层会话容器 scrollWidth 为 501px;点击右侧按钮后该容器 scrollLeft 变为 144px,导致顶部标题离开可见区域。此问题与 fullscreen 面板坐标越界不同。
25
+
26
+ 用户确认后,仅在标题内容区域宽度不超过 360px 时将工具按钮另排一行;上方保留对话名与当前任务。使用标题自身的容器查询而非窗口媒体查询,适配左侧目录和侧栏对实际宽度的影响。原生 React 节点和事件绑定不移动、不重建,常规桌面布局不变。
27
+
28
+ 420px 复测中标题保持 x=184,外层 scrollLeft=0;标题高度由 73px 自适应为 109px,侧栏自动从 y=109 开始,不遮盖工具栏。放大回 1440px 后恢复 73px 单行布局。
29
+
30
+ 补充修复预览包:`senguoyun-dsh-arkme-0.1.70-narrow-header-20260921-0204.tgz`。本地与已安装 `harness-session-client.js` SHA256 一致:`0283b1954813f74e199d47c7552bc7a49f04520e03f96a0da96e29502727231e`。
31
+
32
+ ## 交付边界
33
+
34
+ 仅更新独立 3098 预览;未修改已安装的 Arkme 客户端、未发布 npm。Git 提交推送单独执行,不代表已合并或发布。上一轮添加菜单修复保留。旧版安装包和预览回滚包保留。
35
+
36
+ 提交前补充回归:12 个相关测试文件、95 项通过,包含对话/联系人工具栏尺寸和添加菜单 portal;`git diff --check` 通过。
37
+
38
+ 浏览器脚本与截图位于本机 `.codex-artifacts/web-preview-3098/`:`check-dsh-rightbar.mjs`、`dsh-rightbar-fixed-{width}.png`。
@@ -0,0 +1,29 @@
1
+ # 对话与联系人添加按钮回归(2026-09-21)
2
+
3
+ ## 已确认的交互
4
+
5
+ - 第二栏添加按钮与搜索框同高,使用 40×40px 方形按钮、11px 圆角及原有主题色。
6
+ - 悬浮立即展开,按钮与菜单之间可连续移动;短暂移出后 250ms 内返回取消关闭。
7
+ - 选择菜单项、点击外部、Escape 仍直接关闭;保留键盘与触摸入口。
8
+ - 联系人和对话入口统一使用同一个组件,不新增另一套菜单。
9
+
10
+ ## 根因与修改
11
+
12
+ - 旧添加按钮为 28×28px,搜索框为 40px 高。3098 修改前实测分别为 28px、40px。
13
+ - 原 hover 区域只覆盖左右菜单间隙;下拉菜单实际在按钮下方 4px,该间隙不属于有效区域。修改前浏览器鼠标移入间隙立即关闭。
14
+ - 添加按钮直接引用 `directorySearchLayout.field` 的高度和圆角,图标从 14px 放大到 20px。
15
+ - 补齐上、下方向的短距离菜单过渡区域;仅添加菜单启用 250ms 离开缓冲,其他菜单原有关闭时序不变。
16
+ - 返回按钮、菜单或过渡区取消定时关闭;连续向外移动不重置倒计时;关闭或卸载取消旧定时器,避免影响下一次展开。
17
+ - `ArkmePersistentShell` 联系人入口和 `ArkmeVirtualWorkspace` 对话入口均复用 `ArkmeQuickAddButton`,本次修改同时生效。
18
+
19
+ ## 验证
20
+
21
+ - 20 个相关测试文件、186 项测试通过;包含四方向过渡区域、停留间隙、移出再返回、菜单重开、外部点击、Esc、触摸、键盘、联系人真实工具栏尺寸及原有菜单交互。
22
+ - 类型检查、完整构建和打包通过。
23
+ - 独立 3098 页面:对话与联系人各在 1440、900、420px 宽度下验证。两个入口按钮均为 40×40px,与搜索框同高且顶部对齐。
24
+ - 浏览器实际鼠标验证:停留 4px 间隙、斜向进入菜单、短暂移出后返回、离开主页面菜单区域关闭;键盘 Enter/方向键/Escape、外部点击关闭均通过,未出现页面异常。
25
+ - 浏览器验证未创建联系人、群聊、Bot、任务或真实通话;相关业务写请求被拦截,选项动作由组件测试验证。
26
+
27
+ 预览脚本:`/Users/tison/arkme/.codex-artifacts/web-preview-3098/check-quick-add-hover.mjs`。
28
+
29
+ 仅更新独立 3098 Web 预览,未修改已安装 Arkme 客户端。Git 提交推送单独执行,不代表已合并或发布。
@@ -1830,6 +1830,19 @@ Arkme 用户 {v0}|Arkme user {v0}
1830
1830
  top,
1831
1831
  bottom
1832
1832
  });
1833
+ const left = Math.max(anchor.left, menu.left), right = Math.min(anchor.right, menu.right);
1834
+ if (anchor.bottom <= menu.top && menu.top - anchor.bottom <= 24) return contains({
1835
+ left,
1836
+ right,
1837
+ top: anchor.bottom,
1838
+ bottom: menu.top
1839
+ });
1840
+ if (menu.bottom <= anchor.top && anchor.top - menu.bottom <= 24) return contains({
1841
+ left,
1842
+ right,
1843
+ top: menu.bottom,
1844
+ bottom: anchor.top
1845
+ });
1833
1846
  return false;
1834
1847
  }
1835
1848
  //#endregion
@@ -2072,11 +2085,33 @@ Arkme 用户 {v0}|Arkme user {v0}
2072
2085
  const anchor = props.hoverAnchor;
2073
2086
  if (!open || !anchor || typeof document === "undefined") return;
2074
2087
  const doc = anchor.ownerDocument;
2075
- const close = () => closeRef.current();
2088
+ let pending;
2089
+ const cancel = () => {
2090
+ if (pending !== void 0) {
2091
+ clearTimeout(pending);
2092
+ pending = void 0;
2093
+ }
2094
+ };
2095
+ const close = () => {
2096
+ cancel();
2097
+ closeRef.current();
2098
+ };
2099
+ const scheduleClose = () => {
2100
+ if (!props.hoverCloseDelayMs) {
2101
+ close();
2102
+ return;
2103
+ }
2104
+ if (pending === void 0) pending = setTimeout(close, props.hoverCloseDelayMs);
2105
+ };
2076
2106
  const move = (event) => {
2077
2107
  if (event.pointerType === "touch") return;
2108
+ if (!anchor.isConnected) {
2109
+ close();
2110
+ return;
2111
+ }
2078
2112
  const list = menu.current;
2079
- if (!anchor.isConnected || list && !inMenuHoverRegion(event.clientX, event.clientY, anchor.getBoundingClientRect(), list.getBoundingClientRect())) close();
2113
+ if (!list || inMenuHoverRegion(event.clientX, event.clientY, anchor.getBoundingClientRect(), list.getBoundingClientRect())) cancel();
2114
+ else scheduleClose();
2080
2115
  };
2081
2116
  const leave = (event) => {
2082
2117
  if (event.relatedTarget === null) close();
@@ -2092,12 +2127,17 @@ Arkme 用户 {v0}|Arkme user {v0}
2092
2127
  doc.addEventListener("pointerout", leave, true);
2093
2128
  doc.defaultView?.addEventListener("blur", close);
2094
2129
  return () => {
2130
+ cancel();
2095
2131
  observer.disconnect();
2096
2132
  doc.removeEventListener("pointermove", move, true);
2097
2133
  doc.removeEventListener("pointerout", leave, true);
2098
2134
  doc.defaultView?.removeEventListener("blur", close);
2099
2135
  };
2100
- }, [open, props.hoverAnchor]);
2136
+ }, [
2137
+ open,
2138
+ props.hoverAnchor,
2139
+ props.hoverCloseDelayMs
2140
+ ]);
2101
2141
  const actions = props.actions.filter((action) => !!action);
2102
2142
  const items = actions.map((action) => "type" in action ? action : {
2103
2143
  id: action.id,
package/lib/client.js CHANGED
@@ -110527,6 +110527,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
110527
110527
  top,
110528
110528
  bottom
110529
110529
  });
110530
+ const left = Math.max(anchor.left, menu.left), right = Math.min(anchor.right, menu.right);
110531
+ if (anchor.bottom <= menu.top && menu.top - anchor.bottom <= 24) return contains({
110532
+ left,
110533
+ right,
110534
+ top: anchor.bottom,
110535
+ bottom: menu.top
110536
+ });
110537
+ if (menu.bottom <= anchor.top && anchor.top - menu.bottom <= 24) return contains({
110538
+ left,
110539
+ right,
110540
+ top: menu.bottom,
110541
+ bottom: anchor.top
110542
+ });
110530
110543
  return false;
110531
110544
  }
110532
110545
  //#endregion
@@ -110794,11 +110807,33 @@ Please report this to https://github.com/markedjs/marked.`, e) {
110794
110807
  const anchor = props.hoverAnchor;
110795
110808
  if (!open || !anchor || typeof document === "undefined") return;
110796
110809
  const doc = anchor.ownerDocument;
110797
- const close = () => closeRef.current();
110810
+ let pending;
110811
+ const cancel = () => {
110812
+ if (pending !== void 0) {
110813
+ clearTimeout(pending);
110814
+ pending = void 0;
110815
+ }
110816
+ };
110817
+ const close = () => {
110818
+ cancel();
110819
+ closeRef.current();
110820
+ };
110821
+ const scheduleClose = () => {
110822
+ if (!props.hoverCloseDelayMs) {
110823
+ close();
110824
+ return;
110825
+ }
110826
+ if (pending === void 0) pending = setTimeout(close, props.hoverCloseDelayMs);
110827
+ };
110798
110828
  const move = (event) => {
110799
110829
  if (event.pointerType === "touch") return;
110830
+ if (!anchor.isConnected) {
110831
+ close();
110832
+ return;
110833
+ }
110800
110834
  const list = menu.current;
110801
- if (!anchor.isConnected || list && !inMenuHoverRegion(event.clientX, event.clientY, anchor.getBoundingClientRect(), list.getBoundingClientRect())) close();
110835
+ if (!list || inMenuHoverRegion(event.clientX, event.clientY, anchor.getBoundingClientRect(), list.getBoundingClientRect())) cancel();
110836
+ else scheduleClose();
110802
110837
  };
110803
110838
  const leave = (event) => {
110804
110839
  if (event.relatedTarget === null) close();
@@ -110814,12 +110849,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
110814
110849
  doc.addEventListener("pointerout", leave, true);
110815
110850
  doc.defaultView?.addEventListener("blur", close);
110816
110851
  return () => {
110852
+ cancel();
110817
110853
  observer.disconnect();
110818
110854
  doc.removeEventListener("pointermove", move, true);
110819
110855
  doc.removeEventListener("pointerout", leave, true);
110820
110856
  doc.defaultView?.removeEventListener("blur", close);
110821
110857
  };
110822
- }, [open, props.hoverAnchor]);
110858
+ }, [
110859
+ open,
110860
+ props.hoverAnchor,
110861
+ props.hoverCloseDelayMs
110862
+ ]);
110823
110863
  const actions = props.actions.filter((action) => !!action);
110824
110864
  const items = actions.map((action) => "type" in action ? action : {
110825
110865
  id: action.id,
@@ -139762,6 +139802,7 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139762
139802
  let nativeObserver;
139763
139803
  let viewportStyle;
139764
139804
  let contentFrame;
139805
+ let sessionHeader;
139765
139806
  let scheduled = 0;
139766
139807
  let disposed = false;
139767
139808
  const shadow = surface.ownerDocument.createElement("div");
@@ -139798,6 +139839,16 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139798
139839
  contentFrame = nextContent;
139799
139840
  contentFrame?.setAttribute("data-arkme-harness-content-frame", "");
139800
139841
  }
139842
+ const nextHeader = contentFrame?.querySelector("[data-slot=\"conversation.session.header\"] > header") ?? void 0;
139843
+ if (nextHeader !== sessionHeader) {
139844
+ if (sessionHeader) resize?.unobserve(sessionHeader);
139845
+ sessionHeader = nextHeader;
139846
+ if (sessionHeader) resize?.observe(sessionHeader);
139847
+ }
139848
+ const headerBottom = sessionHeader?.getAttribute("aria-hidden") !== "true" ? sessionHeader?.getBoundingClientRect().bottom ?? rect.top : rect.top;
139849
+ const panelTop = Math.min(rect.bottom, Math.max(rect.top, headerBottom));
139850
+ set(viewport, "--arkme-harness-panel-top", `${panelTop}px`);
139851
+ set(viewport, "--arkme-harness-panel-height", `${Math.max(0, rect.bottom - panelTop)}px`);
139801
139852
  const ready = contentFrame !== void 0;
139802
139853
  const layers = ready ? harnessMenuLayers(native) : [];
139803
139854
  let menuRect;
@@ -139850,6 +139901,8 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139850
139901
  viewportStyle?.remove();
139851
139902
  contentFrame?.removeAttribute("data-arkme-harness-content-frame");
139852
139903
  contentFrame = void 0;
139904
+ if (sessionHeader) resize?.unobserve(sessionHeader);
139905
+ sessionHeader = void 0;
139853
139906
  native?.documentElement.removeAttribute("data-arkme-harness-viewport");
139854
139907
  try {
139855
139908
  native = frame.contentDocument ?? void 0;
@@ -139865,6 +139918,12 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139865
139918
  position: absolute !important; left: var(--arkme-harness-content-left); top: var(--arkme-harness-content-top);
139866
139919
  width: var(--arkme-harness-content-width); height: var(--arkme-harness-content-height);
139867
139920
  }
139921
+ [data-arkme-harness-content-frame] [data-sidebar-right-panel="fullscreen"] {
139922
+ left: var(--arkme-harness-content-left) !important; right: auto !important;
139923
+ top: var(--arkme-harness-panel-top) !important; bottom: auto !important;
139924
+ width: var(--arkme-harness-content-width) !important;
139925
+ height: var(--arkme-harness-panel-height) !important;
139926
+ }
139868
139927
  `;
139869
139928
  native.head.append(viewportStyle);
139870
139929
  nativeObserver = new win.MutationObserver(schedule);
@@ -139876,6 +139935,7 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139876
139935
  "style",
139877
139936
  "class",
139878
139937
  "hidden",
139938
+ "aria-hidden",
139879
139939
  "data-arkme-session-open",
139880
139940
  "data-arkme-session-frame"
139881
139941
  ]
@@ -139919,6 +139979,7 @@ body:has([data-arkme-self-topic-menu]) > [role="menu"] { z-index: 10030; }
139919
139979
  "width",
139920
139980
  "height"
139921
139981
  ]) native?.documentElement.style.removeProperty(`--arkme-harness-content-${key}`);
139982
+ for (const key of ["top", "height"]) native?.documentElement.style.removeProperty(`--arkme-harness-panel-${key}`);
139922
139983
  };
139923
139984
  }
139924
139985
  //#endregion
@@ -152923,14 +152984,15 @@ html body {
152923
152984
  flex: "none"
152924
152985
  },
152925
152986
  trigger: {
152926
- width: 28,
152927
- height: 28,
152987
+ width: directorySearchLayout.field.height,
152988
+ height: directorySearchLayout.field.height,
152928
152989
  flex: "none",
152929
152990
  padding: 0,
152930
152991
  display: "grid",
152931
152992
  placeItems: "center",
152993
+ boxSizing: "border-box",
152932
152994
  border: 0,
152933
- borderRadius: 999,
152995
+ borderRadius: directorySearchLayout.field.borderRadius,
152934
152996
  backgroundColor: "var(--dsw-specific-selector, transparent)",
152935
152997
  color: "var(--dsw-alias-label-primary)",
152936
152998
  cursor: "pointer",
@@ -153073,6 +153135,7 @@ html body {
153073
153135
  anchor,
153074
153136
  align: "end",
153075
153137
  onClose,
153138
+ hoverCloseDelayMs: 250,
153076
153139
  ...getAnchorRect === void 0 ? {} : { getAnchorRect },
153077
153140
  ...hoverAnchor === void 0 ? {} : { hoverAnchor },
153078
153141
  actions: [
@@ -153185,7 +153248,7 @@ html body {
153185
153248
  else openMenu();
153186
153249
  },
153187
153250
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, {
153188
- size: 14,
153251
+ size: 20,
153189
153252
  "aria-hidden": true
153190
153253
  })
153191
153254
  }),
@@ -201350,7 +201413,7 @@ registerProcessor('arkme-pcm-journal', ArkmePcmJournal);
201350
201413
  const c$3 = e$24;
201351
201414
  //#endregion
201352
201415
  //#region package.json
201353
- var version = "0.1.71";
201416
+ var version = "0.1.72";
201354
201417
  //#endregion
201355
201418
  //#region src/client/profile-change-store.ts
201356
201419
  let revision = 0;