dsh-rewind-plugin 0.18.1 → 0.19.1
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 +0 -8
- package/README.md +0 -5
- package/lib/client.js +459 -313
- package/lib/index.js +58 -5
- package/lib/types/client/candidates.d.ts +4 -6
- package/lib/types/client/hidden.d.ts +30 -36
- package/lib/types/client/index.d.ts +1 -7
- package/lib/types/client/locales.d.ts +58 -46
- package/lib/types/client/portals.d.ts +3 -65
- package/lib/types/client/visibility.d.ts +89 -0
- package/lib/types/locales.d.ts +80 -20
- package/locale/ja.json +6 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -9,6 +9,7 @@ var __defProp = Object.defineProperty;
|
|
|
9
9
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
10
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
12
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
13
|
var __export = (target, all) => {
|
|
13
14
|
for (var name2 in all)
|
|
14
15
|
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
@@ -22,22 +23,72 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
22
23
|
return to;
|
|
23
24
|
};
|
|
24
25
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
26
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
25
27
|
|
|
26
28
|
// src/client/index.ts
|
|
27
29
|
var index_exports = {};
|
|
28
30
|
__export(index_exports, {
|
|
29
31
|
apply: () => apply,
|
|
30
|
-
hiddenSeqsOf: () => hiddenSeqsOf,
|
|
31
32
|
inject: () => inject,
|
|
32
|
-
name: () => name
|
|
33
|
-
targetSeqOfArgs: () => targetSeqOfArgs
|
|
33
|
+
name: () => name
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
|
+
// src/client/candidates.ts
|
|
38
|
+
var PREVIEW_CHARS = 80;
|
|
39
|
+
var DEFAULT_CANDIDATE_LIMIT = 100;
|
|
40
|
+
function messagePreviewOf(message) {
|
|
41
|
+
const text = message.content.map((block) => block.type === "text" && typeof block.text === "string" ? block.text : "").join("").replace(/\s+/g, " ").trim();
|
|
42
|
+
return text.length <= PREVIEW_CHARS ? text : `${text.slice(0, PREVIEW_CHARS - 1)}\u2026`;
|
|
43
|
+
}
|
|
44
|
+
function formatCandidateTime(time) {
|
|
45
|
+
const d = new Date(time);
|
|
46
|
+
const hh = String(d.getHours()).padStart(2, "0");
|
|
47
|
+
const mm = String(d.getMinutes()).padStart(2, "0");
|
|
48
|
+
return `${hh}:${mm}`;
|
|
49
|
+
}
|
|
50
|
+
function rewindCandidatesOf(snap, limit = DEFAULT_CANDIDATE_LIMIT) {
|
|
51
|
+
const candidates = [];
|
|
52
|
+
for (let i = snap.order.length - 1; i >= 0 && candidates.length < limit; i--) {
|
|
53
|
+
const key = snap.order[i];
|
|
54
|
+
if (key === void 0) continue;
|
|
55
|
+
const node = snap.nodes.get(key);
|
|
56
|
+
if (node === void 0 || node.kind !== "user" && node.kind !== "steering") continue;
|
|
57
|
+
candidates.push({
|
|
58
|
+
seq: node.data.seq,
|
|
59
|
+
time: node.data.time,
|
|
60
|
+
preview: messagePreviewOf(node.data)
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return candidates;
|
|
64
|
+
}
|
|
65
|
+
function rewindCandidatesOfChat(snap) {
|
|
66
|
+
return rewindCandidatesOf(snap);
|
|
67
|
+
}
|
|
68
|
+
function rewindOptionsFromCandidates(candidates, t) {
|
|
69
|
+
return candidates.map((candidate) => ({
|
|
70
|
+
id: String(candidate.seq),
|
|
71
|
+
label: candidate.preview || t("popover.noText"),
|
|
72
|
+
detail: formatCandidateTime(candidate.time)
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
|
|
37
76
|
// src/client/hidden.ts
|
|
38
77
|
var ENGINE_COMMAND = "rewind-plugin";
|
|
39
78
|
var LEGACY_ENGINE_COMMAND = "rewind";
|
|
40
79
|
var ENGINE_COMMANDS = /* @__PURE__ */ new Set([ENGINE_COMMAND, LEGACY_ENGINE_COMMAND]);
|
|
80
|
+
function chatNodesOf(chat) {
|
|
81
|
+
if (chat === void 0) return EMPTY_NODES;
|
|
82
|
+
const values = chat.nodes.values;
|
|
83
|
+
if (typeof values === "function") return [...values.call(chat.nodes)];
|
|
84
|
+
const nodes = [];
|
|
85
|
+
for (const key of chat.order) {
|
|
86
|
+
const node = chat.nodes.get(key);
|
|
87
|
+
if (node !== void 0) nodes.push(node);
|
|
88
|
+
}
|
|
89
|
+
return nodes;
|
|
90
|
+
}
|
|
91
|
+
var EMPTY_NODES = [];
|
|
41
92
|
function resolveChatWatch(resolveView, sessionId, cb) {
|
|
42
93
|
const view = resolveView(sessionId);
|
|
43
94
|
return view?.subscribe?.(cb) ?? (() => {
|
|
@@ -48,9 +99,8 @@ function chatSnapshotOf(chatView) {
|
|
|
48
99
|
}
|
|
49
100
|
function messageTextAt(chat, seq) {
|
|
50
101
|
if (chat === void 0) return void 0;
|
|
51
|
-
for (const
|
|
52
|
-
|
|
53
|
-
if (node === void 0 || node.kind !== "user" && node.kind !== "steering") continue;
|
|
102
|
+
for (const node of chatNodesOf(chat)) {
|
|
103
|
+
if (node.kind !== "user" && node.kind !== "steering") continue;
|
|
54
104
|
const data = node.data;
|
|
55
105
|
if (data.seq === seq) {
|
|
56
106
|
return data.content?.map((block) => block.type === "text" && typeof block.text === "string" ? block.text : "").join("");
|
|
@@ -60,9 +110,8 @@ function messageTextAt(chat, seq) {
|
|
|
60
110
|
}
|
|
61
111
|
function messageAttachmentsAt(chat, seq) {
|
|
62
112
|
if (chat === void 0) return void 0;
|
|
63
|
-
for (const
|
|
64
|
-
|
|
65
|
-
if (node === void 0 || node.kind !== "user" && node.kind !== "steering") continue;
|
|
113
|
+
for (const node of chatNodesOf(chat)) {
|
|
114
|
+
if (node.kind !== "user" && node.kind !== "steering") continue;
|
|
66
115
|
const data = node.data;
|
|
67
116
|
if (data.seq !== seq) continue;
|
|
68
117
|
const images = [];
|
|
@@ -100,141 +149,21 @@ function isPreviewCommand(command) {
|
|
|
100
149
|
function isCandidateCommand(command) {
|
|
101
150
|
return (command.args ?? "").includes("__candidates");
|
|
102
151
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
for (const span of sorted) {
|
|
108
|
-
const last = merged[merged.length - 1];
|
|
109
|
-
if (last !== void 0 && span.start <= last.end) {
|
|
110
|
-
if (span.end > last.end) last.end = span.end;
|
|
111
|
-
continue;
|
|
112
|
-
}
|
|
113
|
-
merged.push({ start: span.start, end: span.end });
|
|
114
|
-
}
|
|
115
|
-
return merged;
|
|
116
|
-
}
|
|
117
|
-
function cutsContain(cuts, seq) {
|
|
118
|
-
let low = 0;
|
|
119
|
-
let high = cuts.length - 1;
|
|
120
|
-
while (low <= high) {
|
|
121
|
-
const middle = low + high >> 1;
|
|
122
|
-
const cut = cuts[middle];
|
|
123
|
-
if (seq < cut.start) high = middle - 1;
|
|
124
|
-
else if (seq > cut.end) low = middle + 1;
|
|
125
|
-
else return true;
|
|
126
|
-
}
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
function liveAnchorKeys(snap, cuts) {
|
|
130
|
-
const live = /* @__PURE__ */ new Map();
|
|
131
|
-
for (const key of snap.order) {
|
|
132
|
-
const node = snap.nodes.get(key);
|
|
133
|
-
if (node === void 0 || cutsContain(cuts, node.anchorSeq)) continue;
|
|
134
|
-
const keys = live.get(node.anchorSeq);
|
|
135
|
-
if (keys === void 0) live.set(node.anchorSeq, [key]);
|
|
136
|
-
else keys.push(key);
|
|
137
|
-
}
|
|
138
|
-
return live;
|
|
139
|
-
}
|
|
140
|
-
var EMPTY_KEYS = [];
|
|
141
|
-
function addWithdrawnTurnChrome(snap, cuts, hidden) {
|
|
142
|
-
const locations = snap.locations;
|
|
143
|
-
if (locations === void 0 || cuts.length === 0) return;
|
|
144
|
-
let live;
|
|
145
|
-
for (const key of snap.order) {
|
|
146
|
-
const chrome = snap.nodes.get(key);
|
|
147
|
-
if (chrome === void 0 || chrome.kind !== "turn-process") continue;
|
|
148
|
-
const located = chrome.location?.turn;
|
|
149
|
-
if (located?.start === void 0) continue;
|
|
150
|
-
const turn = located.turn;
|
|
151
|
-
if (typeof turn !== "number") continue;
|
|
152
|
-
const keys = locations.getTurn(turn);
|
|
153
|
-
if (keys.length === 0) continue;
|
|
154
|
-
const rows = keys.map((member) => snap.nodes.get(member)).filter((member) => member !== void 0);
|
|
155
|
-
if (rows.length !== keys.length) continue;
|
|
156
|
-
if (!rows.every((member) => member.key === chrome.key || cutsContain(cuts, member.anchorSeq))) continue;
|
|
157
|
-
live ?? (live = liveAnchorKeys(snap, cuts));
|
|
158
|
-
if ((live.get(chrome.anchorSeq) ?? EMPTY_KEYS).some((holder) => holder !== chrome.key)) continue;
|
|
159
|
-
hidden.add(chrome.anchorSeq);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
var hiddenSeqsMemo = /* @__PURE__ */ new WeakMap();
|
|
163
|
-
function hiddenSeqsOf(snap) {
|
|
164
|
-
const memo = hiddenSeqsMemo.get(snap);
|
|
165
|
-
if (memo !== void 0) return new Set(memo);
|
|
166
|
-
const hidden = /* @__PURE__ */ new Set();
|
|
167
|
-
const spans = [];
|
|
168
|
-
for (const key of snap.order) {
|
|
169
|
-
const node = snap.nodes.get(key);
|
|
170
|
-
if (node === void 0 || node.kind !== "command") continue;
|
|
152
|
+
function rewindCutsOf(nodes) {
|
|
153
|
+
const cuts = [];
|
|
154
|
+
for (const node of nodes) {
|
|
155
|
+
if (node.kind !== "command") continue;
|
|
171
156
|
const command = node.data;
|
|
172
157
|
if (command.name === null || !ENGINE_COMMANDS.has(command.name)) continue;
|
|
173
|
-
if (isPreviewCommand(command) || isCandidateCommand(command))
|
|
174
|
-
hidden.add(command.seq);
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
158
|
+
if (isPreviewCommand(command) || isCandidateCommand(command)) continue;
|
|
177
159
|
if (command.outcome?.kind !== "success") continue;
|
|
178
160
|
const marker = command.outcome.sourceEventSeq;
|
|
179
161
|
if (marker === void 0) continue;
|
|
180
|
-
hidden.add(command.seq);
|
|
181
162
|
const target = targetSeqOfArgs(command.args);
|
|
182
|
-
if (target
|
|
183
|
-
|
|
184
|
-
}
|
|
163
|
+
if (target === void 0 || target > marker) continue;
|
|
164
|
+
cuts.push({ target, marker });
|
|
185
165
|
}
|
|
186
|
-
|
|
187
|
-
for (const key of snap.order) {
|
|
188
|
-
const node = snap.nodes.get(key);
|
|
189
|
-
if (node === void 0) continue;
|
|
190
|
-
if (cutsContain(cuts, node.anchorSeq)) hidden.add(node.anchorSeq);
|
|
191
|
-
}
|
|
192
|
-
try {
|
|
193
|
-
addWithdrawnTurnChrome(snap, cuts, hidden);
|
|
194
|
-
} catch {
|
|
195
|
-
}
|
|
196
|
-
hiddenSeqsMemo.set(snap, new Set(hidden));
|
|
197
|
-
return hidden;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// src/client/candidates.ts
|
|
201
|
-
var PREVIEW_CHARS = 80;
|
|
202
|
-
var DEFAULT_CANDIDATE_LIMIT = 100;
|
|
203
|
-
function messagePreviewOf(message) {
|
|
204
|
-
const text = message.content.map((block) => block.type === "text" && typeof block.text === "string" ? block.text : "").join("").replace(/\s+/g, " ").trim();
|
|
205
|
-
return text.length <= PREVIEW_CHARS ? text : `${text.slice(0, PREVIEW_CHARS - 1)}\u2026`;
|
|
206
|
-
}
|
|
207
|
-
function formatCandidateTime(time) {
|
|
208
|
-
const d = new Date(time);
|
|
209
|
-
const hh = String(d.getHours()).padStart(2, "0");
|
|
210
|
-
const mm = String(d.getMinutes()).padStart(2, "0");
|
|
211
|
-
return `${hh}:${mm}`;
|
|
212
|
-
}
|
|
213
|
-
function rewindCandidatesOf(snap, hidden, limit = DEFAULT_CANDIDATE_LIMIT) {
|
|
214
|
-
const candidates = [];
|
|
215
|
-
for (let i = snap.order.length - 1; i >= 0 && candidates.length < limit; i--) {
|
|
216
|
-
const key = snap.order[i];
|
|
217
|
-
if (key === void 0) continue;
|
|
218
|
-
const node = snap.nodes.get(key);
|
|
219
|
-
if (node === void 0 || node.kind !== "user" && node.kind !== "steering") continue;
|
|
220
|
-
if (hidden.has(node.anchorSeq ?? node.data.seq)) continue;
|
|
221
|
-
candidates.push({
|
|
222
|
-
seq: node.data.seq,
|
|
223
|
-
time: node.data.time,
|
|
224
|
-
preview: messagePreviewOf(node.data)
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
return candidates;
|
|
228
|
-
}
|
|
229
|
-
function rewindCandidatesOfChat(snap) {
|
|
230
|
-
return rewindCandidatesOf(snap, hiddenSeqsOf(snap));
|
|
231
|
-
}
|
|
232
|
-
function rewindOptionsFromCandidates(candidates, t) {
|
|
233
|
-
return candidates.map((candidate) => ({
|
|
234
|
-
id: String(candidate.seq),
|
|
235
|
-
label: candidate.preview || t("popover.noText"),
|
|
236
|
-
detail: formatCandidateTime(candidate.time)
|
|
237
|
-
}));
|
|
166
|
+
return cuts;
|
|
238
167
|
}
|
|
239
168
|
|
|
240
169
|
// src/client/styles.ts
|
|
@@ -503,12 +432,11 @@ function closePopover() {
|
|
|
503
432
|
function findCommand(chat, match) {
|
|
504
433
|
if (chat === void 0) return void 0;
|
|
505
434
|
let found;
|
|
506
|
-
for (const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
}
|
|
435
|
+
for (const node of chatNodesOf(chat)) {
|
|
436
|
+
if (node.kind !== "command") continue;
|
|
437
|
+
const command = node.data;
|
|
438
|
+
if (!match(command)) continue;
|
|
439
|
+
if (found === void 0 || command.seq >= found.seq) found = command;
|
|
512
440
|
}
|
|
513
441
|
return found;
|
|
514
442
|
}
|
|
@@ -516,12 +444,10 @@ function knownCommandSeqs(session, chatOf, match) {
|
|
|
516
444
|
const known = /* @__PURE__ */ new Set();
|
|
517
445
|
const chat = chatOf(session);
|
|
518
446
|
if (chat === void 0) return known;
|
|
519
|
-
for (const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
if (match(command)) known.add(command.seq);
|
|
524
|
-
}
|
|
447
|
+
for (const node of chatNodesOf(chat)) {
|
|
448
|
+
if (node.kind !== "command") continue;
|
|
449
|
+
const command = node.data;
|
|
450
|
+
if (match(command)) known.add(command.seq);
|
|
525
451
|
}
|
|
526
452
|
return known;
|
|
527
453
|
}
|
|
@@ -850,6 +776,293 @@ function openPopover(opts) {
|
|
|
850
776
|
});
|
|
851
777
|
}
|
|
852
778
|
|
|
779
|
+
// src/client/log.ts
|
|
780
|
+
var NS = "dsh-rewind";
|
|
781
|
+
var DEBUG_KEY = "dsh-rewind.debug";
|
|
782
|
+
var ALWAYS_ON = /* @__PURE__ */ new Set(["error", "warn"]);
|
|
783
|
+
function switchValue() {
|
|
784
|
+
try {
|
|
785
|
+
return window.localStorage.getItem(DEBUG_KEY) ?? "";
|
|
786
|
+
} catch {
|
|
787
|
+
return "";
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function matches(value, ns) {
|
|
791
|
+
for (const entry of value.split(",")) {
|
|
792
|
+
const part = entry.trim();
|
|
793
|
+
if (part === "") continue;
|
|
794
|
+
if (part === "*" || part === `${NS}*`) return true;
|
|
795
|
+
if (part.endsWith("*")) {
|
|
796
|
+
if (ns.startsWith(part.slice(0, -1))) return true;
|
|
797
|
+
} else if (ns === part) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return false;
|
|
802
|
+
}
|
|
803
|
+
function tag(scope) {
|
|
804
|
+
return `[${NS}:${scope}]`;
|
|
805
|
+
}
|
|
806
|
+
function log(level, scope, message, data) {
|
|
807
|
+
if (ALWAYS_ON.has(level)) {
|
|
808
|
+
console[level](tag(scope), message, data);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (!matches(switchValue(), `${NS}:${scope}`)) return;
|
|
812
|
+
console.info(tag(scope), message, data);
|
|
813
|
+
}
|
|
814
|
+
var rewindLog = {
|
|
815
|
+
error: (scope, message, data) => log("error", scope, message, data),
|
|
816
|
+
warn: (scope, message, data) => log("warn", scope, message, data),
|
|
817
|
+
info: (scope, message, data) => log("info", scope, message, data),
|
|
818
|
+
debug: (scope, message, data) => log("debug", scope, message, data)
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
// src/client/visibility.ts
|
|
822
|
+
var patches = /* @__PURE__ */ new Map();
|
|
823
|
+
var currentCleanup;
|
|
824
|
+
function installChatViewVisibility(ctx) {
|
|
825
|
+
let stopped = false;
|
|
826
|
+
const start = () => {
|
|
827
|
+
const scope = ctx.inject?.(["uiConversation"], (child) => {
|
|
828
|
+
if (!stopped) installOn(child.get("uiConversation"), ctx.sessions);
|
|
829
|
+
});
|
|
830
|
+
if (ctx.inject === void 0) {
|
|
831
|
+
installOn(ctx.get("uiConversation"), ctx.sessions);
|
|
832
|
+
}
|
|
833
|
+
return () => {
|
|
834
|
+
stopped = true;
|
|
835
|
+
currentCleanup?.();
|
|
836
|
+
currentCleanup = void 0;
|
|
837
|
+
if (typeof scope === "function") scope();
|
|
838
|
+
};
|
|
839
|
+
};
|
|
840
|
+
if (ctx.effect === void 0) {
|
|
841
|
+
start();
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
ctx.effect(start, "dsh-rewind chat visibility");
|
|
845
|
+
}
|
|
846
|
+
function installOn(ui, sessions) {
|
|
847
|
+
currentCleanup?.();
|
|
848
|
+
currentCleanup = void 0;
|
|
849
|
+
if (ui?.views === void 0) return;
|
|
850
|
+
const views = ui.views;
|
|
851
|
+
const ensure = () => {
|
|
852
|
+
try {
|
|
853
|
+
const definition = views.entries().find((candidate) => candidate.target === "chat");
|
|
854
|
+
if (definition === void 0 || typeof definition.create !== "function") return;
|
|
855
|
+
const current = patches.get(definition);
|
|
856
|
+
const create = definition.create;
|
|
857
|
+
if (current !== void 0 && create === current.wrapper) return;
|
|
858
|
+
const wrapper = function wrappedChatBuilder() {
|
|
859
|
+
return new RewindVisibilityBuilder(create.call(definition));
|
|
860
|
+
};
|
|
861
|
+
const mutable = definition;
|
|
862
|
+
mutable.create = wrapper;
|
|
863
|
+
patches.set(definition, { original: create, wrapper });
|
|
864
|
+
rewindLog.info("visibility", "installed Chat snapshot visibility wrapper");
|
|
865
|
+
rebuildOpenSessions(ui, sessions);
|
|
866
|
+
} catch (error) {
|
|
867
|
+
rewindLog.error("visibility", "Chat visibility install probe failed", error);
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
let unsubscribe;
|
|
871
|
+
try {
|
|
872
|
+
unsubscribe = views.subscribe?.(ensure);
|
|
873
|
+
} catch (error) {
|
|
874
|
+
rewindLog.warn("visibility", "Chat view subscription failed", error);
|
|
875
|
+
}
|
|
876
|
+
ensure();
|
|
877
|
+
currentCleanup = () => {
|
|
878
|
+
unsubscribe?.();
|
|
879
|
+
restorePatches();
|
|
880
|
+
rebuildOpenSessions(ui, sessions);
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
function restorePatches() {
|
|
884
|
+
for (const [definition, record] of patches) {
|
|
885
|
+
const mutable = definition;
|
|
886
|
+
if (mutable.create === record.wrapper) mutable.create = record.original;
|
|
887
|
+
}
|
|
888
|
+
patches = /* @__PURE__ */ new Map();
|
|
889
|
+
}
|
|
890
|
+
function rebuildOpenSessions(ui, sessions) {
|
|
891
|
+
const state = sessions?.list?.getSnapshot();
|
|
892
|
+
if (state === void 0) return;
|
|
893
|
+
const ids = /* @__PURE__ */ new Set([...state.ids ?? [], ...Object.keys(state.byId ?? {})]);
|
|
894
|
+
for (const id of ids) {
|
|
895
|
+
const row = state.byId?.[id];
|
|
896
|
+
const retained = row?.retainedBy;
|
|
897
|
+
if (retained === void 0 || !Object.values(retained).some((count) => (count ?? 0) > 0)) continue;
|
|
898
|
+
try {
|
|
899
|
+
ui.binding?.(id)?.rebuild?.();
|
|
900
|
+
} catch (error) {
|
|
901
|
+
rewindLog.warn("visibility", `chat rebuild failed for ${id}`, error);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
var RewindVisibilityBuilder = class {
|
|
906
|
+
/** @param inner - the real Chat builder. */
|
|
907
|
+
constructor(inner) {
|
|
908
|
+
__publicField(this, "inner", inner);
|
|
909
|
+
__publicField(this, "originals", /* @__PURE__ */ new Map());
|
|
910
|
+
__publicField(this, "commands", /* @__PURE__ */ new Map());
|
|
911
|
+
__publicField(this, "byTurn", /* @__PURE__ */ new Map());
|
|
912
|
+
__publicField(this, "turnProcess", /* @__PURE__ */ new Map());
|
|
913
|
+
__publicField(this, "derived", /* @__PURE__ */ new Map());
|
|
914
|
+
__publicField(this, "cuts", []);
|
|
915
|
+
__publicField(this, "cutSignature", "[]");
|
|
916
|
+
__publicField(this, "lastSignature", "[]");
|
|
917
|
+
}
|
|
918
|
+
get empty() {
|
|
919
|
+
return this.inner.empty;
|
|
920
|
+
}
|
|
921
|
+
replace(input) {
|
|
922
|
+
this.setAll(input.nodes);
|
|
923
|
+
this.lastSignature = this.cutSignature;
|
|
924
|
+
return this.inner.replace({ nodes: this.deriveAll(), timeline: input.timeline, ...changed(input) });
|
|
925
|
+
}
|
|
926
|
+
apply(input) {
|
|
927
|
+
const affected = /* @__PURE__ */ new Set();
|
|
928
|
+
let commandsChanged = false;
|
|
929
|
+
for (const node of input.upserts) {
|
|
930
|
+
const previous = this.originals.get(node.key);
|
|
931
|
+
const previousTurn = previous === void 0 ? void 0 : turnOf(previous);
|
|
932
|
+
const nextTurn = turnOf(node);
|
|
933
|
+
if (previousTurn !== void 0) affected.add(previousTurn);
|
|
934
|
+
if (nextTurn !== void 0) affected.add(nextTurn);
|
|
935
|
+
if (previous?.kind === "command" || node.kind === "command") commandsChanged = true;
|
|
936
|
+
this.setOriginal(node);
|
|
937
|
+
}
|
|
938
|
+
if (commandsChanged) this.refreshCuts();
|
|
939
|
+
if (this.cutSignature !== this.lastSignature) {
|
|
940
|
+
this.lastSignature = this.cutSignature;
|
|
941
|
+
return this.inner.replace({ nodes: this.deriveAll(), timeline: input.timeline, ...changed(input) });
|
|
942
|
+
}
|
|
943
|
+
const cuts = this.cuts;
|
|
944
|
+
const upserts = /* @__PURE__ */ new Map();
|
|
945
|
+
for (const node of input.upserts) upserts.set(node.key, this.deriveOne(node, cuts));
|
|
946
|
+
for (const turn of affected) {
|
|
947
|
+
const processKey = this.turnProcess.get(turn);
|
|
948
|
+
const base = processKey === void 0 ? void 0 : this.originals.get(processKey);
|
|
949
|
+
if (base === void 0) continue;
|
|
950
|
+
const next = this.deriveTurnProcess(base, cuts, turn, this.deriveOne(base, cuts));
|
|
951
|
+
if (this.derived.get(processKey) !== next) upserts.set(processKey, next);
|
|
952
|
+
}
|
|
953
|
+
const list = [...upserts.values()];
|
|
954
|
+
for (const node of list) this.derived.set(node.key, node);
|
|
955
|
+
return this.inner.apply({ upserts: list, timeline: input.timeline, ...changed(input) });
|
|
956
|
+
}
|
|
957
|
+
groupInput() {
|
|
958
|
+
return this.inner.groupInput?.();
|
|
959
|
+
}
|
|
960
|
+
publish() {
|
|
961
|
+
this.inner.publish?.();
|
|
962
|
+
}
|
|
963
|
+
setAll(nodes) {
|
|
964
|
+
this.originals.clear();
|
|
965
|
+
this.commands.clear();
|
|
966
|
+
this.byTurn.clear();
|
|
967
|
+
this.turnProcess.clear();
|
|
968
|
+
this.derived.clear();
|
|
969
|
+
for (const node of nodes) this.setOriginal(node);
|
|
970
|
+
this.refreshCuts();
|
|
971
|
+
}
|
|
972
|
+
setOriginal(node) {
|
|
973
|
+
const previous = this.originals.get(node.key);
|
|
974
|
+
if (previous !== void 0) this.unindex(previous);
|
|
975
|
+
this.originals.set(node.key, node);
|
|
976
|
+
if (node.kind === "command") this.commands.set(node.key, node);
|
|
977
|
+
const turn = turnOf(node);
|
|
978
|
+
if (turn === void 0) return;
|
|
979
|
+
const members = this.byTurn.get(turn) ?? /* @__PURE__ */ new Map();
|
|
980
|
+
members.set(node.key, node);
|
|
981
|
+
this.byTurn.set(turn, members);
|
|
982
|
+
if (node.kind === "turn-process") this.turnProcess.set(turn, node.key);
|
|
983
|
+
}
|
|
984
|
+
unindex(node) {
|
|
985
|
+
if (node.kind === "command") this.commands.delete(node.key);
|
|
986
|
+
const turn = turnOf(node);
|
|
987
|
+
if (turn === void 0) return;
|
|
988
|
+
const members = this.byTurn.get(turn);
|
|
989
|
+
if (members === void 0) return;
|
|
990
|
+
members.delete(node.key);
|
|
991
|
+
if (members.size === 0) this.byTurn.delete(turn);
|
|
992
|
+
if (node.kind === "turn-process" && this.turnProcess.get(turn) === node.key) {
|
|
993
|
+
this.turnProcess.delete(turn);
|
|
994
|
+
for (const member of members.values()) {
|
|
995
|
+
if (member.kind === "turn-process") {
|
|
996
|
+
this.turnProcess.set(turn, member.key);
|
|
997
|
+
break;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
refreshCuts() {
|
|
1003
|
+
this.cuts = rewindCutsOf(this.commands.values());
|
|
1004
|
+
this.cutSignature = JSON.stringify(
|
|
1005
|
+
this.cuts.map((cut) => `${cut.target}:${cut.marker}`).sort()
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
1008
|
+
deriveAll() {
|
|
1009
|
+
const cuts = this.cuts;
|
|
1010
|
+
const derived = /* @__PURE__ */ new Map();
|
|
1011
|
+
for (const node of this.originals.values()) derived.set(node.key, this.deriveOne(node, cuts));
|
|
1012
|
+
for (const [turn, key] of this.turnProcess) {
|
|
1013
|
+
const base = this.originals.get(key);
|
|
1014
|
+
if (base === void 0) continue;
|
|
1015
|
+
const current = derived.get(key) ?? this.deriveOne(base, cuts);
|
|
1016
|
+
derived.set(key, this.deriveTurnProcess(base, cuts, turn, current));
|
|
1017
|
+
}
|
|
1018
|
+
const result = [...derived.values()];
|
|
1019
|
+
this.derived = derived;
|
|
1020
|
+
return result;
|
|
1021
|
+
}
|
|
1022
|
+
deriveOne(node, cuts) {
|
|
1023
|
+
const base = this.originals.get(node.key) ?? node;
|
|
1024
|
+
if (base.kind === "command") {
|
|
1025
|
+
const command = base.data;
|
|
1026
|
+
if (command.name !== void 0 && command.name !== null && ENGINE_COMMANDS.has(command.name)) {
|
|
1027
|
+
const args = command.args ?? "";
|
|
1028
|
+
const probe = args.includes("preview") || args.includes("__candidates");
|
|
1029
|
+
const executed = command.outcome?.kind === "success" && command.outcome.sourceEventSeq !== void 0;
|
|
1030
|
+
if (probe || executed) return hidden(base);
|
|
1031
|
+
}
|
|
1032
|
+
return base;
|
|
1033
|
+
}
|
|
1034
|
+
const contained = cuts.some((cut) => cut.target <= base.anchorSeq && base.anchorSeq <= cut.marker);
|
|
1035
|
+
return contained ? hidden(base) : base;
|
|
1036
|
+
}
|
|
1037
|
+
deriveTurnProcess(base, cuts, turn = turnOf(base), current = this.deriveOne(base, cuts)) {
|
|
1038
|
+
if (turn === void 0 || current.visibility === "hidden") return current;
|
|
1039
|
+
const members = this.byTurn.get(turn);
|
|
1040
|
+
if (members === void 0) return current;
|
|
1041
|
+
let count = 0;
|
|
1042
|
+
let allHidden = true;
|
|
1043
|
+
for (const member of members.values()) {
|
|
1044
|
+
if (member.key === base.key) continue;
|
|
1045
|
+
count += 1;
|
|
1046
|
+
if (this.deriveOne(member, cuts).visibility !== "hidden") {
|
|
1047
|
+
allHidden = false;
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
if (count === 0) return current;
|
|
1052
|
+
return allHidden ? hidden(base) : current;
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
function hidden(node) {
|
|
1056
|
+
return node.visibility === "hidden" ? node : { ...node, visibility: "hidden" };
|
|
1057
|
+
}
|
|
1058
|
+
function turnOf(node) {
|
|
1059
|
+
const turn = node.location?.turn?.turn;
|
|
1060
|
+
return typeof turn === "number" ? turn : void 0;
|
|
1061
|
+
}
|
|
1062
|
+
function changed(input) {
|
|
1063
|
+
return input.changedTurns === void 0 ? {} : { changedTurns: input.changedTurns };
|
|
1064
|
+
}
|
|
1065
|
+
|
|
853
1066
|
// src/client/portals.tsx
|
|
854
1067
|
var import_react = require("react");
|
|
855
1068
|
var import_react_dom = require("react-dom");
|
|
@@ -885,11 +1098,11 @@ function matchPendingRows(rows, steering) {
|
|
|
885
1098
|
for (let i = 0; i < rows.length; i++) {
|
|
886
1099
|
const row = rows[i];
|
|
887
1100
|
const item = steering[i];
|
|
888
|
-
matched.push(item !== void 0 &&
|
|
1101
|
+
matched.push(item !== void 0 && matches2(item, row) ? item.id : null);
|
|
889
1102
|
}
|
|
890
1103
|
return matched;
|
|
891
1104
|
}
|
|
892
|
-
function
|
|
1105
|
+
function matches2(item, row) {
|
|
893
1106
|
if (item.attachments > 0) return row.attachments === item.attachments;
|
|
894
1107
|
return row.text === (item.text ?? "");
|
|
895
1108
|
}
|
|
@@ -899,48 +1112,6 @@ function retractSpan(steering, targetId) {
|
|
|
899
1112
|
return steering.slice(index).map((item) => item.id);
|
|
900
1113
|
}
|
|
901
1114
|
|
|
902
|
-
// src/client/log.ts
|
|
903
|
-
var NS = "dsh-rewind";
|
|
904
|
-
var DEBUG_KEY = "dsh-rewind.debug";
|
|
905
|
-
var ALWAYS_ON = /* @__PURE__ */ new Set(["error", "warn"]);
|
|
906
|
-
function switchValue() {
|
|
907
|
-
try {
|
|
908
|
-
return window.localStorage.getItem(DEBUG_KEY) ?? "";
|
|
909
|
-
} catch {
|
|
910
|
-
return "";
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
function matches2(value, ns) {
|
|
914
|
-
for (const entry of value.split(",")) {
|
|
915
|
-
const part = entry.trim();
|
|
916
|
-
if (part === "") continue;
|
|
917
|
-
if (part === "*" || part === `${NS}*`) return true;
|
|
918
|
-
if (part.endsWith("*")) {
|
|
919
|
-
if (ns.startsWith(part.slice(0, -1))) return true;
|
|
920
|
-
} else if (ns === part) {
|
|
921
|
-
return true;
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
return false;
|
|
925
|
-
}
|
|
926
|
-
function tag(scope) {
|
|
927
|
-
return `[${NS}:${scope}]`;
|
|
928
|
-
}
|
|
929
|
-
function log(level, scope, message, data) {
|
|
930
|
-
if (ALWAYS_ON.has(level)) {
|
|
931
|
-
console[level](tag(scope), message, data);
|
|
932
|
-
return;
|
|
933
|
-
}
|
|
934
|
-
if (!matches2(switchValue(), `${NS}:${scope}`)) return;
|
|
935
|
-
console.info(tag(scope), message, data);
|
|
936
|
-
}
|
|
937
|
-
var rewindLog = {
|
|
938
|
-
error: (scope, message, data) => log("error", scope, message, data),
|
|
939
|
-
warn: (scope, message, data) => log("warn", scope, message, data),
|
|
940
|
-
info: (scope, message, data) => log("info", scope, message, data),
|
|
941
|
-
debug: (scope, message, data) => log("debug", scope, message, data)
|
|
942
|
-
};
|
|
943
|
-
|
|
944
1115
|
// src/client/portals.tsx
|
|
945
1116
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
946
1117
|
function fillComposerEditable(text) {
|
|
@@ -1072,7 +1243,6 @@ function showHint(text) {
|
|
|
1072
1243
|
}
|
|
1073
1244
|
var COMPOSER_EDITABLE_SELECTOR = "[data-composer-input]";
|
|
1074
1245
|
var USER_SEAT_SELECTOR = '[data-chat-flow-kind="user"][data-chat-anchor-key], [data-chat-flow-kind="steering"][data-chat-anchor-key]';
|
|
1075
|
-
var CHAT_SEAT_SELECTOR = "[data-chat-anchor-key]";
|
|
1076
1246
|
var IGNORED_PORTAL_SCOPE = [
|
|
1077
1247
|
"[data-composer-seat]",
|
|
1078
1248
|
"[data-composer-input]",
|
|
@@ -1080,14 +1250,6 @@ var IGNORED_PORTAL_SCOPE = [
|
|
|
1080
1250
|
"[data-sidebar-chat]",
|
|
1081
1251
|
"[data-plugin-panel]"
|
|
1082
1252
|
].join(", ");
|
|
1083
|
-
var GROUP_SHELL_SELECTOR = '[data-chat-anchor-key^="group:"]';
|
|
1084
|
-
function resolveSeatAnchorSeq(element, chat) {
|
|
1085
|
-
if (chat === void 0) return void 0;
|
|
1086
|
-
const flowKey = element.dataset.chatAnchorKey;
|
|
1087
|
-
const nodeKey = element.dataset.chatNodeKey;
|
|
1088
|
-
const node = (flowKey !== void 0 ? chat.nodes.get(flowKey) : void 0) ?? (nodeKey !== void 0 ? chat.nodes.get(nodeKey) : void 0);
|
|
1089
|
-
return node?.anchorSeq;
|
|
1090
|
-
}
|
|
1091
1253
|
var PENDING_SEAT_SELECTOR = "[data-pending-steering]";
|
|
1092
1254
|
var MESSAGE_ATTACHMENT_SELECTOR = "[data-message-attachments]";
|
|
1093
1255
|
function actionsContainerOf(row) {
|
|
@@ -1097,47 +1259,7 @@ function actionsContainerOf(row) {
|
|
|
1097
1259
|
if (structural instanceof HTMLElement && structural.querySelector("button") !== null) return structural;
|
|
1098
1260
|
return void 0;
|
|
1099
1261
|
}
|
|
1100
|
-
function
|
|
1101
|
-
if (chat === void 0) return;
|
|
1102
|
-
const shells = /* @__PURE__ */ new Map();
|
|
1103
|
-
for (const seat of seats) {
|
|
1104
|
-
if (seat.matches(GROUP_SHELL_SELECTOR)) continue;
|
|
1105
|
-
const anchor = resolveSeatAnchorSeq(seat, chat);
|
|
1106
|
-
const withdrawn = anchor !== void 0 && hiddenSeqs.has(anchor);
|
|
1107
|
-
if (withdrawn) {
|
|
1108
|
-
seat.style.display = "none";
|
|
1109
|
-
seat.dataset.dshRewindHidden = "true";
|
|
1110
|
-
hidden.add(seat);
|
|
1111
|
-
} else if (hidden.has(seat)) {
|
|
1112
|
-
seat.style.display = "";
|
|
1113
|
-
delete seat.dataset.dshRewindHidden;
|
|
1114
|
-
hidden.delete(seat);
|
|
1115
|
-
}
|
|
1116
|
-
if (seat.dataset.chatNodeKey === void 0) continue;
|
|
1117
|
-
const shell = seat.parentElement?.closest(GROUP_SHELL_SELECTOR);
|
|
1118
|
-
if (shell === null || shell === void 0) continue;
|
|
1119
|
-
shells.set(shell, (shells.get(shell) ?? true) && withdrawn);
|
|
1120
|
-
}
|
|
1121
|
-
for (const [shell, allWithdrawn] of shells) {
|
|
1122
|
-
if (allWithdrawn) {
|
|
1123
|
-
shell.style.display = "none";
|
|
1124
|
-
shell.dataset.dshRewindHidden = "true";
|
|
1125
|
-
hidden.add(shell);
|
|
1126
|
-
} else if (hidden.has(shell)) {
|
|
1127
|
-
shell.style.display = "";
|
|
1128
|
-
delete shell.dataset.dshRewindHidden;
|
|
1129
|
-
hidden.delete(shell);
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
function showHiddenSeats(hidden) {
|
|
1134
|
-
for (const element of hidden) {
|
|
1135
|
-
element.style.display = "";
|
|
1136
|
-
delete element.dataset.dshRewindHidden;
|
|
1137
|
-
}
|
|
1138
|
-
hidden.clear();
|
|
1139
|
-
}
|
|
1140
|
-
function collectTargets(chat, hiddenSeqs) {
|
|
1262
|
+
function collectTargets(chat) {
|
|
1141
1263
|
const rows = /* @__PURE__ */ new Map();
|
|
1142
1264
|
for (const element of document.querySelectorAll(USER_SEAT_SELECTOR)) {
|
|
1143
1265
|
const key = element.dataset.chatAnchorKey;
|
|
@@ -1148,7 +1270,6 @@ function collectTargets(chat, hiddenSeqs) {
|
|
|
1148
1270
|
const node = chat.nodes.get(key);
|
|
1149
1271
|
if (node === void 0 || node.kind !== "user" && node.kind !== "steering") continue;
|
|
1150
1272
|
const user = node.data;
|
|
1151
|
-
if (hiddenSeqs.has(node.anchorSeq ?? user.seq)) continue;
|
|
1152
1273
|
const row = rows.get(key);
|
|
1153
1274
|
const actions = actionsContainerOf(row);
|
|
1154
1275
|
if (actions === void 0) continue;
|
|
@@ -1159,9 +1280,9 @@ function collectTargets(chat, hiddenSeqs) {
|
|
|
1159
1280
|
function isRewindInertSession(snapshot) {
|
|
1160
1281
|
return snapshot.subagent !== null && snapshot.subagent !== void 0;
|
|
1161
1282
|
}
|
|
1162
|
-
function collectDurableTargets(snapshot, chat
|
|
1283
|
+
function collectDurableTargets(snapshot, chat) {
|
|
1163
1284
|
if (chat === void 0 || isRewindInertSession(snapshot)) return [];
|
|
1164
|
-
return collectTargets(chat
|
|
1285
|
+
return collectTargets(chat);
|
|
1165
1286
|
}
|
|
1166
1287
|
function inboxOf(session) {
|
|
1167
1288
|
return session.projections.faceOf(INBOX_PROJECTION).getSnapshot();
|
|
@@ -1210,7 +1331,6 @@ function sameTargets(left, right) {
|
|
|
1210
1331
|
}
|
|
1211
1332
|
function RewindPortals({ sessionId, sessionOf, chatOf, isMainViewSession, watchChat, t, subscribeLocale, setComposerText, restoreImages }) {
|
|
1212
1333
|
const [targets, setTargets] = (0, import_react.useState)([]);
|
|
1213
|
-
const hidden = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
1214
1334
|
const [, forceRender] = (0, import_react.useReducer)((count) => count + 1, 0);
|
|
1215
1335
|
(0, import_react.useEffect)(() => subscribeLocale(() => {
|
|
1216
1336
|
forceRender();
|
|
@@ -1230,17 +1350,7 @@ function RewindPortals({ sessionId, sessionOf, chatOf, isMainViewSession, watchC
|
|
|
1230
1350
|
}
|
|
1231
1351
|
const snapshot = session.getSnapshot();
|
|
1232
1352
|
const chat = chatOf(session);
|
|
1233
|
-
const
|
|
1234
|
-
for (const element of hidden.current) if (!element.isConnected) hidden.current.delete(element);
|
|
1235
|
-
if (hiddenSeqs.size > 0 || hidden.current.size > 0) {
|
|
1236
|
-
hideWithdrawnSeats(
|
|
1237
|
-
chat,
|
|
1238
|
-
chat === void 0 ? [] : document.querySelectorAll(CHAT_SEAT_SELECTOR),
|
|
1239
|
-
hiddenSeqs,
|
|
1240
|
-
hidden.current
|
|
1241
|
-
);
|
|
1242
|
-
}
|
|
1243
|
-
const durable = collectDurableTargets(snapshot, chat, hiddenSeqs);
|
|
1353
|
+
const durable = collectDurableTargets(snapshot, chat);
|
|
1244
1354
|
const next = [...durable, ...collectPendingTargets(snapshot, steeringItemsOf(inboxOf(session)?.["next-step"]))];
|
|
1245
1355
|
setTargets((current) => sameTargets(current, next) ? current : next);
|
|
1246
1356
|
};
|
|
@@ -1268,26 +1378,17 @@ function RewindPortals({ sessionId, sessionOf, chatOf, isMainViewSession, watchC
|
|
|
1268
1378
|
const unsubscribeChat = watchChat(sessionId, queueRefresh);
|
|
1269
1379
|
const observer = new MutationObserver((records) => {
|
|
1270
1380
|
for (const record of records) {
|
|
1271
|
-
if (record.type === "attributes") {
|
|
1272
|
-
const target = record.target;
|
|
1273
|
-
if (target instanceof HTMLElement && hidden.current.has(target) && target.style.display !== "none") {
|
|
1274
|
-
queueRefresh();
|
|
1275
|
-
return;
|
|
1276
|
-
}
|
|
1277
|
-
continue;
|
|
1278
|
-
}
|
|
1279
1381
|
const node = record.target instanceof Element ? record.target : record.target.parentElement;
|
|
1280
1382
|
if (node !== null && node.closest(IGNORED_PORTAL_SCOPE) !== null) continue;
|
|
1281
1383
|
queueRefresh();
|
|
1282
1384
|
return;
|
|
1283
1385
|
}
|
|
1284
1386
|
});
|
|
1285
|
-
observer.observe(document.body, { childList: true, subtree: true
|
|
1387
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
1286
1388
|
return () => {
|
|
1287
1389
|
active = false;
|
|
1288
1390
|
observer.disconnect();
|
|
1289
1391
|
unsubscribeChat();
|
|
1290
|
-
showHiddenSeats(hidden.current);
|
|
1291
1392
|
unsubscribeInbox?.();
|
|
1292
1393
|
unsubscribeInbox = void 0;
|
|
1293
1394
|
inboxOwner = void 0;
|
|
@@ -1475,11 +1576,54 @@ async function candidatesOverRpc(connection, sessionId) {
|
|
|
1475
1576
|
}
|
|
1476
1577
|
|
|
1477
1578
|
// src/client/build-info.ts
|
|
1478
|
-
var PLUGIN_VERSION = true ? "0.
|
|
1579
|
+
var PLUGIN_VERSION = true ? "0.19.1" : "dev";
|
|
1479
1580
|
var PLUGIN_PACKAGE = "dsh-rewind-plugin";
|
|
1480
|
-
var BUILD_HASH = true ? "
|
|
1581
|
+
var BUILD_HASH = true ? "cc2bb5b8" : "dev";
|
|
1481
1582
|
|
|
1482
1583
|
// src/client/locales.ts
|
|
1584
|
+
var en = {
|
|
1585
|
+
"button.aria": "Rewind to this message",
|
|
1586
|
+
"button.title": "Rewind",
|
|
1587
|
+
"button.retract.aria": "Rewind to this pending message",
|
|
1588
|
+
"button.retract.title": "Rewind",
|
|
1589
|
+
"popover.title": "Rewind to this message",
|
|
1590
|
+
"popover.noText": "(no text)",
|
|
1591
|
+
"popover.retract.title": "Rewind to this pending message",
|
|
1592
|
+
"popover.retract.target": "Pending \xB7 {preview}",
|
|
1593
|
+
"popover.retract.hint": "Retracts this pending message and the ones after it, without interrupting the run",
|
|
1594
|
+
"popover.retract.confirm": "Confirm rewind",
|
|
1595
|
+
"popover.chat": "Rewind conversation only",
|
|
1596
|
+
"popover.chat.hint": "Context only; workspace untouched",
|
|
1597
|
+
"popover.both": "Rewind conversation and files",
|
|
1598
|
+
"popover.both.hint": "Context and restore workspace files",
|
|
1599
|
+
"popover.checking": "Checking for file changes\u2026",
|
|
1600
|
+
"popover.noChanges": "No restorable file changes",
|
|
1601
|
+
"popover.backupDisabled": "Snapshots off; the restore may be incomplete",
|
|
1602
|
+
"popover.cancel": "Cancel",
|
|
1603
|
+
"popover.impact.loading": "Fetching impact list\u2026",
|
|
1604
|
+
"popover.impact.failed": "Could not fetch the impact list: {message}",
|
|
1605
|
+
"popover.impact.none": "No tracked file changes after the target; nothing to restore.",
|
|
1606
|
+
"popover.impact.restore": "Restore {path}",
|
|
1607
|
+
"popover.impact.delete": "Delete {path}",
|
|
1608
|
+
"popover.confirm": "Confirm rewind",
|
|
1609
|
+
"popover.back": "Back",
|
|
1610
|
+
"backup.title": "Snapshot backups",
|
|
1611
|
+
"backup.on": "When on, file snapshots are created automatically for file restore.",
|
|
1612
|
+
"backup.off": "When off, no file snapshots are created; file changes made while off cannot be restored.",
|
|
1613
|
+
"cleanup.auto": "Auto cleanup",
|
|
1614
|
+
"cleanup.auto.on": "When enabled, session snapshots idle past the cutoff are cleaned automatically.",
|
|
1615
|
+
"cleanup.auto.off": "When off, snapshots are not cleaned automatically.",
|
|
1616
|
+
"cleanup.maxAge": "Idle time (days)",
|
|
1617
|
+
"cleanup.maxAge.hint": "Snapshot backups of sessions idle longer than this many days are cleaned.",
|
|
1618
|
+
"cleanup.invalid": "Enter a positive integer, or leave blank to use the default",
|
|
1619
|
+
"cleanup.overridden": "Overridden",
|
|
1620
|
+
"cleanup.reset": "Reset to default",
|
|
1621
|
+
"cleanup.save": "Save",
|
|
1622
|
+
"cleanup.saving": "Saving\u2026",
|
|
1623
|
+
"cleanup.saveFailed": "The deployment did not accept these values; they were left for you to correct",
|
|
1624
|
+
"cleanup.readonly": "This deployment stores settings read-only",
|
|
1625
|
+
"cleanup.unavailable": "This plugin is not loaded, so it cannot be configured right now"
|
|
1626
|
+
};
|
|
1483
1627
|
var zh = {
|
|
1484
1628
|
"button.aria": "\u56DE\u9000\u5230\u6B64\u6D88\u606F",
|
|
1485
1629
|
"button.title": "\u56DE\u9000",
|
|
@@ -1523,49 +1667,50 @@ var zh = {
|
|
|
1523
1667
|
"cleanup.readonly": "\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB",
|
|
1524
1668
|
"cleanup.unavailable": "\u8BE5\u63D2\u4EF6\u5F53\u524D\u672A\u52A0\u8F7D\uFF0C\u6682\u65F6\u65E0\u6CD5\u914D\u7F6E"
|
|
1525
1669
|
};
|
|
1526
|
-
var
|
|
1527
|
-
"button.aria": "
|
|
1528
|
-
"button.title": "
|
|
1529
|
-
"button.retract.aria": "
|
|
1530
|
-
"button.retract.title": "
|
|
1531
|
-
"popover.title": "
|
|
1532
|
-
"popover.noText": "
|
|
1533
|
-
"popover.retract.title": "
|
|
1534
|
-
"popover.retract.target": "
|
|
1535
|
-
"popover.retract.hint": "
|
|
1536
|
-
"popover.retract.confirm": "
|
|
1537
|
-
"popover.chat": "
|
|
1538
|
-
"popover.chat.hint": "
|
|
1539
|
-
"popover.both": "
|
|
1540
|
-
"popover.both.hint": "
|
|
1541
|
-
"popover.checking": "
|
|
1542
|
-
"popover.noChanges": "
|
|
1543
|
-
"popover.backupDisabled": "
|
|
1544
|
-
"popover.cancel": "
|
|
1545
|
-
"popover.impact.loading": "
|
|
1546
|
-
"popover.impact.failed": "
|
|
1547
|
-
"popover.impact.none": "
|
|
1548
|
-
"popover.impact.restore": "
|
|
1549
|
-
"popover.impact.delete": "
|
|
1550
|
-
"popover.confirm": "
|
|
1551
|
-
"popover.back": "
|
|
1552
|
-
"backup.title": "
|
|
1553
|
-
"backup.on": "
|
|
1554
|
-
"backup.off": "
|
|
1555
|
-
"cleanup.auto": "
|
|
1556
|
-
"cleanup.auto.on": "
|
|
1557
|
-
"cleanup.auto.off": "
|
|
1558
|
-
"cleanup.maxAge": "
|
|
1559
|
-
"cleanup.maxAge.hint": "
|
|
1560
|
-
"cleanup.invalid": "
|
|
1561
|
-
"cleanup.overridden": "
|
|
1562
|
-
"cleanup.reset": "
|
|
1563
|
-
"cleanup.save": "
|
|
1564
|
-
"cleanup.saving": "
|
|
1565
|
-
"cleanup.saveFailed": "
|
|
1566
|
-
"cleanup.readonly": "
|
|
1567
|
-
"cleanup.unavailable": "
|
|
1670
|
+
var ja = {
|
|
1671
|
+
"button.aria": "\u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u307E\u3067\u5DFB\u304D\u623B\u3059",
|
|
1672
|
+
"button.title": "\u5DFB\u304D\u623B\u3057",
|
|
1673
|
+
"button.retract.aria": "\u3053\u306E\u4FDD\u7559\u4E2D\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u307E\u3067\u5DFB\u304D\u623B\u3059",
|
|
1674
|
+
"button.retract.title": "\u5DFB\u304D\u623B\u3057",
|
|
1675
|
+
"popover.title": "\u3053\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u307E\u3067\u5DFB\u304D\u623B\u3059",
|
|
1676
|
+
"popover.noText": "\uFF08\u30C6\u30AD\u30B9\u30C8\u306A\u3057\uFF09",
|
|
1677
|
+
"popover.retract.title": "\u3053\u306E\u4FDD\u7559\u4E2D\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u307E\u3067\u5DFB\u304D\u623B\u3059",
|
|
1678
|
+
"popover.retract.target": "\u4FDD\u7559\u4E2D \xB7 {preview}",
|
|
1679
|
+
"popover.retract.hint": "\u3053\u306E\u4FDD\u7559\u4E2D\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u3068\u305D\u308C\u4EE5\u964D\u3092\u64A4\u56DE\u3057\u307E\u3059\u3002\u73FE\u5728\u306E\u751F\u6210\u306F\u4E2D\u65AD\u3057\u307E\u305B\u3093",
|
|
1680
|
+
"popover.retract.confirm": "\u5DFB\u304D\u623B\u3057\u3092\u5B9F\u884C",
|
|
1681
|
+
"popover.chat": "\u4F1A\u8A71\u306E\u307F\u5DFB\u304D\u623B\u3059",
|
|
1682
|
+
"popover.chat.hint": "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306E\u307F\u5BFE\u8C61\u3067\u3001\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306F\u5909\u66F4\u3057\u307E\u305B\u3093",
|
|
1683
|
+
"popover.both": "\u4F1A\u8A71\u3068\u30D5\u30A1\u30A4\u30EB\u3092\u5DFB\u304D\u623B\u3059",
|
|
1684
|
+
"popover.both.hint": "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u5DFB\u304D\u623B\u3057\u3001\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u5FA9\u5143\u3057\u307E\u3059",
|
|
1685
|
+
"popover.checking": "\u30D5\u30A1\u30A4\u30EB\u306E\u5909\u66F4\u3092\u78BA\u8A8D\u4E2D\u2026",
|
|
1686
|
+
"popover.noChanges": "\u5FA9\u5143\u3067\u304D\u308B\u30D5\u30A1\u30A4\u30EB\u306E\u5909\u66F4\u306F\u3042\u308A\u307E\u305B\u3093",
|
|
1687
|
+
"popover.backupDisabled": "\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u304C\u7121\u52B9\u306A\u305F\u3081\u3001\u5FA9\u5143\u304C\u4E0D\u5B8C\u5168\u306B\u306A\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059",
|
|
1688
|
+
"popover.cancel": "\u30AD\u30E3\u30F3\u30BB\u30EB",
|
|
1689
|
+
"popover.impact.loading": "\u5F71\u97FF\u30EA\u30B9\u30C8\u3092\u53D6\u5F97\u4E2D\u2026",
|
|
1690
|
+
"popover.impact.failed": "\u5F71\u97FF\u30EA\u30B9\u30C8\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF1A{message}",
|
|
1691
|
+
"popover.impact.none": "\u5BFE\u8C61\u3088\u308A\u5F8C\u306B\u8FFD\u8DE1\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB\u5909\u66F4\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u5FA9\u5143\u3059\u308B\u3082\u306E\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
1692
|
+
"popover.impact.restore": "{path} \u3092\u5FA9\u5143",
|
|
1693
|
+
"popover.impact.delete": "{path} \u3092\u524A\u9664",
|
|
1694
|
+
"popover.confirm": "\u5DFB\u304D\u623B\u3057\u3092\u5B9F\u884C",
|
|
1695
|
+
"popover.back": "\u623B\u308B",
|
|
1696
|
+
"backup.title": "\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u306E\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7",
|
|
1697
|
+
"backup.on": "\u6709\u52B9\u306B\u3059\u308B\u3068\u3001\u30D5\u30A1\u30A4\u30EB\u5FA9\u5143\u7528\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u304C\u81EA\u52D5\u3067\u4F5C\u6210\u3055\u308C\u307E\u3059\u3002",
|
|
1698
|
+
"backup.off": "\u7121\u52B9\u306B\u3059\u308B\u3068\u3001\u30D5\u30A1\u30A4\u30EB\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u306F\u4F5C\u6210\u3055\u308C\u307E\u305B\u3093\u3002\u7121\u52B9\u306A\u9593\u306E\u30D5\u30A1\u30A4\u30EB\u5909\u66F4\u306F\u5FA9\u5143\u3067\u304D\u307E\u305B\u3093\u3002",
|
|
1699
|
+
"cleanup.auto": "\u81EA\u52D5\u30AF\u30EA\u30FC\u30F3\u30A2\u30C3\u30D7",
|
|
1700
|
+
"cleanup.auto.on": "\u6709\u52B9\u306B\u3059\u308B\u3068\u3001\u3057\u304D\u3044\u5024\u3092\u8D85\u3048\u3066\u30A2\u30A4\u30C9\u30EB\u72B6\u614B\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u304C\u81EA\u52D5\u3067\u524A\u9664\u3055\u308C\u307E\u3059\u3002",
|
|
1701
|
+
"cleanup.auto.off": "\u7121\u52B9\u306B\u3059\u308B\u3068\u3001\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u306F\u81EA\u52D5\u3067\u524A\u9664\u3055\u308C\u307E\u305B\u3093\u3002",
|
|
1702
|
+
"cleanup.maxAge": "\u30A2\u30A4\u30C9\u30EB\u6642\u9593\uFF08\u65E5\uFF09",
|
|
1703
|
+
"cleanup.maxAge.hint": "\u3053\u306E\u65E5\u6570\u3092\u8D85\u3048\u3066\u30A2\u30A4\u30C9\u30EB\u72B6\u614B\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u304C\u524A\u9664\u3055\u308C\u307E\u3059\u3002",
|
|
1704
|
+
"cleanup.invalid": "\u6B63\u306E\u6574\u6570\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u7A7A\u6B04\u306E\u5834\u5408\u306F\u65E2\u5B9A\u5024\u3092\u4F7F\u3044\u307E\u3059",
|
|
1705
|
+
"cleanup.overridden": "\u4E0A\u66F8\u304D\u6E08\u307F",
|
|
1706
|
+
"cleanup.reset": "\u65E2\u5B9A\u5024\u306B\u623B\u3059",
|
|
1707
|
+
"cleanup.save": "\u4FDD\u5B58",
|
|
1708
|
+
"cleanup.saving": "\u4FDD\u5B58\u4E2D\u2026",
|
|
1709
|
+
"cleanup.saveFailed": "\u3053\u306E\u30C7\u30D7\u30ED\u30A4\u30E1\u30F3\u30C8\u3067\u306F\u5024\u304C\u53D7\u3051\u4ED8\u3051\u3089\u308C\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u4FEE\u6B63\u3067\u304D\u308B\u3088\u3046\u5165\u529B\u306F\u4FDD\u6301\u3055\u308C\u3066\u3044\u307E\u3059",
|
|
1710
|
+
"cleanup.readonly": "\u3053\u306E\u30C7\u30D7\u30ED\u30A4\u30E1\u30F3\u30C8\u3067\u306F\u8A2D\u5B9A\u304C\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u3059",
|
|
1711
|
+
"cleanup.unavailable": "\u3053\u306E\u30D7\u30E9\u30B0\u30A4\u30F3\u306F\u73FE\u5728\u8AAD\u307F\u8FBC\u307E\u308C\u3066\u3044\u306A\u3044\u305F\u3081\u3001\u8A2D\u5B9A\u3067\u304D\u307E\u305B\u3093"
|
|
1568
1712
|
};
|
|
1713
|
+
var CLIENT_DICTS = { en, zh, ja };
|
|
1569
1714
|
|
|
1570
1715
|
// src/client/settings-card.tsx
|
|
1571
1716
|
var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
@@ -1696,7 +1841,7 @@ var COMPOSER_EDITABLE_SELECTOR2 = "[data-composer-input]";
|
|
|
1696
1841
|
function apply(ctx) {
|
|
1697
1842
|
rewindLog.info("boot", `loaded v${PLUGIN_VERSION} (build ${BUILD_HASH})`);
|
|
1698
1843
|
ctx.effect(function* () {
|
|
1699
|
-
yield ctx.locale.register(NS2,
|
|
1844
|
+
yield ctx.locale.register(NS2, CLIENT_DICTS);
|
|
1700
1845
|
const t = ctx.locale.bind(NS2);
|
|
1701
1846
|
const connection = ctx.get("connection");
|
|
1702
1847
|
registerPreviewCall((sessionId, seq) => previewOverRpc(connection, sessionId, seq));
|
|
@@ -1707,6 +1852,7 @@ function apply(ctx) {
|
|
|
1707
1852
|
style.dataset.plugin = PLUGIN_PACKAGE;
|
|
1708
1853
|
style.textContent = STYLE;
|
|
1709
1854
|
document.head.appendChild(style);
|
|
1855
|
+
installChatViewVisibility(ctx);
|
|
1710
1856
|
const sessionOf = (sessionId) => ctx.sessions.binding(sessionId)?.session;
|
|
1711
1857
|
const isMainViewSession = (sessionId) => (ctx.sessions.list.getSnapshot().byId[sessionId]?.retainedBy.mainView ?? 0) > 0;
|
|
1712
1858
|
const subscribeLocale = (cb) => ctx.locale.subscribe(cb);
|