@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 +24 -0
- package/CHANGELOG.zh-CN.md +24 -0
- package/lib/client.js +85 -10
- package/package.json +1 -1
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.
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -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
|
-
|
|
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]
|
|
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]
|
|
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
|
}
|