@logictan/dsh-easyrewrite 2.5.4 → 2.6.0
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/README.en.md +1 -1
- package/README.ja.md +1 -1
- package/README.md +4 -4
- package/lib/client.js +177 -64
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
Click your own message bubble to edit it in place; hit the recall button beside copy to withdraw it and everything after it. Nothing is ever really changed until you commit — the conversation, the model context, and the session log stay untouched until you press **Confirm** (rewrite) or **Send** (recall).
|
|
20
20
|
|
|
21
|
-
> Compatible with DeepSeek Harness Web (**
|
|
21
|
+
> Compatible with DeepSeek Harness Web (**v2.6.0 fully supports both dsh 0.1.7-rc.1+ and 0.1.2-rc.1+**; users on dsh 0.1.1-rc.2 and older hosts, please stay on **2.3.1** — the final release of that line, fully functional, no further features). Built on official extension points only — no source patches.
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
package/README.ja.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
自分のメッセージバブルをクリックすればその場で編集、コピーキーの隣の撤回キーでそのメッセージと以降の内容をすべて撤回できます。**すべての変更はあなたが本当に確認した後にのみ発生します**——「確定」(編集)または「送信」(撤回)を押すまでは、会話・モデルコンテキスト・セッションログは一切変わりません。
|
|
20
20
|
|
|
21
|
-
> DeepSeek Harness Web(**
|
|
21
|
+
> DeepSeek Harness Web(**v2.6.0 は dsh 0.1.7-rc.1+ および 0.1.2-rc.1+ に両対応**。0.1.1-rc.2 以前のホストのユーザーは **2.3.1** に留まってください——このラインの最終版で、機能は完全に動作しますが新機能は追加されません)対応。公式拡張ポイントのみを使用し、DSH ソースコードは変更しません。
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
package/README.md
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
`#dsh` `#deepseek-harness` `#撤回` `#气泡编辑` `#重编辑` `#版本翻页器` `#i18n` `#多语言`
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**在 DeepSeek Harness Web 里内联编辑与撤回你自己的消息——惰性、无痕、零丢失。**
|
|
15
|
+
**在 DeepSeek Harness Web 里使用撤回键和气泡编辑功能轻松编辑已发出的消息——轻量、原版风格、惰性、无痕、数据任何情况下0丢失。保护您修改过程中的每一份灵感。**
|
|
18
16
|
|
|
19
17
|
单击自己的消息气泡即可原位编辑;点击复制键旁的撤回键可撤回该消息及其后的全部内容。**一切修改都发生在你真正确认之后**——在按下「确定」(编辑)或「发送」(撤回)之前,对话、模型上下文、会话日志纹丝不动。
|
|
20
18
|
|
|
21
|
-
> 兼容 DeepSeek Harness Web(**
|
|
19
|
+
> 兼容 DeepSeek Harness Web(**v2.6.0 全面适配 dsh 0.1.7-rc.1+ 与 0.1.2-rc.1+ 双代版本**;0.1.1-rc.2 及更早宿主用户请停留 **2.3.1**——该线最终版,功能完整可用,仅不再追加新功能)。纯官方扩展点实现,不改 DSH 源码。
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
package/lib/client.js
CHANGED
|
@@ -11,6 +11,31 @@ window.__ModuleLoader__.load({
|
|
|
11
11
|
var React = require("react");
|
|
12
12
|
var Primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* 取第一个可用的图标导出。
|
|
16
|
+
*
|
|
17
|
+
* dsh 0.1.7 重排了图标导出名:名字里的数字从**尺寸**改成了**字重**
|
|
18
|
+
* (IconCheckOutline16 → IconCheckOutlineRegular;尺寸仍由 size prop 控制,
|
|
19
|
+
* 各字形的默认绘制尺寸没变)。旧名在新版解析为 undefined,而
|
|
20
|
+
* React.createElement(undefined) 会抛 #130 —— 崩的是整个
|
|
21
|
+
* conversation.chat.node 槽条目,不是"少一个图标":撤回按钮会连同气泡一起消失。
|
|
22
|
+
*
|
|
23
|
+
* 所以两种写法都取:先旧名,保住 0.1.5 及以下;再新名,让 0.1.7 起恢复。
|
|
24
|
+
* 都取不到时退回空组件而不是 undefined —— 图标缺失只该少一个 glyph,
|
|
25
|
+
* 不该把整个气泡拖崩。
|
|
26
|
+
*/
|
|
27
|
+
function pickIcon() {
|
|
28
|
+
for (var i = 0; i < arguments.length; i++) {
|
|
29
|
+
if (arguments[i]) return arguments[i];
|
|
30
|
+
}
|
|
31
|
+
return function EmptyIcon() { return null; };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var IconCheckOutline = pickIcon(Primitives.IconCheckOutline16, Primitives.IconCheckOutlineRegular);
|
|
35
|
+
var IconCopyOutline = pickIcon(Primitives.IconCopyOutline16, Primitives.IconCopyOutlineRegular);
|
|
36
|
+
var IconChevronLeftOutline = pickIcon(Primitives.IconChevronLeftOutline14, Primitives.IconChevronLeftOutlineRegular);
|
|
37
|
+
var IconChevronRightOutline = pickIcon(Primitives.IconChevronRightOutline14, Primitives.IconChevronRightOutlineRegular);
|
|
38
|
+
|
|
14
39
|
var NS = "dsh-easyrewrite";
|
|
15
40
|
|
|
16
41
|
/** 统一日志:默认静默(仅上报 host 落盘);调试模式(localStorage dsh-easyrewrite:debug=1)时打印控制台。 */
|
|
@@ -422,7 +447,7 @@ window.__ModuleLoader__.load({
|
|
|
422
447
|
|
|
423
448
|
// ---------- dsh 宿主版本比较(v2.4.0) ----------
|
|
424
449
|
var MIN_DSH_VERSION = "0.1.2-rc.1";
|
|
425
|
-
var MAX_TESTED_DSH_VERSION = "0.1.
|
|
450
|
+
var MAX_TESTED_DSH_VERSION = "0.1.7-rc.2";
|
|
426
451
|
function dshVerRank(v) {
|
|
427
452
|
var m = String(v || "").trim().match(/^(\d+)\.(\d+)\.(\d+)(?:-(alpha|rc)\.(\d+))?$/);
|
|
428
453
|
if (!m) return null;
|
|
@@ -560,22 +585,31 @@ window.__ModuleLoader__.load({
|
|
|
560
585
|
|
|
561
586
|
/** 安全打开会话:多重降级通道,确保可靠切换会话 */
|
|
562
587
|
function safeOpenSession(targetId, props) {
|
|
588
|
+
if (props && typeof props.openSession === "function") {
|
|
589
|
+
try {
|
|
590
|
+
var r1 = props.openSession(targetId);
|
|
591
|
+
if (r1 !== false) return true;
|
|
592
|
+
} catch (e1) {
|
|
593
|
+
log("warn", "session", "props.openSession 失败,尝试降级通道", { targetId: targetId, err: String(e1 && e1.message ? e1.message : e1) });
|
|
594
|
+
}
|
|
595
|
+
}
|
|
563
596
|
try {
|
|
564
|
-
if (
|
|
565
|
-
|
|
597
|
+
if (ctxUiWorkspaceRef && typeof ctxUiWorkspaceRef.openSession === "function") {
|
|
598
|
+
ctxUiWorkspaceRef.openSession(targetId);
|
|
566
599
|
return true;
|
|
567
600
|
}
|
|
601
|
+
} catch (e2) {
|
|
602
|
+
log("warn", "session", "ctxUiWorkspaceRef.openSession 失败", { targetId: targetId, err: String(e2 && e2.message ? e2.message : e2) });
|
|
603
|
+
}
|
|
604
|
+
try {
|
|
568
605
|
if (props && props.ctxSessions && typeof props.ctxSessions.open === "function") {
|
|
569
606
|
props.ctxSessions.open(targetId);
|
|
570
607
|
return true;
|
|
571
608
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
return true;
|
|
575
|
-
}
|
|
576
|
-
} catch (e) {
|
|
577
|
-
log("error", "session", "切换会话异常", { targetId: targetId, err: String(e && e.message ? e.message : e) });
|
|
609
|
+
} catch (e3) {
|
|
610
|
+
log("warn", "session", "ctxSessions.open 失败", { targetId: targetId, err: String(e3 && e3.message ? e3.message : e3) });
|
|
578
611
|
}
|
|
612
|
+
log("error", "session", "所有切换会话通道均不可用", { targetId: targetId });
|
|
579
613
|
return false;
|
|
580
614
|
}
|
|
581
615
|
|
|
@@ -1506,7 +1540,6 @@ window.__ModuleLoader__.load({
|
|
|
1506
1540
|
zh: {
|
|
1507
1541
|
title: "EasyRewrite",
|
|
1508
1542
|
subtitle: "简单易用的撤回重编辑",
|
|
1509
|
-
cardSummary: "撤回、重编辑与版本历史",
|
|
1510
1543
|
expand: "展开",
|
|
1511
1544
|
collapse: "收起",
|
|
1512
1545
|
rewrite: "气泡框编辑(点击气泡原位修改)",
|
|
@@ -1600,7 +1633,6 @@ window.__ModuleLoader__.load({
|
|
|
1600
1633
|
en: {
|
|
1601
1634
|
title: "EasyRewrite",
|
|
1602
1635
|
subtitle: "Simple & easy recall and re-edit",
|
|
1603
|
-
cardSummary: "Recall, re-edit and version history",
|
|
1604
1636
|
expand: "Expand",
|
|
1605
1637
|
collapse: "Collapse",
|
|
1606
1638
|
rewrite: "Bubble edit (click bubble to edit in place)",
|
|
@@ -1694,7 +1726,6 @@ window.__ModuleLoader__.load({
|
|
|
1694
1726
|
ja: {
|
|
1695
1727
|
title: "EasyRewrite",
|
|
1696
1728
|
subtitle: "簡単で使いやすい撤回・再編集",
|
|
1697
|
-
cardSummary: "撤回・再編集とバージョン履歴",
|
|
1698
1729
|
expand: "展開",
|
|
1699
1730
|
collapse: "折りたたむ",
|
|
1700
1731
|
rewrite: "バブル編集(クリックでその場編集)",
|
|
@@ -1820,9 +1851,17 @@ window.__ModuleLoader__.load({
|
|
|
1820
1851
|
/** 设置卡片:注册进 plugins.row.config(设置 → 插件 → 插件配置)。
|
|
1821
1852
|
* 插件页对每个配置项渲染两次:view==='summary' 取行标题下的一行摘要,view==='page' 取完整表单。 */
|
|
1822
1853
|
function EasyRewriteSettingsCard(props) {
|
|
1854
|
+
/**
|
|
1855
|
+
* 是否由外部容器提供卡片外壳。
|
|
1856
|
+
*
|
|
1857
|
+
* 0.1.7 的插件页(plugins.item)自己画行外壳、标题取自插槽 label,卡片再画一层头部
|
|
1858
|
+
* 就成了嵌套折叠;旧插槽 settings.plugin.item 没有外壳,卡片必须自画。由挂载方经
|
|
1859
|
+
* inject 面传入,默认 false,保持旧行为。
|
|
1860
|
+
*/
|
|
1861
|
+
var embedded = !!(props && props.embedded);
|
|
1823
1862
|
var L = useUILocaleDict();
|
|
1824
|
-
|
|
1825
|
-
var openState = React.useState(
|
|
1863
|
+
// embedded 时头部不渲染,但「展开时检查更新」这类 side effect 仍要照跑,故初始即展开。
|
|
1864
|
+
var openState = React.useState(embedded);
|
|
1826
1865
|
var open = openState[0];
|
|
1827
1866
|
var setOpen = openState[1];
|
|
1828
1867
|
// 控件状态(初始化自 localStorage)
|
|
@@ -2084,7 +2123,7 @@ window.__ModuleLoader__.load({
|
|
|
2084
2123
|
"aria-disabled": disabled || undefined,
|
|
2085
2124
|
style: Object.assign({}, checkStyle, disabled ? { cursor: "not-allowed" } : null),
|
|
2086
2125
|
onClick: function (e) { e.stopPropagation(); if (disabled) return; onChange(!value); }
|
|
2087
|
-
}, value ? React.createElement(
|
|
2126
|
+
}, value ? React.createElement(IconCheckOutline, null) : null)
|
|
2088
2127
|
);
|
|
2089
2128
|
}
|
|
2090
2129
|
// Apple 风格分段控件:灰色药丸长条 + 白色小药丸高亮当前项(滑动过渡,主题自适应)
|
|
@@ -2140,22 +2179,13 @@ window.__ModuleLoader__.load({
|
|
|
2140
2179
|
);
|
|
2141
2180
|
}
|
|
2142
2181
|
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
},
|
|
2151
|
-
React.createElement("span", { style: headTextStyle },
|
|
2152
|
-
React.createElement("span", { style: titleStyle }, L.title),
|
|
2153
|
-
React.createElement("span", { style: subStyle }, L.subtitle)
|
|
2154
|
-
),
|
|
2155
|
-
React.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", style: Object.assign({}, chevronStyle, open ? chevronOpenStyle : null) },
|
|
2156
|
-
React.createElement("path", { d: "M9 6l6 6-6 6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }))
|
|
2157
|
-
),
|
|
2158
|
-
open ? React.createElement("div", { style: bodyStyle },
|
|
2182
|
+
// 配置主体:两种挂法共用。
|
|
2183
|
+
//
|
|
2184
|
+
// 0.1.7 起卡片挂进 plugins.item,页面已经给了行外壳(标题来自插槽 label、描述、
|
|
2185
|
+
// 展开由页面管),卡片只该交出主体。自带 <li> + 可点头部会变成页面里多出来的一层
|
|
2186
|
+
// 折叠 —— 列表上一个下拉,点进去还有一个。旧插槽 settings.plugin.item 没有外壳,
|
|
2187
|
+
// 那种挂法仍旧要卡片自画,所以分流在函数末尾按 embedded 做。
|
|
2188
|
+
var cardBody = React.createElement("div", { style: bodyStyle },
|
|
2159
2189
|
// —— 编辑 ——
|
|
2160
2190
|
React.createElement("div", { style: sectionStyle },
|
|
2161
2191
|
React.createElement("span", { style: groupTitleStyle }, L.sectionEdit),
|
|
@@ -2384,7 +2414,28 @@ window.__ModuleLoader__.load({
|
|
|
2384
2414
|
)
|
|
2385
2415
|
),
|
|
2386
2416
|
React.createElement("span", { style: hintStyle }, L.instant)
|
|
2387
|
-
|
|
2417
|
+
);
|
|
2418
|
+
// plugins.item(0.1.7 起):页面把同一个组件按 view 渲染两次 —— summary 当列表行与
|
|
2419
|
+
// 详情页的一行描述,page 当配置主体。图标、标题(取自插槽 label)、启用开关与详情页
|
|
2420
|
+
// 外壳都由页面提供,所以这里两者都不画头部。
|
|
2421
|
+
if (embedded) return props.view === "summary" ? L.subtitle : cardBody;
|
|
2422
|
+
// settings.plugin.item(0.1.5 及以下):插槽不提供外壳,卡片自画可点头部。
|
|
2423
|
+
return React.createElement("li", { style: Object.assign({}, cardStyle, open ? cardOpenStyle : null), "data-dsh-easyrewrite": "settings-card" },
|
|
2424
|
+
React.createElement("button", {
|
|
2425
|
+
type: "button",
|
|
2426
|
+
style: headStyle,
|
|
2427
|
+
"aria-expanded": open,
|
|
2428
|
+
"aria-label": (open ? L.collapse : L.expand) + ": " + L.title,
|
|
2429
|
+
onClick: function () { setOpen(!open); }
|
|
2430
|
+
},
|
|
2431
|
+
React.createElement("span", { style: headTextStyle },
|
|
2432
|
+
React.createElement("span", { style: titleStyle }, L.title),
|
|
2433
|
+
React.createElement("span", { style: subStyle }, L.subtitle)
|
|
2434
|
+
),
|
|
2435
|
+
React.createElement("svg", { width: "18", height: "18", viewBox: "0 0 24 24", style: Object.assign({}, chevronStyle, open ? chevronOpenStyle : null) },
|
|
2436
|
+
React.createElement("path", { d: "M9 6l6 6-6 6", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }))
|
|
2437
|
+
),
|
|
2438
|
+
open ? cardBody : null
|
|
2388
2439
|
);
|
|
2389
2440
|
}
|
|
2390
2441
|
|
|
@@ -2396,7 +2447,7 @@ window.__ModuleLoader__.load({
|
|
|
2396
2447
|
log("info", "pager", "切换版本", { from: sessionId, to: next, index: nextIndex + 1, count: fam.versions.length });
|
|
2397
2448
|
// 历史版本都是归档会话(无痕替换副作用),先恢复再打开;恢复失败也照常打开(幂等)
|
|
2398
2449
|
var doOpen = function () {
|
|
2399
|
-
|
|
2450
|
+
safeOpenSession(next, props);
|
|
2400
2451
|
// 等当前会话确认为 next(轮询 current,不猜时间)后,归档家族其余版本——列表只保留目标一个。
|
|
2401
2452
|
// open 未确认(超时 8s)则放弃归档,绝不误伤任何会话。
|
|
2402
2453
|
if (cleanupRef.current !== null) { clearInterval(cleanupRef.current); cleanupRef.current = null; }
|
|
@@ -2604,7 +2655,7 @@ window.__ModuleLoader__.load({
|
|
|
2604
2655
|
disabled: atFirst,
|
|
2605
2656
|
"aria-label": L.pagerPrev,
|
|
2606
2657
|
onClick: function () { go(-1); }
|
|
2607
|
-
}, React.createElement(
|
|
2658
|
+
}, React.createElement(IconChevronLeftOutline, null)),
|
|
2608
2659
|
React.createElement("span", { style: { padding: "0 4px", fontSize: "14px", whiteSpace: "nowrap" } }, (index + 1) + "/" + count),
|
|
2609
2660
|
React.createElement("button", {
|
|
2610
2661
|
type: "button",
|
|
@@ -2613,7 +2664,7 @@ window.__ModuleLoader__.load({
|
|
|
2613
2664
|
disabled: atLast,
|
|
2614
2665
|
"aria-label": L.pagerNext,
|
|
2615
2666
|
onClick: function () { go(1); }
|
|
2616
|
-
}, React.createElement(
|
|
2667
|
+
}, React.createElement(IconChevronRightOutline, null))
|
|
2617
2668
|
);
|
|
2618
2669
|
}
|
|
2619
2670
|
|
|
@@ -2650,8 +2701,8 @@ window.__ModuleLoader__.load({
|
|
|
2650
2701
|
onMouseLeave: function (e) { e.currentTarget.style.background = "transparent"; },
|
|
2651
2702
|
onClick: function (e) { e.stopPropagation(); copy(); }
|
|
2652
2703
|
}, copied
|
|
2653
|
-
? React.createElement(
|
|
2654
|
-
: React.createElement(
|
|
2704
|
+
? React.createElement(IconCheckOutline, { size: 14 })
|
|
2705
|
+
: React.createElement(IconCopyOutline, { size: 14 }));
|
|
2655
2706
|
}
|
|
2656
2707
|
|
|
2657
2708
|
/** clipboard API 不可用时的回退复制。 */
|
|
@@ -3344,8 +3395,8 @@ window.__ModuleLoader__.load({
|
|
|
3344
3395
|
padding: "8px 14px",
|
|
3345
3396
|
whiteSpace: "pre-wrap",
|
|
3346
3397
|
wordBreak: "break-word",
|
|
3347
|
-
fontSize: "14px",
|
|
3348
|
-
lineHeight: "22px",
|
|
3398
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
3399
|
+
lineHeight: "calc(22px + var(--dsh-content-font-delta, 0px))",
|
|
3349
3400
|
color: "var(--dsw-alias-label-primary, inherit)"
|
|
3350
3401
|
};
|
|
3351
3402
|
var actionsStyle = { display: "flex", gap: "2px", alignItems: "center" };
|
|
@@ -3362,8 +3413,8 @@ window.__ModuleLoader__.load({
|
|
|
3362
3413
|
background: "var(--dsw-alias-interactive-bg-hover, rgba(128,128,128,0.10))",
|
|
3363
3414
|
borderRadius: "14px",
|
|
3364
3415
|
padding: "8px 14px",
|
|
3365
|
-
fontSize: "14px",
|
|
3366
|
-
lineHeight: "22px",
|
|
3416
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
3417
|
+
lineHeight: "calc(22px + var(--dsh-content-font-delta, 0px))",
|
|
3367
3418
|
cursor: "pointer",
|
|
3368
3419
|
color: "var(--dsw-alias-label-tertiary)",
|
|
3369
3420
|
whiteSpace: "pre-wrap",
|
|
@@ -3401,6 +3452,7 @@ window.__ModuleLoader__.load({
|
|
|
3401
3452
|
showPreview ? origImages : null,
|
|
3402
3453
|
showPreview ? React.createElement(
|
|
3403
3454
|
"div", {
|
|
3455
|
+
className: "dsh-easyrewrite-bubble",
|
|
3404
3456
|
style: grayBubbleStyle,
|
|
3405
3457
|
title: L.collapse,
|
|
3406
3458
|
onClick: togglePreview
|
|
@@ -3408,6 +3460,7 @@ window.__ModuleLoader__.load({
|
|
|
3408
3460
|
text || L.emptyMsg
|
|
3409
3461
|
) : React.createElement(
|
|
3410
3462
|
"div", {
|
|
3463
|
+
className: "dsh-easyrewrite-bubble",
|
|
3411
3464
|
style: grayBubbleStyle,
|
|
3412
3465
|
title: L.viewOriginal,
|
|
3413
3466
|
onClick: togglePreview
|
|
@@ -3618,8 +3671,8 @@ window.__ModuleLoader__.load({
|
|
|
3618
3671
|
background: "transparent",
|
|
3619
3672
|
resize: "none",
|
|
3620
3673
|
font: "inherit",
|
|
3621
|
-
fontSize: "14px",
|
|
3622
|
-
lineHeight: "22px",
|
|
3674
|
+
fontSize: "var(--dsh-content-font-size, 14px)",
|
|
3675
|
+
lineHeight: "calc(22px + var(--dsh-content-font-delta, 0px))",
|
|
3623
3676
|
color: "var(--dsw-alias-label-primary)",
|
|
3624
3677
|
whiteSpace: "pre-wrap",
|
|
3625
3678
|
wordBreak: "break-word",
|
|
@@ -3826,7 +3879,7 @@ window.__ModuleLoader__.load({
|
|
|
3826
3879
|
"div", { style: rowStyle, "data-dsh-easyrewrite": "user", "data-time-hover-root": true },
|
|
3827
3880
|
renderMessageImagesCompat(msgImages, props),
|
|
3828
3881
|
React.createElement(
|
|
3829
|
-
"div", { style: bubbleStyle, onClick: onBubbleClick, title: L.clickEdit },
|
|
3882
|
+
"div", { className: "dsh-easyrewrite-bubble", style: bubbleStyle, onClick: onBubbleClick, title: L.clickEdit },
|
|
3830
3883
|
text || L.emptyMsg
|
|
3831
3884
|
),
|
|
3832
3885
|
confirming
|
|
@@ -3956,7 +4009,6 @@ window.__ModuleLoader__.load({
|
|
|
3956
4009
|
var disposers = [];
|
|
3957
4010
|
var styleTag = injectThemeStyle();
|
|
3958
4011
|
try { if (typeof ctx.locale === "object" && ctx.locale !== null && typeof ctx.locale.register === "function") ctx.locale.register(NS, {}); } catch (e) { /* ignore */ }
|
|
3959
|
-
log("info", "lifecycle", "client half active");
|
|
3960
4012
|
// 调试 API:撤回条实时调参(调试模式门控:localStorage dsh-easyrewrite:debug=1;set/get/diagnose/export)
|
|
3961
4013
|
try {
|
|
3962
4014
|
var wRef = (typeof window !== "undefined") ? window : null;
|
|
@@ -4035,7 +4087,42 @@ window.__ModuleLoader__.load({
|
|
|
4035
4087
|
} catch (eDbg) { /* ignore */ }
|
|
4036
4088
|
try { ctxConversationRef = ctx.conversation; } catch (e) { ctxConversationRef = null; }
|
|
4037
4089
|
try { ctxUiConversationRef = (typeof ctx.get === "function") ? (ctx.get("uiConversation") || null) : null; } catch (eUic) { ctxUiConversationRef = null; }
|
|
4038
|
-
try { ctxUiWorkspaceRef = (typeof ctx.get === "function") ? (ctx.get("uiWorkspace") || null) : null; } catch (eUiw) { ctxUiWorkspaceRef = null; }
|
|
4090
|
+
try { ctxUiWorkspaceRef = ctx.uiWorkspace || ((typeof ctx.get === "function") ? (ctx.get("uiWorkspace") || null) : null); } catch (eUiw) { ctxUiWorkspaceRef = null; }
|
|
4091
|
+
function invokeOpenSession(id) {
|
|
4092
|
+
try {
|
|
4093
|
+
if (ctx.uiWorkspace && typeof ctx.uiWorkspace.openSession === "function") {
|
|
4094
|
+
ctx.uiWorkspace.openSession(id);
|
|
4095
|
+
return true;
|
|
4096
|
+
}
|
|
4097
|
+
} catch (e1) {}
|
|
4098
|
+
try {
|
|
4099
|
+
var uiW = (typeof ctx.get === "function") ? ctx.get("uiWorkspace") : null;
|
|
4100
|
+
if (uiW && typeof uiW.openSession === "function") {
|
|
4101
|
+
uiW.openSession(id);
|
|
4102
|
+
return true;
|
|
4103
|
+
}
|
|
4104
|
+
} catch (e2) {}
|
|
4105
|
+
try {
|
|
4106
|
+
if (ctxUiWorkspaceRef && typeof ctxUiWorkspaceRef.openSession === "function") {
|
|
4107
|
+
ctxUiWorkspaceRef.openSession(id);
|
|
4108
|
+
return true;
|
|
4109
|
+
}
|
|
4110
|
+
} catch (e3) {}
|
|
4111
|
+
try {
|
|
4112
|
+
if (ctx.sessions && typeof ctx.sessions.open === "function") {
|
|
4113
|
+
ctx.sessions.open(id);
|
|
4114
|
+
return true;
|
|
4115
|
+
}
|
|
4116
|
+
} catch (e4) {}
|
|
4117
|
+
try {
|
|
4118
|
+
if (ctx.workspaces && typeof ctx.workspaces.openSession === "function") {
|
|
4119
|
+
ctx.workspaces.openSession(id);
|
|
4120
|
+
return true;
|
|
4121
|
+
}
|
|
4122
|
+
} catch (e5) {}
|
|
4123
|
+
log("error", "session", "所有 openSession 途径均不可用", { id: id });
|
|
4124
|
+
return false;
|
|
4125
|
+
}
|
|
4039
4126
|
// 陈旧版本树键清扫(review #6:lineage 已接管;旧 localStorage 键为死数据,启动时一次清掉)
|
|
4040
4127
|
try {
|
|
4041
4128
|
var stale = [];
|
|
@@ -4124,7 +4211,7 @@ window.__ModuleLoader__.load({
|
|
|
4124
4211
|
}
|
|
4125
4212
|
} catch (eSh2) { inputShell2 = null; }
|
|
4126
4213
|
return {
|
|
4127
|
-
openSession:
|
|
4214
|
+
openSession: invokeOpenSession,
|
|
4128
4215
|
ctxWorkspaces: ctx.workspaces,
|
|
4129
4216
|
ctxSessions: ctx.sessions,
|
|
4130
4217
|
modelSel: modelSel,
|
|
@@ -4167,7 +4254,7 @@ window.__ModuleLoader__.load({
|
|
|
4167
4254
|
} catch (eShell) { inputShell = null; }
|
|
4168
4255
|
return {
|
|
4169
4256
|
sessionId: sessionId,
|
|
4170
|
-
openSession:
|
|
4257
|
+
openSession: invokeOpenSession,
|
|
4171
4258
|
ctxWorkspaces: ctx.workspaces,
|
|
4172
4259
|
ctxSessions: ctx.sessions,
|
|
4173
4260
|
updateQueue: function (itemId, action) {
|
|
@@ -4203,26 +4290,38 @@ window.__ModuleLoader__.load({
|
|
|
4203
4290
|
}, RecallBanner);
|
|
4204
4291
|
});
|
|
4205
4292
|
if (typeof d3 === "function") disposers.push(d3);
|
|
4206
|
-
//
|
|
4207
|
-
//
|
|
4208
|
-
//
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4293
|
+
// 设置卡片。两种挂载方式各注册一次:
|
|
4294
|
+
//
|
|
4295
|
+
// ≤0.1.5 keyed 插槽 settings.plugin.item(按命名空间分发),插槽不给外壳,
|
|
4296
|
+
// 卡片自画可点头部。
|
|
4297
|
+
// 0.1.7+ 改用插件页。第三方 bundle 的配置属于它自己那一行,走
|
|
4298
|
+
// plugins.row.config,key 为 `<包名>#<行 id>`;页面因此会给该行一个
|
|
4299
|
+
// Configure 控件,打开它自己的配置页。
|
|
4300
|
+
//
|
|
4301
|
+
// 行 id 等于宿主半边 export const name;bundle 包名随安装形态而变——经本仓库聚合包
|
|
4302
|
+
// 安装时是聚合包,独立安装时是本包。两个 bundle 名都注册,页面只会分派已安装的那个。
|
|
4303
|
+
function registerSettingsCard(slotName, kind, embedded) {
|
|
4304
|
+
return ctx.slots.inject(slotName, function () {
|
|
4305
|
+
return ctx.slots.register(Object.assign({
|
|
4306
|
+
name: slotName,
|
|
4216
4307
|
inject: function () {
|
|
4217
4308
|
return {
|
|
4218
|
-
openSession:
|
|
4219
|
-
ctxSessions: ctx.sessions
|
|
4309
|
+
openSession: invokeOpenSession,
|
|
4310
|
+
ctxSessions: ctx.sessions,
|
|
4311
|
+
// 页面提供行外壳的挂法,卡片只交出配置主体(见组件里的 embedded)。
|
|
4312
|
+
embedded: !!embedded
|
|
4220
4313
|
};
|
|
4221
4314
|
}
|
|
4222
|
-
}, EasyRewriteSettingsCard);
|
|
4315
|
+
}, kind), EasyRewriteSettingsCard);
|
|
4223
4316
|
});
|
|
4317
|
+
}
|
|
4318
|
+
var ROW_ID = "dsh-easyrewrite";
|
|
4319
|
+
var BUNDLE_NAMES = ["@logictan/dsh-plugins-all", "@logictan/dsh-easyrewrite"];
|
|
4320
|
+
var d4 = [registerSettingsCard("settings.plugin.item", { key: ROW_ID })];
|
|
4321
|
+
BUNDLE_NAMES.forEach(function (bundle) {
|
|
4322
|
+
d4.push(registerSettingsCard("plugins.row.config", { key: bundle + "#" + ROW_ID }, true));
|
|
4224
4323
|
});
|
|
4225
|
-
|
|
4324
|
+
d4.forEach(function (d) { if (typeof d === "function") disposers.push(d); });
|
|
4226
4325
|
// 版本翻页器 < X >:assistant 消息操作区(最后回答底部)
|
|
4227
4326
|
var d5 = ctx.slots.inject("conversation.chat.assistant-actions", function () {
|
|
4228
4327
|
return ctx.slots.register({
|
|
@@ -4231,7 +4330,7 @@ window.__ModuleLoader__.load({
|
|
|
4231
4330
|
order: 10,
|
|
4232
4331
|
inject: function () {
|
|
4233
4332
|
return {
|
|
4234
|
-
openSession:
|
|
4333
|
+
openSession: invokeOpenSession,
|
|
4235
4334
|
ctxSessions: ctx.sessions,
|
|
4236
4335
|
archiveSession: function (id) {
|
|
4237
4336
|
// review #5:官方 archiveSession 幂等且 sessionKnown 接受归档会话(dsh-workspace L424/L439)——
|
|
@@ -4250,7 +4349,18 @@ window.__ModuleLoader__.load({
|
|
|
4250
4349
|
}
|
|
4251
4350
|
},
|
|
4252
4351
|
currentSessionId: function () {
|
|
4253
|
-
try {
|
|
4352
|
+
try {
|
|
4353
|
+
var s = ctx.sessions.list.getSnapshot();
|
|
4354
|
+
if (!s) return null;
|
|
4355
|
+
if (s.current) return s.current;
|
|
4356
|
+
if (s.byId) {
|
|
4357
|
+
var found = Object.values(s.byId).find(function (r) {
|
|
4358
|
+
return r && r.retainedBy && (r.retainedBy.mainView > 0);
|
|
4359
|
+
});
|
|
4360
|
+
if (found && found.id) return found.id;
|
|
4361
|
+
}
|
|
4362
|
+
return null;
|
|
4363
|
+
} catch (e) { return null; }
|
|
4254
4364
|
},
|
|
4255
4365
|
restoreSession: function (id) {
|
|
4256
4366
|
return fetch("/bubble/unarchive", {
|
|
@@ -4268,6 +4378,9 @@ window.__ModuleLoader__.load({
|
|
|
4268
4378
|
}, VersionPager);
|
|
4269
4379
|
});
|
|
4270
4380
|
if (typeof d5 === "function") disposers.push(d5);
|
|
4381
|
+
// 这行必须在全部 slots.register 之后:旧位置在注册之前,槽位渲染崩溃时它照样输出,
|
|
4382
|
+
// 让人误以为「日志正常 = UI 正常」。现在它只证明注册跑完,不证明槽位渲染成功。
|
|
4383
|
+
log("info", "lifecycle", "client half registered", { disposers: disposers.length });
|
|
4271
4384
|
return function () {
|
|
4272
4385
|
for (var i = 0; i < disposers.length; i++) disposers[i]();
|
|
4273
4386
|
if (styleTag !== null) styleTag.remove();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logictan/dsh-easyrewrite",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "DSH Web内目前最无感的消息撤回、重编辑插件,原版体验,兼容性强,功能简单可开关,设置丰富,现代化轻量ui框架。The most seamless message recall & re-edit plugin for DSH Web — native experience, strong compatibility, simple toggles, rich settings, modern lightweight UI. DSH Web で最もシームレスなメッセージ撤回・再編集プラグイン——ネイティブ体験、高い互換性、シンプルなトグル、充実した設定、モダンで軽量な UI。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
],
|
|
59
59
|
"license": "MIT",
|
|
60
60
|
"scripts": {
|
|
61
|
-
"test": "node tests/smoke-host.mjs && node tests/test-log-memory.mjs && node tests/test-issue9-anti-double-submit.mjs",
|
|
61
|
+
"test": "node tests/smoke-host.mjs && node tests/test-log-memory.mjs && node tests/test-issue9-anti-double-submit.mjs && node tests/test-issue11-bubble-compatibility.mjs && node tests/test-dsh-0.1.7-pager.mjs",
|
|
62
62
|
"build": "node build.mjs",
|
|
63
63
|
"prepare": "node build.mjs",
|
|
64
64
|
"prepack": "node build.mjs"
|