@michengai/dsh-codex-ui 0.2.99 → 0.2.101
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 +35 -0
- package/CHANGELOG.zh-CN.md +35 -0
- package/dist/client.js +87 -19
- package/dist/index.mjs +1 -39
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,41 @@
|
|
|
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
|
+
## 0.2.101 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
Companion release: `@michengai/dsh-codex-suite-installer@0.1.18`.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Restored the host pending-interaction store as a fallback for workspace, channel, and scheduled-task trees when `SessionSummary.pendingInteraction` is absent, so approvals, questions, and plan reviews remain visible in Web and Desktop sidebars.
|
|
14
|
+
- Kept valid `SessionSummary.pendingInteraction` values authoritative while preserving a stable empty-store fallback for older hosts that do not inject the hook.
|
|
15
|
+
|
|
16
|
+
### Tests
|
|
17
|
+
|
|
18
|
+
- Added DOM integration coverage for all three trees using the real pending-interaction store path, alongside the existing `SessionSummary` snapshot coverage.
|
|
19
|
+
|
|
20
|
+
### Dependencies
|
|
21
|
+
|
|
22
|
+
- The Suite Installer release workflow will resolve Codex UI `0.2.101` after this release is published.
|
|
23
|
+
|
|
24
|
+
## 0.2.100 — 2026-09-01
|
|
25
|
+
|
|
26
|
+
Companion release: `@michengai/dsh-codex-suite-installer@0.1.17`.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- Added pending-interaction indicators to workspace, channel, and scheduled-task trees for questions, approvals, and plan reviews, with the warning state taking precedence over unread and running indicators.
|
|
31
|
+
- Aligned all three trees with the official `SessionSummary.pendingInteraction` contract, removed the unused host-store abstraction, and matched the official English status labels.
|
|
32
|
+
- Removed the package release-age guard from About-page companion installs and updates so explicitly requested versions can be installed immediately.
|
|
33
|
+
|
|
34
|
+
### Tests
|
|
35
|
+
|
|
36
|
+
- Added DOM rendering coverage for pending-interaction states in all three trees using fully typed `SessionListState` and `SessionSummary` snapshots.
|
|
37
|
+
|
|
38
|
+
### Dependencies
|
|
39
|
+
|
|
40
|
+
- The Suite Installer release workflow will resolve Codex UI `0.2.100` after this release is published.
|
|
41
|
+
|
|
7
42
|
## 0.2.99 — 2026-09-01
|
|
8
43
|
|
|
9
44
|
Companion release: `@michengai/dsh-codex-suite-installer@0.1.16`.
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -4,6 +4,41 @@
|
|
|
4
4
|
|
|
5
5
|
本日志记录 DSH Codex UI 及其一键安装器的最近发布;更早的变更可查看 [Git 提交历史](https://github.com/MichengAI/dsh-codex-ui/commits/main)。
|
|
6
6
|
|
|
7
|
+
## 0.2.101 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
配套版本:`@michengai/dsh-codex-suite-installer@0.1.18`。
|
|
10
|
+
|
|
11
|
+
### 修复
|
|
12
|
+
|
|
13
|
+
- 当 `SessionSummary.pendingInteraction` 缺失时,任务、频道和定时任务树恢复回退读取宿主待处理交互 Store,确保 Web 与 Desktop 侧栏继续显示等待审批、等待回答和计划待审状态。
|
|
14
|
+
- 有效的 `SessionSummary.pendingInteraction` 仍保持最高优先级;旧宿主未注入 Hook 时使用稳定空 Store 安全降级。
|
|
15
|
+
|
|
16
|
+
### 测试
|
|
17
|
+
|
|
18
|
+
- 在原有 `SessionSummary` 快照覆盖之外,为三棵树补充真实待处理交互 Store 路径的 DOM 集成测试。
|
|
19
|
+
|
|
20
|
+
### 依赖
|
|
21
|
+
|
|
22
|
+
- Suite Installer 发布 workflow 会在本版本发布后解析 Codex UI `0.2.101`。
|
|
23
|
+
|
|
24
|
+
## 0.2.100 — 2026-09-01
|
|
25
|
+
|
|
26
|
+
配套版本:`@michengai/dsh-codex-suite-installer@0.1.17`。
|
|
27
|
+
|
|
28
|
+
### 修复
|
|
29
|
+
|
|
30
|
+
- 在任务、频道和定时任务树中显示等待回答、等待审批和计划待审状态,并让待处理警告优先于未读和运行中标记。
|
|
31
|
+
- 三棵树统一使用官方 `SessionSummary.pendingInteraction` 契约,删除未使用的宿主状态抽象,并对齐官方英文状态文案。
|
|
32
|
+
- 移除关于页配套插件安装与更新的发布时间保护,让用户明确请求的版本可以立即安装。
|
|
33
|
+
|
|
34
|
+
### 测试
|
|
35
|
+
|
|
36
|
+
- 使用完整类型约束的 `SessionListState` 和 `SessionSummary` 快照,为三棵树补充待处理状态 DOM 渲染测试。
|
|
37
|
+
|
|
38
|
+
### 依赖
|
|
39
|
+
|
|
40
|
+
- Suite Installer 发布 workflow 会在本版本发布后解析 Codex UI `0.2.100`。
|
|
41
|
+
|
|
7
42
|
## 0.2.99 — 2026-09-01
|
|
8
43
|
|
|
9
44
|
配套版本:`@michengai/dsh-codex-suite-installer@0.1.16`。
|
package/dist/client.js
CHANGED
|
@@ -501,7 +501,41 @@ window.__ModuleLoader__.load({
|
|
|
501
501
|
function pointerMenuRect(x, y) {
|
|
502
502
|
return new DOMRect(x, y, 0, 0);
|
|
503
503
|
}
|
|
504
|
-
function
|
|
504
|
+
function pendingLabel(kind, t) {
|
|
505
|
+
switch (kind) {
|
|
506
|
+
case "approval": return t("sessions.waitingApproval");
|
|
507
|
+
case "plan-review": return t("sessions.planReview");
|
|
508
|
+
case "question": return t("sessions.waitingAnswer");
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
function SessionState({ pendingInteraction, unread, running, t }) {
|
|
512
|
+
if (pendingInteraction !== void 0) {
|
|
513
|
+
const label = pendingLabel(pendingInteraction, t);
|
|
514
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
515
|
+
className: "dcu-wb-pending",
|
|
516
|
+
"data-state": "warning",
|
|
517
|
+
"data-pending-kind": pendingInteraction,
|
|
518
|
+
"aria-label": label,
|
|
519
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
520
|
+
className: "dcu-wb-pending-dot",
|
|
521
|
+
"aria-hidden": "true"
|
|
522
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
523
|
+
className: "dcu-wb-pending-label",
|
|
524
|
+
children: label
|
|
525
|
+
})]
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (unread) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
529
|
+
className: "dcu-wb-unread",
|
|
530
|
+
"aria-label": t("sessions.unread")
|
|
531
|
+
});
|
|
532
|
+
if (running) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
533
|
+
className: "dcu-wb-running",
|
|
534
|
+
"aria-hidden": "true"
|
|
535
|
+
});
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
function SessionRow({ id, title, selected, menuOpen, pinned, unread, running, pendingInteraction, t, menuItems, onOpen, onMenuChange, onSelectAction, onPin, onArchive, onHover, onLeave, onContextMenu, menuPoint, subtitle, flat, draggable, dropActive, onDragStart, onDragEnd, onDragOver, onDrop }) {
|
|
505
539
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
506
540
|
className: `dcu-wb-session${selected ? " dcu-wb-selected" : ""}${menuOpen ? " dcu-wb-menu-open" : ""}${dropActive === true ? " dcu-wb-drop" : ""}${flat === true ? " dcu-wb-session-flat" : ""}`,
|
|
507
541
|
role: "treeitem",
|
|
@@ -534,13 +568,12 @@ window.__ModuleLoader__.load({
|
|
|
534
568
|
"aria-label": t("sessions.pinned"),
|
|
535
569
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinMark, {})
|
|
536
570
|
}),
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}) : null,
|
|
571
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionState, {
|
|
572
|
+
pendingInteraction,
|
|
573
|
+
unread,
|
|
574
|
+
running,
|
|
575
|
+
t
|
|
576
|
+
}),
|
|
544
577
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
545
578
|
className: "dcu-wb-quick-actions",
|
|
546
579
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -621,6 +654,23 @@ window.__ModuleLoader__.load({
|
|
|
621
654
|
});
|
|
622
655
|
}
|
|
623
656
|
//#endregion
|
|
657
|
+
//#region src/client/session-pending.ts
|
|
658
|
+
const EMPTY_PENDING_INTERACTIONS = /* @__PURE__ */ new Map();
|
|
659
|
+
function useEmptySessionPendingInteraction(selector) {
|
|
660
|
+
return selector(EMPTY_PENDING_INTERACTIONS);
|
|
661
|
+
}
|
|
662
|
+
function visiblePendingKind(kind) {
|
|
663
|
+
switch (kind) {
|
|
664
|
+
case "approval":
|
|
665
|
+
case "plan-review":
|
|
666
|
+
case "question": return kind;
|
|
667
|
+
default: return;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
function pendingInteractionForSession(sessionId, pendingInteractions, summaryKind) {
|
|
671
|
+
return visiblePendingKind(summaryKind) ?? visiblePendingKind(pendingInteractions.get(sessionId)?.kind);
|
|
672
|
+
}
|
|
673
|
+
//#endregion
|
|
624
674
|
//#region src/client/pinned-workspaces.ts
|
|
625
675
|
/** 浏览器本地持久化键;置顶只影响本插件中的工作区分区。 */
|
|
626
676
|
const PINNED_WORKSPACES_STORAGE_KEY = "dsh-codex-ui.pinned-workspace-ids";
|
|
@@ -1361,6 +1411,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1361
1411
|
.dcu-wb-context-anchor{opacity:0;pointer-events:none}
|
|
1362
1412
|
.dcu-wb-tip{position:fixed;z-index:10050;min-width:220px;max-width:280px;padding:10px 12px;border:1px solid var(--dcu-sidebar-border);border-radius:12px;background:var(--dcu-tip-bg,#fff);box-shadow:var(--dcu-tip-shadow,0 8px 28px rgba(31,39,36,.16));color:var(--dcu-sidebar-primary);animation:dcu-tip-in 180ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-tip-in{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.dcu-wb-tip{animation:none}}.dcu-wb-tip-title{display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0;font-size:14px;line-height:20px;font-weight:500}.dcu-wb-tip-time{flex:none;color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:18px;font-weight:400}.dcu-wb-tip-title>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-wb-tip-meta{margin-top:6px;color:var(--dcu-sidebar-secondary);font-size:12px;line-height:18px}.dcu-wb-tip-row{display:flex;align-items:center;gap:6px;min-width:0;margin-top:4px;color:var(--dcu-sidebar-secondary);font-size:12px;line-height:18px}.dcu-wb-tip-row>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-wb-tip-sep{height:1px;margin:8px 0;background:var(--dcu-sidebar-border)}.dcu-wb-tip-edit{display:flex;align-items:center;gap:8px;width:100%;border:0;padding:4px 0;background:transparent;color:var(--dcu-sidebar-primary);font:12px/18px var(--dcu-font,inherit);cursor:pointer}
|
|
1363
1413
|
.dcu-wb-unread{flex:none;width:7px;height:7px;margin-left:8px;margin-right:8px;border-radius:50%;background:var(--dsw-alias-state-business-primary)}
|
|
1414
|
+
.dcu-wb-pending{display:flex;align-items:center;gap:4px;flex:none;max-width:88px;margin-left:8px;margin-right:8px;color:var(--dsw-alias-state-warn-label,#b45309);font-size:11px;line-height:16px;white-space:nowrap}.dcu-wb-pending-dot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--dsw-alias-state-warn-primary,#f59e0b)}.dcu-wb-pending-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
|
1364
1415
|
.dcu-wb-empty{padding:14px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}
|
|
1365
1416
|
.dcu-wb-error{margin:4px 0;padding:6px 8px;border-radius:6px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent);color:var(--dsw-alias-state-error-primary);font-size:12px}
|
|
1366
1417
|
.dcu-wb-rail{display:none}
|
|
@@ -1392,8 +1443,9 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1392
1443
|
function CodexWorkspaceBrowser(props) {
|
|
1393
1444
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HoverShell, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexWorkspaceTree, { ...props }) });
|
|
1394
1445
|
}
|
|
1395
|
-
function CodexWorkspaceTree({ wide, useSessions, useWorkspaces, t, archiveSession, deleteSession, deleteWorkspace, forkSession, insertSessionBefore, insertWorkspaceBefore, openPath, openSession, renameSession, renameWorkspace, startSession }) {
|
|
1446
|
+
function CodexWorkspaceTree({ wide, useSessions, useSessionPendingInteraction, useWorkspaces, t, archiveSession, deleteSession, deleteWorkspace, forkSession, insertSessionBefore, insertWorkspaceBefore, openPath, openSession, renameSession, renameWorkspace, startSession }) {
|
|
1396
1447
|
const sessions = useSessions((state) => state);
|
|
1448
|
+
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
1397
1449
|
const workspaces = useWorkspaces((state) => state);
|
|
1398
1450
|
const [expanded, setExpanded] = (0, react.useState)(() => readTreeExpansionState(storage$1(), WORKSPACE_EXPANSION_STORAGE_KEY));
|
|
1399
1451
|
const [pinnedWorkspaceIds, setPinnedWorkspaceIdsState] = (0, react.useState)(() => readPinnedWorkspaceIds(storage$1()));
|
|
@@ -1905,6 +1957,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1905
1957
|
isExpanded && shownIds.map((id) => {
|
|
1906
1958
|
const session = sessions.byId[id];
|
|
1907
1959
|
if (session === void 0) return null;
|
|
1960
|
+
const pendingInteraction = pendingInteractionForSession(id, pendingInteractions, session.pendingInteraction);
|
|
1908
1961
|
const path = session.cwd ?? workspace.path;
|
|
1909
1962
|
const selected = sessions.current === id;
|
|
1910
1963
|
const sessionMenuOpen = menu?.type === "session" && menu.id === id;
|
|
@@ -2013,13 +2066,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2013
2066
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5 2.5h6M5 2.5v2L3.75 6v1h8.5V6L11 4.5v-2M8 7v6" })
|
|
2014
2067
|
})
|
|
2015
2068
|
}),
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
}) : null,
|
|
2069
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionState, {
|
|
2070
|
+
pendingInteraction,
|
|
2071
|
+
unread: unreadSessionIds.includes(id),
|
|
2072
|
+
running: session.running === true,
|
|
2073
|
+
t
|
|
2074
|
+
}),
|
|
2023
2075
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2024
2076
|
className: "dcu-wb-quick-actions",
|
|
2025
2077
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -2318,6 +2370,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2318
2370
|
const title = session.displayTitle;
|
|
2319
2371
|
const pinned = pinnedSessionIds.includes(id);
|
|
2320
2372
|
const unread = unreadSessionIds.includes(id);
|
|
2373
|
+
const pendingInteraction = pendingInteractionForSession(id, pendingInteractions, session.pendingInteraction);
|
|
2321
2374
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
2322
2375
|
id,
|
|
2323
2376
|
title,
|
|
@@ -2326,6 +2379,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2326
2379
|
pinned,
|
|
2327
2380
|
unread,
|
|
2328
2381
|
running: session.running === true,
|
|
2382
|
+
pendingInteraction,
|
|
2329
2383
|
t,
|
|
2330
2384
|
menuItems: sessionMenu(id, title, session.cwd),
|
|
2331
2385
|
draggable: true,
|
|
@@ -2823,8 +2877,9 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2823
2877
|
})
|
|
2824
2878
|
});
|
|
2825
2879
|
}
|
|
2826
|
-
function ChannelBrowserTree({ openSession, archiveSession, deleteSession, forkSession, renameSession, useSessions, t, menu, setMenu }) {
|
|
2880
|
+
function ChannelBrowserTree({ openSession, archiveSession, deleteSession, forkSession, renameSession, useSessions, useSessionPendingInteraction, t, menu, setMenu }) {
|
|
2827
2881
|
const sessions = useSessions((state) => state);
|
|
2882
|
+
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
2828
2883
|
const [groups, setGroups] = (0, react.useState)([]);
|
|
2829
2884
|
const [pollError, setPollError] = (0, react.useState)();
|
|
2830
2885
|
const [expanded, setExpanded] = (0, react.useState)(() => readTreeExpansionState(browserStorage(), CHANNEL_EXPANSION_STORAGE_KEY));
|
|
@@ -2922,6 +2977,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2922
2977
|
const updatedAt = session.updatedAt ?? sessions.byId[id]?.updatedAt;
|
|
2923
2978
|
const pinned = flags.pinnedSessionIds.includes(id);
|
|
2924
2979
|
const unread = flags.unreadSessionIds.includes(id);
|
|
2980
|
+
const pendingInteraction = pendingInteractionForSession(id, pendingInteractions, sessions.byId[id]?.pendingInteraction);
|
|
2925
2981
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
2926
2982
|
id,
|
|
2927
2983
|
title,
|
|
@@ -2930,6 +2986,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2930
2986
|
pinned,
|
|
2931
2987
|
unread,
|
|
2932
2988
|
running,
|
|
2989
|
+
pendingInteraction,
|
|
2933
2990
|
t,
|
|
2934
2991
|
menuItems: sessionMenuItems(t, {
|
|
2935
2992
|
pinned,
|
|
@@ -3077,8 +3134,9 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3077
3134
|
})]
|
|
3078
3135
|
});
|
|
3079
3136
|
}
|
|
3080
|
-
function ScheduleBrowserTree({ openSession, archiveSession, deleteSession, forkSession, renameSession, useSessions, useWorkspaces, t, openTaskSettings, menu, setMenu }) {
|
|
3137
|
+
function ScheduleBrowserTree({ openSession, archiveSession, deleteSession, forkSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, openTaskSettings, menu, setMenu }) {
|
|
3081
3138
|
const sessions = useSessions((state) => state);
|
|
3139
|
+
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
3082
3140
|
const workspaces = useWorkspaces((state) => state);
|
|
3083
3141
|
const [expanded, setExpanded] = (0, react.useState)(() => readTreeExpansionState(browserStorage(), SCHEDULE_EXPANSION_STORAGE_KEY));
|
|
3084
3142
|
const [groupMenu, setGroupMenu] = (0, react.useState)();
|
|
@@ -3211,6 +3269,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3211
3269
|
const title = session.title;
|
|
3212
3270
|
const pinned = flags.pinnedSessionIds.includes(id);
|
|
3213
3271
|
const unread = flags.unreadSessionIds.includes(id);
|
|
3272
|
+
const pendingInteraction = pendingInteractionForSession(id, pendingInteractions, sessions.byId[id]?.pendingInteraction);
|
|
3214
3273
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
3215
3274
|
id,
|
|
3216
3275
|
title,
|
|
@@ -3219,6 +3278,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3219
3278
|
pinned,
|
|
3220
3279
|
unread,
|
|
3221
3280
|
running: session.running,
|
|
3281
|
+
pendingInteraction,
|
|
3222
3282
|
t,
|
|
3223
3283
|
menuItems: sessionMenuItems(t, {
|
|
3224
3284
|
pinned,
|
|
@@ -3823,7 +3883,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
3823
3883
|
});
|
|
3824
3884
|
});
|
|
3825
3885
|
/** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
|
|
3826
|
-
function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useWorkspaces }) {
|
|
3886
|
+
function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces }) {
|
|
3827
3887
|
const compact = collapsed || width < 80;
|
|
3828
3888
|
const [visualCompact, setVisualCompact] = (0, react.useState)(compact);
|
|
3829
3889
|
const [collapsing, setCollapsing] = (0, react.useState)(false);
|
|
@@ -4107,6 +4167,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4107
4167
|
forkSession,
|
|
4108
4168
|
renameSession,
|
|
4109
4169
|
useSessions,
|
|
4170
|
+
useSessionPendingInteraction,
|
|
4110
4171
|
t
|
|
4111
4172
|
})
|
|
4112
4173
|
}) : imTab === "schedule" && showSchedule ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -4118,6 +4179,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4118
4179
|
forkSession,
|
|
4119
4180
|
renameSession,
|
|
4120
4181
|
useSessions,
|
|
4182
|
+
useSessionPendingInteraction,
|
|
4121
4183
|
useWorkspaces,
|
|
4122
4184
|
t,
|
|
4123
4185
|
overviewContent: scheduleOverviewSlot,
|
|
@@ -4836,6 +4898,9 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4836
4898
|
"sessions.markUnread": "标记为未读",
|
|
4837
4899
|
"sessions.markRead": "标记为已读",
|
|
4838
4900
|
"sessions.unread": "未读",
|
|
4901
|
+
"sessions.waitingAnswer": "等待回答",
|
|
4902
|
+
"sessions.waitingApproval": "等待审批",
|
|
4903
|
+
"sessions.planReview": "计划待审",
|
|
4839
4904
|
"sessions.rename": "重命名会话",
|
|
4840
4905
|
"sessions.renameDescription": "保持简短且易于识别",
|
|
4841
4906
|
"sessions.archive": "归档会话",
|
|
@@ -4976,6 +5041,9 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4976
5041
|
"sessions.markUnread": "Mark as unread",
|
|
4977
5042
|
"sessions.markRead": "Mark as read",
|
|
4978
5043
|
"sessions.unread": "Unread",
|
|
5044
|
+
"sessions.waitingAnswer": "Waiting for answer",
|
|
5045
|
+
"sessions.waitingApproval": "Waiting for approval",
|
|
5046
|
+
"sessions.planReview": "Plan awaiting review",
|
|
4979
5047
|
"sessions.rename": "Rename conversation",
|
|
4980
5048
|
"sessions.renameDescription": "Keep it short and easy to recognize.",
|
|
4981
5049
|
"sessions.archive": "Archive conversation",
|
package/dist/index.mjs
CHANGED
|
@@ -226,29 +226,6 @@ async function npmLatestVersion(packageName) {
|
|
|
226
226
|
if (isOfficialRuntimePackage(packageName)) return await npmTaggedVersion(packageName, "next") ?? await npmTaggedVersion(packageName, "latest");
|
|
227
227
|
return npmTaggedVersion(packageName, "latest");
|
|
228
228
|
}
|
|
229
|
-
function escapeRegExp(value) {
|
|
230
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
231
|
-
}
|
|
232
|
-
/** 允许写入 YAML 单引号白名单的版本:semver 及常见预发布后缀,禁止引号与空白。 */
|
|
233
|
-
function isSafeReleaseVersion(version) {
|
|
234
|
-
return /^v?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(version);
|
|
235
|
-
}
|
|
236
|
-
/** 将用户确认的精确版本合并进 Profile 的 pnpm 发布时间保护例外。 */
|
|
237
|
-
function applyReleaseExclude(source, packageName, version) {
|
|
238
|
-
if (!isSafeReleaseVersion(version)) throw new Error("npm 返回了无法识别的最新版本。");
|
|
239
|
-
const eol = source.includes("\r\n") ? "\r\n" : "\n";
|
|
240
|
-
const existing = new RegExp(`^ - '${escapeRegExp(packageName)}@([^']*)'\\s*$`, "m").exec(source);
|
|
241
|
-
if (existing !== null) {
|
|
242
|
-
const versions = existing[1].split(/\s*\|\|\s*/).map((item) => item.trim()).filter((item) => item !== "");
|
|
243
|
-
if (versions.includes(version)) return source;
|
|
244
|
-
const next = ` - '${packageName}@${[...versions, version].join(" || ")}'`;
|
|
245
|
-
return `${source.slice(0, existing.index)}${next}${source.slice(existing.index + existing[0].length)}`;
|
|
246
|
-
}
|
|
247
|
-
const entry = ` - '${packageName}@${version}'`;
|
|
248
|
-
const section = /^minimumReleaseAgeExclude:\r?\n(?:(?: |\t).*(?:\r?\n|$))*/m;
|
|
249
|
-
if (section.test(source)) return source.replace(section, (match) => `${match.endsWith("\n") ? match : `${match}${eol}`}${entry}${eol}`);
|
|
250
|
-
return `${source}${source === "" || source.endsWith("\n") ? "" : eol}minimumReleaseAgeExclude:${eol}${entry}${eol}`;
|
|
251
|
-
}
|
|
252
229
|
/**
|
|
253
230
|
* pnpm 11 会在首次解析带 install script 的传递依赖时中止并写入占位值。
|
|
254
231
|
* 这些依赖的运行时不需要 postinstall,因此在调用 DSH plugin add 之前显式
|
|
@@ -277,20 +254,6 @@ async function ensureRequiredBuildPolicies(runtime) {
|
|
|
277
254
|
const next = applyRequiredBuildPolicies(source);
|
|
278
255
|
if (next !== source) await writeFile(path, next, "utf8");
|
|
279
256
|
}
|
|
280
|
-
/** 将用户本次确认的精确版本加入 Profile 的 pnpm 发布时间保护例外。 */
|
|
281
|
-
async function ensureLatestReleaseAllowed(packageName, version, runtime) {
|
|
282
|
-
if (parseSemver(version) === void 0) throw new Error("npm 返回了无法识别的最新版本。");
|
|
283
|
-
const path = resolve(profileDirectory(runtime), "pnpm-workspace.yaml");
|
|
284
|
-
let source;
|
|
285
|
-
try {
|
|
286
|
-
source = await readFile(path, "utf8");
|
|
287
|
-
} catch (error) {
|
|
288
|
-
if (error.code !== "ENOENT") throw error;
|
|
289
|
-
source = "";
|
|
290
|
-
}
|
|
291
|
-
const next = applyReleaseExclude(source, packageName, version);
|
|
292
|
-
if (next !== source) await writeFile(path, next, "utf8");
|
|
293
|
-
}
|
|
294
257
|
function parseSemver(version) {
|
|
295
258
|
const match = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(version);
|
|
296
259
|
if (match === null) return void 0;
|
|
@@ -542,7 +505,6 @@ async function waitUntilPluginMounted(packageName, version, runtime, timeoutMs =
|
|
|
542
505
|
}
|
|
543
506
|
function pluginCommandError(stderr) {
|
|
544
507
|
const detail = stderr.replace(/\s+/g, " ").trim();
|
|
545
|
-
if (detail.includes("minimumReleaseAge") || detail.includes("Release age")) return /* @__PURE__ */ new Error("更新被 pnpm 发布时间保护拦截。请确认已写入当前版本白名单后重试。");
|
|
546
508
|
if (/EPERM|EBUSY|EACCES|unable to unlink|ERR_PNPM_LOCKED|Lock/i.test(detail)) return /* @__PURE__ */ new Error("无法覆盖正在运行的插件文件。请先完全退出桌面端,再重新打开后更新。");
|
|
547
509
|
if (/UNEXPECTED_STORE|Unexpected store location/i.test(detail)) return /* @__PURE__ */ new Error("插件目录和 pnpm 仓库不一致。请完全退出桌面端后再更新。");
|
|
548
510
|
if (/ERR_PNPM_IGNORED_BUILDS|Ignored build scripts/i.test(detail)) return /* @__PURE__ */ new Error("插件依赖的 pnpm 构建脚本策略尚未确认。请更新 Profile 的 allowBuilds 配置后重试。");
|
|
@@ -798,7 +760,6 @@ async function installDependenciesLocked(ids, requestHotUpdate, runtime) {
|
|
|
798
760
|
const remove = [...new Set(targets.flatMap((target) => pluginsToRemoveBeforeInstall(declared, target.packageName)))];
|
|
799
761
|
await ensureRequiredBuildPolicies(runtime);
|
|
800
762
|
for (const target of targets) {
|
|
801
|
-
await ensureLatestReleaseAllowed(target.packageName, target.version, runtime);
|
|
802
763
|
if (!isOfficialRuntimePackage(target.packageName)) await removeUnmountedPackagePath(target.packageName, runtime);
|
|
803
764
|
await recordPendingUpdate(target.packageName, target.version, runtime);
|
|
804
765
|
}
|
|
@@ -813,6 +774,7 @@ async function installDependenciesLocked(ids, requestHotUpdate, runtime) {
|
|
|
813
774
|
for (const batch of batches) {
|
|
814
775
|
await runDshPlugin([
|
|
815
776
|
"add",
|
|
777
|
+
"--config.minimumReleaseAge=0",
|
|
816
778
|
...batch.map((target) => `${target.packageName}@${target.version}`),
|
|
817
779
|
"--registry=https://registry.npmjs.org/"
|
|
818
780
|
], runtime);
|