@michengai/dsh-codex-ui 0.2.98 → 0.2.100
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 +31 -0
- package/CHANGELOG.zh-CN.md +31 -0
- package/dist/client.js +102 -18
- package/dist/index.mjs +1 -39
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@
|
|
|
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.100 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
Companion release: `@michengai/dsh-codex-suite-installer@0.1.17`.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- 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.
|
|
14
|
+
- Aligned all three trees with the official `SessionSummary.pendingInteraction` contract, removed the unused host-store abstraction, and matched the official English status labels.
|
|
15
|
+
- Removed the package release-age guard from About-page companion installs and updates so explicitly requested versions can be installed immediately.
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
|
|
19
|
+
- Added DOM rendering coverage for pending-interaction states in all three trees using fully typed `SessionListState` and `SessionSummary` snapshots.
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
|
|
23
|
+
- The Suite Installer release workflow will resolve Codex UI `0.2.100` after this release is published.
|
|
24
|
+
|
|
25
|
+
## 0.2.99 — 2026-09-01
|
|
26
|
+
|
|
27
|
+
Companion release: `@michengai/dsh-codex-suite-installer@0.1.16`.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Restored full rendering for user question bubbles in the main conversation body so long prompts are not hidden by overflow, max-height, or multi-line clamp rules.
|
|
32
|
+
- Kept the official DSH user bubble DOM intact while applying a stable compatibility marker to newly mounted user bubbles.
|
|
33
|
+
|
|
34
|
+
### Dependencies
|
|
35
|
+
|
|
36
|
+
- The Suite Installer release workflow will resolve Codex UI `0.2.99` after this release is published.
|
|
37
|
+
|
|
7
38
|
## 0.2.98 — 2026-09-01
|
|
8
39
|
|
|
9
40
|
Companion release: `@michengai/dsh-codex-suite-installer@0.1.15`.
|
package/CHANGELOG.zh-CN.md
CHANGED
|
@@ -4,6 +4,37 @@
|
|
|
4
4
|
|
|
5
5
|
本日志记录 DSH Codex UI 及其一键安装器的最近发布;更早的变更可查看 [Git 提交历史](https://github.com/MichengAI/dsh-codex-ui/commits/main)。
|
|
6
6
|
|
|
7
|
+
## 0.2.100 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
配套版本:`@michengai/dsh-codex-suite-installer@0.1.17`。
|
|
10
|
+
|
|
11
|
+
### 修复
|
|
12
|
+
|
|
13
|
+
- 在任务、频道和定时任务树中显示等待回答、等待审批和计划待审状态,并让待处理警告优先于未读和运行中标记。
|
|
14
|
+
- 三棵树统一使用官方 `SessionSummary.pendingInteraction` 契约,删除未使用的宿主状态抽象,并对齐官方英文状态文案。
|
|
15
|
+
- 移除关于页配套插件安装与更新的发布时间保护,让用户明确请求的版本可以立即安装。
|
|
16
|
+
|
|
17
|
+
### 测试
|
|
18
|
+
|
|
19
|
+
- 使用完整类型约束的 `SessionListState` 和 `SessionSummary` 快照,为三棵树补充待处理状态 DOM 渲染测试。
|
|
20
|
+
|
|
21
|
+
### 依赖
|
|
22
|
+
|
|
23
|
+
- Suite Installer 发布 workflow 会在本版本发布后解析 Codex UI `0.2.100`。
|
|
24
|
+
|
|
25
|
+
## 0.2.99 — 2026-09-01
|
|
26
|
+
|
|
27
|
+
配套版本:`@michengai/dsh-codex-suite-installer@0.1.16`。
|
|
28
|
+
|
|
29
|
+
### 修复
|
|
30
|
+
|
|
31
|
+
- 恢复主会话正文中用户提问气泡的完整显示,避免长问题被溢出、高度上限或多行省略规则截断。
|
|
32
|
+
- 保留 DSH 官方用户气泡 DOM,只为新增用户气泡补充稳定兼容标记。
|
|
33
|
+
|
|
34
|
+
### 依赖
|
|
35
|
+
|
|
36
|
+
- Suite Installer 发布 workflow 会在本版本发布后解析 Codex UI `0.2.99`。
|
|
37
|
+
|
|
7
38
|
## 0.2.98 — 2026-09-01
|
|
8
39
|
|
|
9
40
|
配套版本:`@michengai/dsh-codex-suite-installer@0.1.15`。
|
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,16 @@ window.__ModuleLoader__.load({
|
|
|
621
654
|
});
|
|
622
655
|
}
|
|
623
656
|
//#endregion
|
|
657
|
+
//#region src/client/session-pending.ts
|
|
658
|
+
function visiblePendingKind(kind) {
|
|
659
|
+
switch (kind) {
|
|
660
|
+
case "approval":
|
|
661
|
+
case "plan-review":
|
|
662
|
+
case "question": return kind;
|
|
663
|
+
default: return;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
//#endregion
|
|
624
667
|
//#region src/client/pinned-workspaces.ts
|
|
625
668
|
/** 浏览器本地持久化键;置顶只影响本插件中的工作区分区。 */
|
|
626
669
|
const PINNED_WORKSPACES_STORAGE_KEY = "dsh-codex-ui.pinned-workspace-ids";
|
|
@@ -736,10 +779,37 @@ window.__ModuleLoader__.load({
|
|
|
736
779
|
//#region src/client/conversation-bubbles.ts
|
|
737
780
|
/** 撤回旧版 Codex 用户卡片,恢复 DSH 官方问题气泡。 */
|
|
738
781
|
const USER_BUBBLE_STYLE_ID = "dcu-user-bubble-style";
|
|
782
|
+
const USER_BUBBLE_EXPAND_STYLE_ID = "dcu-user-bubble-expand-style";
|
|
783
|
+
const USER_BUBBLE_EXPAND_STYLE = `
|
|
784
|
+
[data-time-hover-root]:not([data-turn-tail]),[data-time-hover-root]:not([data-turn-tail])>:first-child{overflow:visible!important}
|
|
785
|
+
[data-dcu-expandable-user-bubble]{max-height:none!important;overflow:visible!important;display:block!important;white-space:pre-wrap!important;overflow-wrap:anywhere!important;word-break:break-word!important;text-overflow:clip!important;-webkit-line-clamp:unset!important;-webkit-box-orient:initial!important}
|
|
786
|
+
`;
|
|
787
|
+
function ensureExpandableStyle(doc) {
|
|
788
|
+
if (doc.getElementById("dcu-user-bubble-expand-style") !== null) return;
|
|
789
|
+
const style = doc.createElement("style");
|
|
790
|
+
style.id = USER_BUBBLE_EXPAND_STYLE_ID;
|
|
791
|
+
style.textContent = USER_BUBBLE_EXPAND_STYLE;
|
|
792
|
+
doc.head.append(style);
|
|
793
|
+
}
|
|
794
|
+
function matchingElements(root, selector) {
|
|
795
|
+
const items = [...root.querySelectorAll(selector)];
|
|
796
|
+
if (root instanceof HTMLElement && root.matches(selector)) items.unshift(root);
|
|
797
|
+
return items;
|
|
798
|
+
}
|
|
799
|
+
function markExpandableUserBubbles(root) {
|
|
800
|
+
for (const row of matchingElements(root, "[data-time-hover-root]:not([data-turn-tail])")) {
|
|
801
|
+
const bubble = row.firstElementChild?.lastElementChild;
|
|
802
|
+
if (!(bubble instanceof HTMLElement) || bubble.textContent?.trim() === "") continue;
|
|
803
|
+
bubble.dataset.dcuExpandableUserBubble = "";
|
|
804
|
+
}
|
|
805
|
+
}
|
|
739
806
|
function restoreOfficialUserBubbles(root) {
|
|
740
|
-
|
|
807
|
+
const doc = "getElementById" in root ? root : root.ownerDocument;
|
|
808
|
+
doc?.getElementById(USER_BUBBLE_STYLE_ID)?.remove();
|
|
809
|
+
if (doc !== void 0 && doc !== null && doc.head !== null) ensureExpandableStyle(doc);
|
|
741
810
|
for (const card of root.querySelectorAll("[data-dcu-user-card]")) card.remove();
|
|
742
811
|
for (const source of root.querySelectorAll("[data-dcu-user-source]")) delete source.dataset.dcuUserSource;
|
|
812
|
+
markExpandableUserBubbles(root);
|
|
743
813
|
}
|
|
744
814
|
//#endregion
|
|
745
815
|
//#region src/client/conversation-header.ts
|
|
@@ -891,12 +961,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
891
961
|
style.textContent = CONVERSATION_HEADER_STYLE;
|
|
892
962
|
doc.head.append(style);
|
|
893
963
|
}
|
|
894
|
-
const CONVERSATION_DECORATION_SELECTOR = "header";
|
|
964
|
+
const CONVERSATION_DECORATION_SELECTOR = "header,[data-time-hover-root],[data-dcu-user-card],[data-dcu-user-source]";
|
|
895
965
|
function conversationDecorationMutation(records) {
|
|
896
966
|
const relevant = (node) => node instanceof Element && (node.matches(CONVERSATION_DECORATION_SELECTOR) || node.closest(CONVERSATION_DECORATION_SELECTOR) !== null || node.querySelector(CONVERSATION_DECORATION_SELECTOR) !== null);
|
|
897
967
|
return records.some((record) => relevant(record.target) || [...record.addedNodes].some(relevant) || [...record.removedNodes].some(relevant));
|
|
898
968
|
}
|
|
899
|
-
/**
|
|
969
|
+
/** 观察会话顶栏与用户气泡;只对相关子树变更按帧合并,流式回答不会触发全文档扫描。 */
|
|
900
970
|
function observeConversationHeader(doc = document) {
|
|
901
971
|
if (doc.head === null || doc.body === null) return () => {};
|
|
902
972
|
ensureStyle(doc);
|
|
@@ -910,6 +980,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
910
980
|
if (applying) return;
|
|
911
981
|
applying = true;
|
|
912
982
|
try {
|
|
983
|
+
restoreOfficialUserBubbles(doc);
|
|
913
984
|
placeConversationTabs(doc);
|
|
914
985
|
const tabs = findConversationTablist(doc);
|
|
915
986
|
if (tabs !== watchedTabs) {
|
|
@@ -1333,6 +1404,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1333
1404
|
.dcu-wb-context-anchor{opacity:0;pointer-events:none}
|
|
1334
1405
|
.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}
|
|
1335
1406
|
.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)}
|
|
1407
|
+
.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}
|
|
1336
1408
|
.dcu-wb-empty{padding:14px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}
|
|
1337
1409
|
.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}
|
|
1338
1410
|
.dcu-wb-rail{display:none}
|
|
@@ -1877,6 +1949,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1877
1949
|
isExpanded && shownIds.map((id) => {
|
|
1878
1950
|
const session = sessions.byId[id];
|
|
1879
1951
|
if (session === void 0) return null;
|
|
1952
|
+
const pendingInteraction = visiblePendingKind(session.pendingInteraction);
|
|
1880
1953
|
const path = session.cwd ?? workspace.path;
|
|
1881
1954
|
const selected = sessions.current === id;
|
|
1882
1955
|
const sessionMenuOpen = menu?.type === "session" && menu.id === id;
|
|
@@ -1985,13 +2058,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1985
2058
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M5 2.5h6M5 2.5v2L3.75 6v1h8.5V6L11 4.5v-2M8 7v6" })
|
|
1986
2059
|
})
|
|
1987
2060
|
}),
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
}) : null,
|
|
2061
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionState, {
|
|
2062
|
+
pendingInteraction,
|
|
2063
|
+
unread: unreadSessionIds.includes(id),
|
|
2064
|
+
running: session.running === true,
|
|
2065
|
+
t
|
|
2066
|
+
}),
|
|
1995
2067
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1996
2068
|
className: "dcu-wb-quick-actions",
|
|
1997
2069
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -2290,6 +2362,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2290
2362
|
const title = session.displayTitle;
|
|
2291
2363
|
const pinned = pinnedSessionIds.includes(id);
|
|
2292
2364
|
const unread = unreadSessionIds.includes(id);
|
|
2365
|
+
const pendingInteraction = visiblePendingKind(session.pendingInteraction);
|
|
2293
2366
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
2294
2367
|
id,
|
|
2295
2368
|
title,
|
|
@@ -2298,6 +2371,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2298
2371
|
pinned,
|
|
2299
2372
|
unread,
|
|
2300
2373
|
running: session.running === true,
|
|
2374
|
+
pendingInteraction,
|
|
2301
2375
|
t,
|
|
2302
2376
|
menuItems: sessionMenu(id, title, session.cwd),
|
|
2303
2377
|
draggable: true,
|
|
@@ -2894,6 +2968,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2894
2968
|
const updatedAt = session.updatedAt ?? sessions.byId[id]?.updatedAt;
|
|
2895
2969
|
const pinned = flags.pinnedSessionIds.includes(id);
|
|
2896
2970
|
const unread = flags.unreadSessionIds.includes(id);
|
|
2971
|
+
const pendingInteraction = visiblePendingKind(sessions.byId[id]?.pendingInteraction);
|
|
2897
2972
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
2898
2973
|
id,
|
|
2899
2974
|
title,
|
|
@@ -2902,6 +2977,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2902
2977
|
pinned,
|
|
2903
2978
|
unread,
|
|
2904
2979
|
running,
|
|
2980
|
+
pendingInteraction,
|
|
2905
2981
|
t,
|
|
2906
2982
|
menuItems: sessionMenuItems(t, {
|
|
2907
2983
|
pinned,
|
|
@@ -3183,6 +3259,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3183
3259
|
const title = session.title;
|
|
3184
3260
|
const pinned = flags.pinnedSessionIds.includes(id);
|
|
3185
3261
|
const unread = flags.unreadSessionIds.includes(id);
|
|
3262
|
+
const pendingInteraction = visiblePendingKind(sessions.byId[id]?.pendingInteraction);
|
|
3186
3263
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
3187
3264
|
id,
|
|
3188
3265
|
title,
|
|
@@ -3191,6 +3268,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3191
3268
|
pinned,
|
|
3192
3269
|
unread,
|
|
3193
3270
|
running: session.running,
|
|
3271
|
+
pendingInteraction,
|
|
3194
3272
|
t,
|
|
3195
3273
|
menuItems: sessionMenuItems(t, {
|
|
3196
3274
|
pinned,
|
|
@@ -4808,6 +4886,9 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4808
4886
|
"sessions.markUnread": "标记为未读",
|
|
4809
4887
|
"sessions.markRead": "标记为已读",
|
|
4810
4888
|
"sessions.unread": "未读",
|
|
4889
|
+
"sessions.waitingAnswer": "等待回答",
|
|
4890
|
+
"sessions.waitingApproval": "等待审批",
|
|
4891
|
+
"sessions.planReview": "计划待审",
|
|
4811
4892
|
"sessions.rename": "重命名会话",
|
|
4812
4893
|
"sessions.renameDescription": "保持简短且易于识别",
|
|
4813
4894
|
"sessions.archive": "归档会话",
|
|
@@ -4948,6 +5029,9 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
4948
5029
|
"sessions.markUnread": "Mark as unread",
|
|
4949
5030
|
"sessions.markRead": "Mark as read",
|
|
4950
5031
|
"sessions.unread": "Unread",
|
|
5032
|
+
"sessions.waitingAnswer": "Waiting for answer",
|
|
5033
|
+
"sessions.waitingApproval": "Waiting for approval",
|
|
5034
|
+
"sessions.planReview": "Plan awaiting review",
|
|
4951
5035
|
"sessions.rename": "Rename conversation",
|
|
4952
5036
|
"sessions.renameDescription": "Keep it short and easy to recognize.",
|
|
4953
5037
|
"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);
|