@michengai/dsh-codex-ui 1.1.10 → 1.1.11

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 CHANGED
@@ -4,6 +4,30 @@
4
4
 
5
5
  This changelog records recent releases of DSH Codex UI and its one-click installer. Earlier changes remain available in the [Git history](https://github.com/MichengAI/dsh-codex-ui/commits/main).
6
6
 
7
+ ## 1.1.11 - 2026-09-16
8
+
9
+ - Open the settings page (and usage statistics) through a `document.body` portal so a collapsed 56px rail cannot trap the overlay in a transform containing block.
10
+ - Skip the dsh-context `context-overview` footer action by slot id and render the remaining footer actions one by one. Usage statistics stays visible. Footer actions without an id are dropped. The per-session Context tab is unchanged.
11
+ - Pin a dragged project into an empty pinned section even when dragleave clears the insertion target.
12
+
13
+ ## suite-installer-v1.0.13 - 2026-09-16
14
+
15
+ Install or maintain 11 first-party plugins in one step. Included plugins and versions:
16
+
17
+ - `@michengai/dsh-archive-manager@0.1.43`
18
+ - `@michengai/dsh-codex-ui@1.1.10`
19
+ - `@michengai/dsh-skills-manager@0.1.52`
20
+ - `@michengai/dsh-agency-agents@0.1.43`
21
+ - `@michengai/dsh-im-connect@0.1.50`
22
+ - `@michengai/dsh-automation@0.1.44`
23
+ - `@michengai/dsh-btw@0.1.8`
24
+ - `@michengai/dsh-simplify@0.1.5`
25
+ - `@michengai/dsh-pua@0.3.13`
26
+ - `@michengai/dsh-code-review@0.1.2`
27
+ - `@michengai/dsh-codex-pet@0.1.6`
28
+
29
+ The installer uses these exact versions for reproducible installation.
30
+
7
31
  ## 1.1.10 - 2026-09-16
8
32
 
9
33
  - Cold start registers session titles through a dedicated `@michengai/dsh-codex-ui/session-title` plugin after `sessionTitle` and `llm` are ready, and recycles the provider on unload.
@@ -4,6 +4,30 @@
4
4
 
5
5
  本日志记录 DSH Codex UI 及其一键安装器的最近发布;更早的变更可查看 [Git 提交历史](https://github.com/MichengAI/dsh-codex-ui/commits/main)。
6
6
 
7
+ ## 1.1.11 - 2026-09-16
8
+
9
+ - 设置页和用量统计改为挂到 `document.body`。侧栏收缩后,宿主或插件若给窄轨加了 transform,全屏页不再被困在 56px 里挤成竖排。
10
+ - 侧栏底部按 slot id 跳过 dsh-context 的 `context-overview`,其余底部动作(含费用统计)仍按 id 单独渲染。没有 id 的底部动作不渲染。会话里的上下文页还在。
11
+ - 置顶为空时,从项目区拖入仍会置顶;松手时即使蓝线落点被清掉也不丢。
12
+
13
+ ## suite-installer-v1.0.13 - 2026-09-16
14
+
15
+ 一键维护安装 11 个自研插件。包含以下插件及版本:
16
+
17
+ - `@michengai/dsh-archive-manager@0.1.43`
18
+ - `@michengai/dsh-codex-ui@1.1.10`
19
+ - `@michengai/dsh-skills-manager@0.1.52`
20
+ - `@michengai/dsh-agency-agents@0.1.43`
21
+ - `@michengai/dsh-im-connect@0.1.50`
22
+ - `@michengai/dsh-automation@0.1.44`
23
+ - `@michengai/dsh-btw@0.1.8`
24
+ - `@michengai/dsh-simplify@0.1.5`
25
+ - `@michengai/dsh-pua@0.3.13`
26
+ - `@michengai/dsh-code-review@0.1.2`
27
+ - `@michengai/dsh-codex-pet@0.1.6`
28
+
29
+ 安装器使用这些精确版本执行安装,确保可复现。
30
+
7
31
  ## 1.1.10 - 2026-09-16
8
32
 
9
33
  - 冷启动也能自动命名:独立挂上 `@michengai/dsh-codex-ui/session-title`,等 `sessionTitle` 与 `llm` 就绪后再占 first-prompt;卸载时回收提供方。
package/lib/client.js CHANGED
@@ -2451,6 +2451,18 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2451
2451
  workspaceId
2452
2452
  };
2453
2453
  }
2454
+ /**
2455
+ * 空置顶没有项目行可自行计算落点,松手时 dragleave 又常把 relatedTarget 置空并清掉蓝线。
2456
+ * 只要这次 drop 发生在置顶区,空列表也必须把项目置顶。
2457
+ */
2458
+ function resolvePinnedSectionDrop(draggedWorkspace, target, pinnedEmpty) {
2459
+ if (draggedWorkspace === void 0) return void 0;
2460
+ if (target?.zone === "pinned") return {
2461
+ id: draggedWorkspace,
2462
+ beforeId: target.beforeId
2463
+ };
2464
+ return pinnedEmpty ? { id: draggedWorkspace } : void 0;
2465
+ }
2454
2466
  /** 按指定 id 顺序取出对应项;未出现在 ids 中的项丢弃。 */
2455
2467
  function orderByIds(items, ids, idOf) {
2456
2468
  const byId = new Map(items.map((item) => [idOf(item), item]));
@@ -4492,10 +4504,11 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
4492
4504
  const target = workspaceDropTargetRef.current;
4493
4505
  setWorkspaceDragId(void 0);
4494
4506
  setWorkspaceDropTarget(void 0);
4495
- if (draggedWorkspace !== void 0 && target?.zone === "pinned") pinWorkspaceAt(draggedWorkspace, target.beforeId);
4507
+ const drop = resolvePinnedSectionDrop(draggedWorkspace, target, pinnedGroups.length === 0);
4508
+ if (drop !== void 0) pinWorkspaceAt(drop.id, drop.beforeId);
4496
4509
  },
4497
4510
  onDragLeave: (event) => {
4498
- if (event.currentTarget.contains(event.relatedTarget)) return;
4511
+ if (!(event.relatedTarget instanceof Node) || event.currentTarget.contains(event.relatedTarget)) return;
4499
4512
  setWorkspaceDropTarget(void 0);
4500
4513
  },
4501
4514
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -4541,10 +4554,36 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
4541
4554
  zone: "pinned",
4542
4555
  beforeId: void 0
4543
4556
  });
4557
+ },
4558
+ onDrop: (event) => {
4559
+ event.preventDefault();
4560
+ event.stopPropagation();
4561
+ const draggedWorkspace = readWorkspaceDrag(event.dataTransfer, workspaceDragId);
4562
+ setWorkspaceDragId(void 0);
4563
+ setWorkspaceDropTarget(void 0);
4564
+ if (draggedWorkspace !== void 0) pinWorkspaceAt(draggedWorkspace);
4544
4565
  }
4545
4566
  }),
4546
4567
  pinnedGroups.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4547
4568
  className: "dcu-wb-empty",
4569
+ onDragOver: (event) => {
4570
+ if (!pinDragActive) return;
4571
+ event.preventDefault();
4572
+ event.stopPropagation();
4573
+ event.dataTransfer.dropEffect = "move";
4574
+ setWorkspaceDropTarget({
4575
+ zone: "pinned",
4576
+ beforeId: void 0
4577
+ });
4578
+ },
4579
+ onDrop: (event) => {
4580
+ event.preventDefault();
4581
+ event.stopPropagation();
4582
+ const draggedWorkspace = readWorkspaceDrag(event.dataTransfer, workspaceDragId);
4583
+ setWorkspaceDragId(void 0);
4584
+ setWorkspaceDropTarget(void 0);
4585
+ if (draggedWorkspace !== void 0) pinWorkspaceAt(draggedWorkspace);
4586
+ },
4548
4587
  children: t("workspace.pinnedEmpty")
4549
4588
  }),
4550
4589
  pinnedGroups.map((workspace) => renderGroup(workspace, "pinned")),
@@ -6449,6 +6488,8 @@ body[data-ds-dark-theme] [data-conversation-scroll] [data-trigger-menu]{backgrou
6449
6488
  //#region src/client/CodexSidebar.tsx
6450
6489
  const subscribeEmptyCompanionTabs = () => () => {};
6451
6490
  const getEmptyCompanionTabs = () => EMPTY_COMPANION_TABS;
6491
+ const emptyFooterActions = [];
6492
+ const getEmptyFooterActions = () => emptyFooterActions;
6452
6493
  const SIDEBAR_COLLAPSE_SETTLE_MS = 500;
6453
6494
  const SIDEBAR_EXPANSION_STORAGE_KEY = "dsh-codex-ui.sidebar-expansion.v1";
6454
6495
  const EXTENSIONS_EXPANSION_KEY = "extensions";
@@ -6833,8 +6874,9 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
6833
6874
  });
6834
6875
  });
6835
6876
  /** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
6836
- function CodexSidebar({ globalPanels, selectPanel, usePanelInfo = useLegacyPanelInfo, collapsed, width, openSession, startSession, toggleSidebar, archiveSession, canDeleteSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces, prefillNewConversation, newConversationDraft }) {
6877
+ function CodexSidebar({ globalPanels, footerActions, selectPanel, usePanelInfo = useLegacyPanelInfo, collapsed, width, openSession, startSession, toggleSidebar, archiveSession, canDeleteSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces, prefillNewConversation, newConversationDraft }) {
6837
6878
  const panels = (0, react.useSyncExternalStore)(globalPanels?.subscribe ?? subscribeEmptyCompanionTabs, globalPanels?.getSnapshot ?? getEmptyPanels, globalPanels?.getSnapshot ?? getEmptyPanels);
6879
+ const visibleFooterActions = (0, react.useSyncExternalStore)(footerActions?.subscribe ?? subscribeEmptyCompanionTabs, footerActions?.getSnapshot ?? getEmptyFooterActions, footerActions?.getSnapshot ?? getEmptyFooterActions);
6838
6880
  const activePanelId = usePanelInfo((info) => info.activePanelId);
6839
6881
  const panelButtons = (wide) => selectPanel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalPanelButtons, {
6840
6882
  panels,
@@ -7325,7 +7367,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
7325
7367
  className: "dcu-foot",
7326
7368
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7327
7369
  className: "dcu-footer-actions",
7328
- children: renderSlot("sidebar.footer.action", { wide: !visualCompact })
7370
+ children: footerActions === void 0 ? renderSlot("sidebar.footer.action", { wide: !visualCompact }) : visibleFooterActions.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderSlot("sidebar.footer.action", { wide: !visualCompact }, { only: action.id }) }, action.id))
7329
7371
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7330
7372
  ref: settingsSeat,
7331
7373
  className: "dcu-settings-seat",
@@ -8550,6 +8592,38 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
8550
8592
  "sessionTitle.type.research": "Research",
8551
8593
  "meta.locale": "en-US"
8552
8594
  };
8595
+ const HIDDEN_FOOTER_ACTION_IDS = /* @__PURE__ */ new Set(["context-overview"]);
8596
+ function visibleFooterActions(slots) {
8597
+ return slots.entriesOfSlot("sidebar.footer.action").flatMap(({ options }) => {
8598
+ const id = options.id;
8599
+ if (id === void 0 || HIDDEN_FOOTER_ACTION_IDS.has(id)) return [];
8600
+ return [{
8601
+ id,
8602
+ order: options.order ?? 0
8603
+ }];
8604
+ }).sort((left, right) => left.order - right.order);
8605
+ }
8606
+ function sameFooterActions(left, right) {
8607
+ return left.length === right.length && left.every((action, index) => {
8608
+ const previous = right[index];
8609
+ return previous !== void 0 && action.id === previous.id && action.order === previous.order;
8610
+ });
8611
+ }
8612
+ /** 给 React useSyncExternalStore 用的底部动作快照;按 slot id 过滤,不靠 DOM class。 */
8613
+ function createFooterActionSource(slots) {
8614
+ let cached = [];
8615
+ return {
8616
+ getSnapshot() {
8617
+ const next = visibleFooterActions(slots);
8618
+ if (sameFooterActions(next, cached)) return cached;
8619
+ cached = next;
8620
+ return cached;
8621
+ },
8622
+ subscribe(listener) {
8623
+ return slots.subscribe("sidebar.footer.action", listener);
8624
+ }
8625
+ };
8626
+ }
8553
8627
  //#endregion
8554
8628
  //#region src/client/host-open-path.ts
8555
8629
  const OPEN_IN_EXPLORER_ENDPOINT = CODEX_UI_API_ENDPOINTS.openInExplorer;
@@ -8985,10 +9059,10 @@ html[data-dsh-native-backdrop=mica] #root :is([class$="_centerCol"],[class$="_de
8985
9059
  html[data-dsh-native-backdrop=mica] :is(.dcu-root,.dcu-settings-nav){background:rgba(255,255,255,.18)}
8986
9060
  html[data-dsh-native-backdrop=mica] body[data-ds-dark-theme] :is(.dcu-root,.dcu-settings-nav){background:rgba(20,23,22,.18)}
8987
9061
  /* 会话折叠容器显式设了 visible,必须同时隐藏隔离分支的后代,避免穿透透明设置页。 */
8988
- html[data-dsh-native-backdrop=mica] .dcu-root:has(.dcu-settings-page) :is([inert],[inert] *){visibility:hidden!important}
9062
+ html[data-dsh-native-backdrop=mica] body:has(.dcu-settings-page) .dcu-root :is([inert],[inert] *){visibility:hidden!important}
8989
9063
  /* 同步隐藏本设置页隔离的外部 portal,保留引导模态及其他组件自己的 inert 语义。 */
8990
9064
  body:has(.dcu-settings-page) :is([data-dcu-settings-isolated],[data-dcu-settings-isolated] *){visibility:hidden!important}
8991
- html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-backdrop=mica] .dcu-root:has(.dcu-settings-page){background:transparent}
9065
+ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-backdrop=mica] body:has(.dcu-settings-page) .dcu-root{background:transparent}
8992
9066
 
8993
9067
  .dcu-settings-inner:has(.dcu-usage-section){height:100%;display:flex;flex-direction:column;padding-bottom:0}
8994
9068
  .dcu-settings-inner:has(.dcu-usage-section)>.dcu-settings-heading{display:none}
@@ -9233,7 +9307,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
9233
9307
  restartActionLabel: t("settings.reconnect"),
9234
9308
  onReconnect: reconnect
9235
9309
  }),
9236
- open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9310
+ (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
9237
9311
  ref: page,
9238
9312
  className: "dcu-settings-page",
9239
9313
  "data-dcu-settings-page": true,
@@ -9325,8 +9399,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
9325
9399
  }), active !== void 0 && renderSlot("settings.section", { close }, { only: active.id })]
9326
9400
  })
9327
9401
  })]
9328
- }),
9329
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9402
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9330
9403
  ref: onboardingRoot,
9331
9404
  style: { display: "contents" },
9332
9405
  children: step !== void 0 && renderSlot("settings.onboarding", {
@@ -9336,7 +9409,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
9336
9409
  },
9337
9410
  openSection
9338
9411
  }, { only: step.id })
9339
- })
9412
+ })] }), document.body)
9340
9413
  ] });
9341
9414
  }
9342
9415
  /** 每条偏好仍由原插件渲染和保存,只为公共条目添加可扩展的分组容器。 */
@@ -10292,6 +10365,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10292
10365
  });
10293
10366
  const companionSlots = createCompanionTabSource(ctx.slots);
10294
10367
  const globalPanels = createGlobalPanelSource(ctx.slots, ctx.locale);
10368
+ const footerActions = createFooterActionSource(ctx.slots);
10295
10369
  ctx.slots.inject("sidebar", () => ctx.slots.register({
10296
10370
  name: "sidebar",
10297
10371
  registrant: "michengai-codex-ui",
@@ -10347,6 +10421,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10347
10421
  openPath,
10348
10422
  companionSlots,
10349
10423
  globalPanels,
10424
+ footerActions,
10350
10425
  selectPanel: (id) => {
10351
10426
  selectGlobalPanel(ctx.layout, id);
10352
10427
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michengai/dsh-codex-ui",
3
- "version": "1.1.10",
3
+ "version": "1.1.11",
4
4
  "description": "以 Codex 风格重构 DSH Web 侧栏的独立客户端插件",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {