@michengai/dsh-codex-ui 1.1.11 → 1.1.12
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 +172 -26
- package/lib/session-title-plugin.mjs +8 -0
- 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.12 - 2026-09-17
|
|
8
|
+
|
|
9
|
+
- Session rows show compact relative time on the right (now, minutes, hours, days, weeks, months, years). Hover or the action menu yields to the archive shortcut; a pending label hides the inline time.
|
|
10
|
+
- Truncated session titles scroll on hover or when the menu is open. Reduced motion keeps the ellipsis.
|
|
11
|
+
- Relative times refresh every minute. Inline English uses now; hover cards use Just now.
|
|
12
|
+
|
|
13
|
+
## suite-installer-v1.0.14 - 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.11`
|
|
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.11 - 2026-09-16
|
|
8
32
|
|
|
9
33
|
- 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.
|
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.12 - 2026-09-17
|
|
8
|
+
|
|
9
|
+
- 会话行右侧显示紧凑相对时间(刚刚、分、小时、天、周、月、年)。悬停或打开菜单时让位给归档快捷图标;待处理标签优先于行内时间。
|
|
10
|
+
- 标题被截断时,悬停或打开菜单会横向滚动全文;系统减动效时保持省略号。
|
|
11
|
+
- 相对时间每分钟对齐刷新。行内英文用 now,悬停卡片用 Just now。
|
|
12
|
+
|
|
13
|
+
## suite-installer-v1.0.14 - 2026-09-16
|
|
14
|
+
|
|
15
|
+
一键维护安装 11 个自研插件。包含以下插件及版本:
|
|
16
|
+
|
|
17
|
+
- `@michengai/dsh-archive-manager@0.1.43`
|
|
18
|
+
- `@michengai/dsh-codex-ui@1.1.11`
|
|
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.11 - 2026-09-16
|
|
8
32
|
|
|
9
33
|
- 设置页和用量统计改为挂到 `document.body`。侧栏收缩后,宿主或插件若给窄轨加了 transform,全屏页不再被困在 56px 里挤成竖排。
|
package/lib/client.js
CHANGED
|
@@ -1246,6 +1246,23 @@ window.__ModuleLoader__.load({
|
|
|
1246
1246
|
return parseChannelGroups(payload, fallbackLabel);
|
|
1247
1247
|
}
|
|
1248
1248
|
//#endregion
|
|
1249
|
+
//#region src/client/session-title-scroll.ts
|
|
1250
|
+
/** 会话行只展示标题第一行,避免换行把胶囊撑高。 */
|
|
1251
|
+
function sessionTitleLine(title) {
|
|
1252
|
+
return title.split(/\r?\n/)[0] ?? title;
|
|
1253
|
+
}
|
|
1254
|
+
/** 标题比可视槽多出来的像素;1px 内当作测量误差。 */
|
|
1255
|
+
function titleOverflowPx(scrollWidth, clientWidth) {
|
|
1256
|
+
const extra = Math.ceil(scrollWidth - clientWidth);
|
|
1257
|
+
return extra > 1 ? extra : 0;
|
|
1258
|
+
}
|
|
1259
|
+
const PX_PER_SECOND = 42;
|
|
1260
|
+
/** 按溢出长度估算单程时长,长标题更慢,避免一闪而过。 */
|
|
1261
|
+
function titleScrollDurationMs(overflowPx) {
|
|
1262
|
+
if (overflowPx <= 0) return 0;
|
|
1263
|
+
return Math.min(8e3, Math.max(1600, Math.round(overflowPx / PX_PER_SECOND * 1e3)));
|
|
1264
|
+
}
|
|
1265
|
+
//#endregion
|
|
1249
1266
|
//#region src/client/session-tree.tsx
|
|
1250
1267
|
function PinIcon() {
|
|
1251
1268
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pin, {
|
|
@@ -1416,7 +1433,58 @@ window.__ModuleLoader__.load({
|
|
|
1416
1433
|
});
|
|
1417
1434
|
return null;
|
|
1418
1435
|
}
|
|
1419
|
-
function
|
|
1436
|
+
function SessionTime({ time }) {
|
|
1437
|
+
if (time === void 0 || time === "") return null;
|
|
1438
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1439
|
+
className: "dcu-wb-session-time",
|
|
1440
|
+
children: time
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
function SessionRowTitle({ title }) {
|
|
1444
|
+
const text = sessionTitleLine(title);
|
|
1445
|
+
const wrapRef = (0, react.useRef)(null);
|
|
1446
|
+
const textRef = (0, react.useRef)(null);
|
|
1447
|
+
const [shift, setShift] = (0, react.useState)(0);
|
|
1448
|
+
(0, react.useLayoutEffect)(() => {
|
|
1449
|
+
const wrap = wrapRef.current;
|
|
1450
|
+
const inner = textRef.current;
|
|
1451
|
+
if (wrap === null || inner === null) return;
|
|
1452
|
+
const measure = () => {
|
|
1453
|
+
setShift(titleOverflowPx(inner.scrollWidth, wrap.clientWidth));
|
|
1454
|
+
};
|
|
1455
|
+
measure();
|
|
1456
|
+
let cancelled = false;
|
|
1457
|
+
const fonts = typeof document === "undefined" ? void 0 : document.fonts;
|
|
1458
|
+
if (fonts !== void 0) fonts.ready.then(() => {
|
|
1459
|
+
if (!cancelled) measure();
|
|
1460
|
+
});
|
|
1461
|
+
if (typeof ResizeObserver === "undefined") return () => {
|
|
1462
|
+
cancelled = true;
|
|
1463
|
+
};
|
|
1464
|
+
const observer = new ResizeObserver(measure);
|
|
1465
|
+
observer.observe(wrap);
|
|
1466
|
+
return () => {
|
|
1467
|
+
cancelled = true;
|
|
1468
|
+
observer.disconnect();
|
|
1469
|
+
};
|
|
1470
|
+
}, [text]);
|
|
1471
|
+
const style = shift > 0 ? {
|
|
1472
|
+
"--dcu-title-shift": `${shift}px`,
|
|
1473
|
+
"--dcu-title-duration": `${titleScrollDurationMs(shift)}ms`
|
|
1474
|
+
} : void 0;
|
|
1475
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1476
|
+
ref: wrapRef,
|
|
1477
|
+
className: "dcu-wb-session-title",
|
|
1478
|
+
"data-overflow": shift > 0 || void 0,
|
|
1479
|
+
style,
|
|
1480
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1481
|
+
ref: textRef,
|
|
1482
|
+
className: "dcu-wb-session-title-text",
|
|
1483
|
+
children: text
|
|
1484
|
+
})
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
function SessionRow({ id, title, selected, menuOpen, unread, running, pendingInteraction, t, menuItems, onOpen, onMenuChange, onSelectAction, onArchive, onHover, onLeave, onContextMenu, menuPoint, subtitle, flat, draggable, dropActive, onDragStart, onDragEnd, onDragOver, onDrop, time }) {
|
|
1420
1488
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1421
1489
|
"data-dcu-session": id,
|
|
1422
1490
|
className: `dcu-wb-session${selected ? " dcu-wb-selected" : ""}${menuOpen ? " dcu-wb-menu-open" : ""}${dropActive === true ? " dcu-wb-drop" : ""}${flat === true ? " dcu-wb-session-flat" : ""}`,
|
|
@@ -1434,23 +1502,18 @@ window.__ModuleLoader__.load({
|
|
|
1434
1502
|
children: [
|
|
1435
1503
|
subtitle !== void 0 && subtitle !== "" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1436
1504
|
className: "dcu-wb-session-copy",
|
|
1437
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1438
|
-
className: "dcu-wb-session-title",
|
|
1439
|
-
children: title.split(/\r?\n/)[0] ?? title
|
|
1440
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1505
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRowTitle, { title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1441
1506
|
className: "dcu-wb-session-sub",
|
|
1442
1507
|
children: subtitle
|
|
1443
1508
|
})]
|
|
1444
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1445
|
-
className: "dcu-wb-session-title",
|
|
1446
|
-
children: title.split(/\r?\n/)[0] ?? title
|
|
1447
|
-
}),
|
|
1509
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRowTitle, { title }),
|
|
1448
1510
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionState, {
|
|
1449
1511
|
pendingInteraction,
|
|
1450
1512
|
unread,
|
|
1451
1513
|
running,
|
|
1452
1514
|
t
|
|
1453
1515
|
}),
|
|
1516
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionTime, { time }),
|
|
1454
1517
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1455
1518
|
className: "dcu-wb-quick-actions",
|
|
1456
1519
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1915,13 +1978,84 @@ window.__ModuleLoader__.load({
|
|
|
1915
1978
|
top: rect.top
|
|
1916
1979
|
};
|
|
1917
1980
|
}
|
|
1918
|
-
|
|
1981
|
+
const HOUR = 3600;
|
|
1982
|
+
const DAY = HOUR * 24;
|
|
1983
|
+
const WEEK = DAY * 7;
|
|
1984
|
+
const MONTH = DAY * 30;
|
|
1985
|
+
const YEAR = DAY * 365;
|
|
1986
|
+
function formatRelativeTime(updatedAt, t, now, justNow) {
|
|
1987
|
+
const seconds = Math.max(0, Math.floor((now - updatedAt) / 1e3));
|
|
1988
|
+
if (seconds < 60) return t(justNow);
|
|
1989
|
+
if (seconds < HOUR) return t("time.minutes", { count: Math.floor(seconds / 60) });
|
|
1990
|
+
if (seconds < DAY) return t("time.hours", { count: Math.floor(seconds / HOUR) });
|
|
1991
|
+
if (seconds < WEEK) return t("time.days", { count: Math.floor(seconds / DAY) });
|
|
1992
|
+
if (seconds < MONTH) return t("time.weeks", { count: Math.floor(seconds / WEEK) });
|
|
1993
|
+
if (seconds < YEAR) return t("time.months", { count: Math.floor(seconds / MONTH) });
|
|
1994
|
+
return t("time.years", { count: Math.floor(seconds / YEAR) });
|
|
1995
|
+
}
|
|
1996
|
+
/** 悬停卡片右上角。分档与 ChatGPT `$wa` 一致;英文刚刚用 Just now。 */
|
|
1919
1997
|
function formatHoverTime(updatedAt, t, now = Date.now()) {
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
return
|
|
1998
|
+
return formatRelativeTime(updatedAt, t, now, "time.justNow");
|
|
1999
|
+
}
|
|
2000
|
+
/** 会话行右侧。分档相同;英文刚刚用 now,避免挤占标题。 */
|
|
2001
|
+
function formatCompactTime(updatedAt, t, now = Date.now()) {
|
|
2002
|
+
return formatRelativeTime(updatedAt, t, now, "time.justNowShort");
|
|
2003
|
+
}
|
|
2004
|
+
//#endregion
|
|
2005
|
+
//#region src/client/shared-now.ts
|
|
2006
|
+
const SHARED_NOW_INTERVAL_MS = 6e4;
|
|
2007
|
+
/** 对齐到下一个整档,避免「刚刚」在整分钟边界之后还多停将近一轮。 */
|
|
2008
|
+
function msUntilNextNowTick(now, intervalMs = SHARED_NOW_INTERVAL_MS) {
|
|
2009
|
+
const remainder = now % intervalMs;
|
|
2010
|
+
return remainder === 0 ? intervalMs : intervalMs - remainder;
|
|
2011
|
+
}
|
|
2012
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2013
|
+
let sharedNow = Date.now();
|
|
2014
|
+
let timeoutId = 0;
|
|
2015
|
+
let intervalId = 0;
|
|
2016
|
+
let cancelled = true;
|
|
2017
|
+
function publish(now) {
|
|
2018
|
+
sharedNow = now;
|
|
2019
|
+
for (const listener of listeners) listener();
|
|
2020
|
+
}
|
|
2021
|
+
function startClock() {
|
|
2022
|
+
cancelled = false;
|
|
2023
|
+
timeoutId = window.setTimeout(() => {
|
|
2024
|
+
if (cancelled) return;
|
|
2025
|
+
publish(Date.now());
|
|
2026
|
+
intervalId = window.setInterval(() => {
|
|
2027
|
+
publish(Date.now());
|
|
2028
|
+
}, SHARED_NOW_INTERVAL_MS);
|
|
2029
|
+
if (cancelled) {
|
|
2030
|
+
window.clearInterval(intervalId);
|
|
2031
|
+
intervalId = 0;
|
|
2032
|
+
}
|
|
2033
|
+
}, msUntilNextNowTick(Date.now()));
|
|
2034
|
+
}
|
|
2035
|
+
function stopClock() {
|
|
2036
|
+
cancelled = true;
|
|
2037
|
+
window.clearTimeout(timeoutId);
|
|
2038
|
+
window.clearInterval(intervalId);
|
|
2039
|
+
timeoutId = 0;
|
|
2040
|
+
intervalId = 0;
|
|
2041
|
+
}
|
|
2042
|
+
function subscribe(listener) {
|
|
2043
|
+
if (listeners.size === 0) {
|
|
2044
|
+
sharedNow = Date.now();
|
|
2045
|
+
startClock();
|
|
2046
|
+
}
|
|
2047
|
+
listeners.add(listener);
|
|
2048
|
+
return () => {
|
|
2049
|
+
listeners.delete(listener);
|
|
2050
|
+
if (listeners.size === 0) stopClock();
|
|
2051
|
+
};
|
|
2052
|
+
}
|
|
2053
|
+
function getSnapshot() {
|
|
2054
|
+
return sharedNow;
|
|
2055
|
+
}
|
|
2056
|
+
/** 模块级当前时刻。几棵树挂着都只走一套定时器,每分钟刷新一次。 */
|
|
2057
|
+
function useSharedNow() {
|
|
2058
|
+
return (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
1925
2059
|
}
|
|
1926
2060
|
//#endregion
|
|
1927
2061
|
//#region src/client/conversation-bubbles.ts
|
|
@@ -2901,7 +3035,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2901
3035
|
}
|
|
2902
3036
|
const previewTitle = document.createElement("span");
|
|
2903
3037
|
previewTitle.className = "dcu-wb-drag-ghost-title";
|
|
2904
|
-
previewTitle.textContent = title
|
|
3038
|
+
previewTitle.textContent = sessionTitleLine(title);
|
|
2905
3039
|
preview.appendChild(previewTitle);
|
|
2906
3040
|
document.body.appendChild(preview);
|
|
2907
3041
|
preview.offsetWidth;
|
|
@@ -3016,11 +3150,11 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3016
3150
|
.dcu-wb-project-title,.dcu-wb-session-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px}
|
|
3017
3151
|
.dcu-wb-project-title{flex:1;font-weight:400;color:var(--dcu-sidebar-primary)}
|
|
3018
3152
|
.dcu-wb-session{position:relative;min-width:0;min-height:30px;gap:0;overflow:hidden;padding-left:30px;padding-right:28px}
|
|
3019
|
-
.dcu-wb-session-title{flex:1;margin-left:0}.dcu-wb-session-copy{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.dcu-wb-session-sub{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:16px}.dcu-wb-session-flat,.dcu-wb-session-top{padding-left:8px}.dcu-wb-session-flat:has(.dcu-wb-running),.dcu-wb-session-top:has(.dcu-wb-running){padding-left:30px}
|
|
3153
|
+
.dcu-wb-session-title{flex:1;margin-left:0}.dcu-wb-session-title-text{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media (prefers-reduced-motion:no-preference){.dcu-wb-session:hover .dcu-wb-session-title[data-overflow] .dcu-wb-session-title-text,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-session-title[data-overflow] .dcu-wb-session-title-text{display:inline-block;width:max-content;max-width:none;overflow:visible;text-overflow:clip;animation:dcu-wb-title-scroll var(--dcu-title-duration,2.4s) linear 320ms infinite alternate}}@keyframes dcu-wb-title-scroll{0%,18%{transform:translateX(0)}82%,100%{transform:translateX(calc(-1 * var(--dcu-title-shift,0px)))}}.dcu-wb-session-time{position:absolute;right:8px;top:50%;transform:translateY(-50%);color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:18px;font-weight:400;font-variant-numeric:tabular-nums;white-space:nowrap;pointer-events:none}.dcu-wb-session:has(.dcu-wb-session-time){padding-right:64px}.dcu-wb-session:has(.dcu-wb-unread) .dcu-wb-session-time{right:22px}.dcu-wb-session:has(.dcu-wb-unread):has(.dcu-wb-session-time){padding-right:78px}.dcu-wb-session-copy{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.dcu-wb-session-sub{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:16px}.dcu-wb-session-flat,.dcu-wb-session-top{padding-left:8px}.dcu-wb-session-flat:has(.dcu-wb-running),.dcu-wb-session-top:has(.dcu-wb-running){padding-left:30px}
|
|
3020
3154
|
.dcu-wb-actions{display:none;align-items:center;gap:8px;flex:none}
|
|
3021
3155
|
.dcu-wb-quick-actions{position:absolute;right:8px;top:50%;display:flex;align-items:center;gap:2px;opacity:0;pointer-events:none;transform:translateY(-50%);background:var(--dcu-sidebar-hover);border-radius:6px}
|
|
3022
3156
|
.dcu-wb-project-head:hover .dcu-wb-actions,.dcu-wb-project-head.dcu-wb-menu-open .dcu-wb-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-actions{display:flex}
|
|
3023
|
-
.dcu-wb-session:hover .dcu-wb-quick-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-quick-actions{opacity:1;pointer-events:auto}.dcu-wb-session:hover .dcu-wb-pending,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-pending,.dcu-wb-session:hover .dcu-wb-unread,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-unread{visibility:hidden}
|
|
3157
|
+
.dcu-wb-session:hover .dcu-wb-quick-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-quick-actions{opacity:1;pointer-events:auto}.dcu-wb-session:hover .dcu-wb-pending,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-pending,.dcu-wb-session:hover .dcu-wb-unread,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-unread,.dcu-wb-session:hover .dcu-wb-session-time,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-session-time{visibility:hidden}.dcu-wb-session:has(.dcu-wb-pending) .dcu-wb-session-time{display:none}
|
|
3024
3158
|
.dcu-wb-more{display:grid;place-items:center;width:20px;height:20px;border:0;border-radius:4px;padding:0;background:transparent;color:var(--dcu-sidebar-tertiary);cursor:pointer}
|
|
3025
3159
|
.dcu-wb-more:hover{color:var(--dcu-sidebar-primary)}
|
|
3026
3160
|
.dcu-wb-context-anchor{opacity:0;pointer-events:none}
|
|
@@ -3091,6 +3225,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3091
3225
|
}
|
|
3092
3226
|
function CodexWorkspaceTree({ wide, useSessions, useSessionPendingInteraction, useWorkspaces, t, archiveSession, deleteSession, deleteWorkspace, forkSession, insertSessionBefore, insertWorkspaceBefore, moveSession, openPath, openSession, renameSession, renameWorkspace, startSession, canDeleteSession }) {
|
|
3093
3227
|
const sessions = useSessions((state) => state);
|
|
3228
|
+
const now = useSharedNow();
|
|
3094
3229
|
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
3095
3230
|
const workspaces = useWorkspaces((state) => state);
|
|
3096
3231
|
const baselinesReady = workspaceBaselinesReady(workspaces, sessions);
|
|
@@ -3951,23 +4086,21 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
3951
4086
|
project: workspace.title,
|
|
3952
4087
|
path,
|
|
3953
4088
|
branch,
|
|
3954
|
-
time: formatHoverTime(session.updatedAt, t),
|
|
4089
|
+
time: formatHoverTime(session.updatedAt, t, now),
|
|
3955
4090
|
left: box.left,
|
|
3956
4091
|
top: box.top
|
|
3957
4092
|
});
|
|
3958
4093
|
},
|
|
3959
4094
|
onMouseLeave: hideTip,
|
|
3960
4095
|
children: [
|
|
3961
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3962
|
-
className: "dcu-wb-session-title",
|
|
3963
|
-
children: session.displayTitle.split(/\r?\n/)[0] ?? session.displayTitle
|
|
3964
|
-
}),
|
|
4096
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRowTitle, { title: session.displayTitle }),
|
|
3965
4097
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionState, {
|
|
3966
4098
|
pendingInteraction,
|
|
3967
4099
|
unread: unreadSessionIds.includes(id),
|
|
3968
4100
|
running: session.running === true,
|
|
3969
4101
|
t
|
|
3970
4102
|
}),
|
|
4103
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionTime, { time: formatCompactTime(session.updatedAt, t, now) }),
|
|
3971
4104
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3972
4105
|
className: "dcu-wb-quick-actions",
|
|
3973
4106
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -4724,6 +4857,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4724
4857
|
unread,
|
|
4725
4858
|
running: session.running === true,
|
|
4726
4859
|
pendingInteraction,
|
|
4860
|
+
time: formatCompactTime(session.updatedAt, t, now),
|
|
4727
4861
|
t,
|
|
4728
4862
|
menuItems: sessionMenu(id, session.cwd),
|
|
4729
4863
|
draggable: true,
|
|
@@ -4769,7 +4903,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4769
4903
|
kind: "session",
|
|
4770
4904
|
id,
|
|
4771
4905
|
title,
|
|
4772
|
-
time: formatHoverTime(session.updatedAt, t),
|
|
4906
|
+
time: formatHoverTime(session.updatedAt, t, now),
|
|
4773
4907
|
left: box.left,
|
|
4774
4908
|
top: box.top
|
|
4775
4909
|
});
|
|
@@ -5418,6 +5552,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5418
5552
|
}
|
|
5419
5553
|
function ChannelBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, canDeleteSession, menu, setMenu }) {
|
|
5420
5554
|
const sessions = useSessions((state) => state);
|
|
5555
|
+
const now = useSharedNow();
|
|
5421
5556
|
const workspaces = useWorkspaces?.((state) => state);
|
|
5422
5557
|
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
5423
5558
|
const [groups, setGroups] = (0, react.useState)([]);
|
|
@@ -5537,6 +5672,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5537
5672
|
unread,
|
|
5538
5673
|
running,
|
|
5539
5674
|
pendingInteraction,
|
|
5675
|
+
time: updatedAt === void 0 ? void 0 : formatCompactTime(updatedAt, t, now),
|
|
5540
5676
|
t,
|
|
5541
5677
|
menuItems: sessionMenuItems(t, {
|
|
5542
5678
|
unread,
|
|
@@ -5562,7 +5698,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5562
5698
|
showTip({
|
|
5563
5699
|
title,
|
|
5564
5700
|
project: label,
|
|
5565
|
-
time: updatedAt === void 0 ? void 0 : formatHoverTime(updatedAt, t),
|
|
5701
|
+
time: updatedAt === void 0 ? void 0 : formatHoverTime(updatedAt, t, now),
|
|
5566
5702
|
left: box.left,
|
|
5567
5703
|
top: box.top
|
|
5568
5704
|
});
|
|
@@ -5692,6 +5828,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5692
5828
|
}
|
|
5693
5829
|
function ScheduleBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, canDeleteSession, openTaskSettings, menu, setMenu }) {
|
|
5694
5830
|
const sessions = useSessions((state) => state);
|
|
5831
|
+
const now = useSharedNow();
|
|
5695
5832
|
const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
|
|
5696
5833
|
const workspaces = useWorkspaces((state) => state);
|
|
5697
5834
|
const [expanded, setExpanded] = (0, react.useState)(() => readTreeExpansionState(browserStorage(), SCHEDULE_EXPANSION_STORAGE_KEY));
|
|
@@ -5841,6 +5978,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5841
5978
|
unread,
|
|
5842
5979
|
running: session.running,
|
|
5843
5980
|
pendingInteraction,
|
|
5981
|
+
time: session.updatedAt === void 0 ? void 0 : formatCompactTime(session.updatedAt, t, now),
|
|
5844
5982
|
t,
|
|
5845
5983
|
menuItems: sessionMenuItems(t, {
|
|
5846
5984
|
unread,
|
|
@@ -5866,7 +6004,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
5866
6004
|
showTip({
|
|
5867
6005
|
title,
|
|
5868
6006
|
project: group.label,
|
|
5869
|
-
time: session.updatedAt === void 0 ? void 0 : formatHoverTime(session.updatedAt, t),
|
|
6007
|
+
time: session.updatedAt === void 0 ? void 0 : formatHoverTime(session.updatedAt, t, now),
|
|
5870
6008
|
left: box.left,
|
|
5871
6009
|
top: box.top
|
|
5872
6010
|
});
|
|
@@ -8284,9 +8422,13 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
8284
8422
|
"turns.untitled": "未命名提问",
|
|
8285
8423
|
"turns.jump": "跳转到第 {index} 轮:{summary}",
|
|
8286
8424
|
"time.justNow": "刚刚",
|
|
8425
|
+
"time.justNowShort": "刚刚",
|
|
8287
8426
|
"time.minutes": "{count}分",
|
|
8288
8427
|
"time.hours": "{count}小时",
|
|
8289
8428
|
"time.days": "{count}天",
|
|
8429
|
+
"time.weeks": "{count}周",
|
|
8430
|
+
"time.months": "{count}个月",
|
|
8431
|
+
"time.years": "{count}年",
|
|
8290
8432
|
"errors.unauthorized": "请先登录 DSH,再重试。",
|
|
8291
8433
|
"errors.forbidden": "请求被安全检查拒绝,请从可信的 DSH 地址重试。",
|
|
8292
8434
|
"errors.serviceUnavailable": "服务暂不可用,请稍后重试。",
|
|
@@ -8568,9 +8710,13 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
|
|
|
8568
8710
|
"turns.untitled": "Untitled prompt",
|
|
8569
8711
|
"turns.jump": "Jump to turn {index}: {summary}",
|
|
8570
8712
|
"time.justNow": "Just now",
|
|
8713
|
+
"time.justNowShort": "now",
|
|
8571
8714
|
"time.minutes": "{count}m",
|
|
8572
8715
|
"time.hours": "{count}h",
|
|
8573
8716
|
"time.days": "{count}d",
|
|
8717
|
+
"time.weeks": "{count}w",
|
|
8718
|
+
"time.months": "{count}mo",
|
|
8719
|
+
"time.years": "{count}y",
|
|
8574
8720
|
"errors.unauthorized": "Sign in to DSH, then try again.",
|
|
8575
8721
|
"errors.forbidden": "The security check rejected this request. Try again from a trusted DSH address.",
|
|
8576
8722
|
"errors.serviceUnavailable": "The service is unavailable. Try again later.",
|
|
@@ -259,9 +259,13 @@ const zh = {
|
|
|
259
259
|
"turns.untitled": "未命名提问",
|
|
260
260
|
"turns.jump": "跳转到第 {index} 轮:{summary}",
|
|
261
261
|
"time.justNow": "刚刚",
|
|
262
|
+
"time.justNowShort": "刚刚",
|
|
262
263
|
"time.minutes": "{count}分",
|
|
263
264
|
"time.hours": "{count}小时",
|
|
264
265
|
"time.days": "{count}天",
|
|
266
|
+
"time.weeks": "{count}周",
|
|
267
|
+
"time.months": "{count}个月",
|
|
268
|
+
"time.years": "{count}年",
|
|
265
269
|
"errors.unauthorized": "请先登录 DSH,再重试。",
|
|
266
270
|
"errors.forbidden": "请求被安全检查拒绝,请从可信的 DSH 地址重试。",
|
|
267
271
|
"errors.serviceUnavailable": "服务暂不可用,请稍后重试。",
|
|
@@ -543,9 +547,13 @@ const en = {
|
|
|
543
547
|
"turns.untitled": "Untitled prompt",
|
|
544
548
|
"turns.jump": "Jump to turn {index}: {summary}",
|
|
545
549
|
"time.justNow": "Just now",
|
|
550
|
+
"time.justNowShort": "now",
|
|
546
551
|
"time.minutes": "{count}m",
|
|
547
552
|
"time.hours": "{count}h",
|
|
548
553
|
"time.days": "{count}d",
|
|
554
|
+
"time.weeks": "{count}w",
|
|
555
|
+
"time.months": "{count}mo",
|
|
556
|
+
"time.years": "{count}y",
|
|
549
557
|
"errors.unauthorized": "Sign in to DSH, then try again.",
|
|
550
558
|
"errors.forbidden": "The security check rejected this request. Try again from a trusted DSH address.",
|
|
551
559
|
"errors.serviceUnavailable": "The service is unavailable. Try again later.",
|