@chaoset/session-archive 0.1.3 → 0.2.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/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +1 -1
- package/client/client.cjs +214 -135
- package/client/index.tsx +501 -0
- package/lib/config-store.d.ts +32 -0
- package/lib/config-store.d.ts.map +1 -0
- package/lib/config-store.js +107 -0
- package/lib/config-store.js.map +1 -0
- package/lib/index.d.ts +130 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +334 -0
- package/lib/index.js.map +1 -0
- package/lib/remote.d.ts +36 -0
- package/lib/remote.d.ts.map +1 -0
- package/lib/remote.js +108 -0
- package/lib/remote.js.map +1 -0
- package/lib/typert.host.d.ts +62 -0
- package/lib/typert.host.d.ts.map +1 -0
- package/lib/typert.host.js +68 -68
- package/lib/typert.host.js.map +1 -0
- package/package.json +10 -9
- package/lib/config-store.mjs +0 -97
- package/lib/index.mjs +0 -314
- package/lib/remote.mjs +0 -110
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.1.3](https://github.com/winliyou/dsh-plugins) (2026-08-18)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* confirm-delete button hover: red text on red background was unreadable; changed to red background with white text
|
|
8
|
+
|
|
9
|
+
## [0.1.2](https://github.com/winliyou/dsh-plugins) (2026-08-18)
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* keep ghost archived id after deleting archived sessions so in-memory sessions don't reappear in the sidebar
|
|
14
|
+
|
|
15
|
+
## [0.1.1](https://github.com/winliyou/dsh-plugins) (2026-08-17)
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* archived sessions no longer mislabeled as running; restored selectable deletion
|
|
20
|
+
|
|
21
|
+
## [0.1.0](https://github.com/winliyou/dsh-plugins) (2026-08-17)
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* initial session archive plugin: archived session list, read-only detail, batch restore and permanent delete
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-plugins contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -53,11 +53,11 @@ dsh plugin --profile web add @chaoset/session-archive
|
|
|
53
53
|
| `list()` | — | `{ items: ArchiveRow[] }` |
|
|
54
54
|
| `detail(sessionId)` | 会话 id | `{ sessionId, header, title, messageCount, messages, live }` |
|
|
55
55
|
| `delete(sessionIds[])` | id 数组 | `{ deleted, failed, removedFromArchive }` |
|
|
56
|
+
| `unarchive(sessionIds[])` | id 数组 | `{ restored, removedFromArchive }` |
|
|
56
57
|
|
|
57
58
|
> `delete` 的 `removedFromArchive` 恒为 0:删除保留归档 ghost id(见上),
|
|
58
59
|
> 侧边栏不会重新显示已删除的会话;`unarchive` 的 `removedFromArchive` 为
|
|
59
60
|
> 实际从归档集合移除的 id 数。
|
|
60
|
-
| `unarchive(sessionIds[])` | id 数组 | `{ restored, removedFromArchive }` |
|
|
61
61
|
|
|
62
62
|
`ArchiveRow`:`{ sessionId, title, cwd, createdAt, updatedAt, size, live }`。
|
|
63
63
|
|
package/client/client.cjs
CHANGED
|
@@ -3,15 +3,52 @@ window.__ModuleLoader__.load({
|
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
|
-
|
|
6
|
+
"use strict";
|
|
7
|
+
var __create = Object.create;
|
|
8
|
+
var __defProp = Object.defineProperty;
|
|
9
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
10
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
12
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
13
|
+
var __export = (target, all) => {
|
|
14
|
+
for (var name in all)
|
|
15
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
+
for (let key of __getOwnPropNames(from))
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
+
}
|
|
23
|
+
return to;
|
|
24
|
+
};
|
|
25
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
+
mod
|
|
32
|
+
));
|
|
33
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
7
34
|
|
|
8
|
-
//
|
|
35
|
+
// client/index.tsx
|
|
36
|
+
var index_exports = {};
|
|
37
|
+
__export(index_exports, {
|
|
38
|
+
apply: () => apply,
|
|
39
|
+
inject: () => inject
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(index_exports);
|
|
42
|
+
var React = __toESM(require("react"), 1);
|
|
9
43
|
var css = [
|
|
10
44
|
".sa_badge{width:100%;height:49px;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:0 8px 0 6px;font-family:inherit;font-size:14px;display:inline-flex;overflow:hidden}",
|
|
11
45
|
".sa_badge:hover{background:var(--dsw-alias-interactive-bg-hover)}",
|
|
12
|
-
".sa_badgeIcon{flex:none;
|
|
46
|
+
".sa_badgeIcon{flex:none;display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;color:var(--dsw-alias-label-primary)}",
|
|
47
|
+
".sa_badgeIcon svg{width:18px;height:18px;display:block}",
|
|
13
48
|
".sa_badgeLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}",
|
|
14
49
|
".sa_badgeCount{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;margin-left:auto;font-size:12px;line-height:16px}",
|
|
50
|
+
".sa_badge--collapsed{width:auto;justify-content:center;padding:0}",
|
|
51
|
+
".sa_badge--collapsed .sa_badgeLabel,.sa_badge--collapsed .sa_badgeCount{display:none}",
|
|
15
52
|
".sa_panel{z-index:30;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-base);width:440px;max-width:calc(100vw - 24px);max-height:62vh;box-shadow:var(--dsw-shadow-lv2);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);border-radius:12px;flex-direction:column;display:flex;position:fixed;bottom:128px;left:12px;overflow:hidden}",
|
|
16
53
|
".sa_header{box-sizing:border-box;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);flex:none;justify-content:space-between;align-items:center;min-height:44px;padding:8px 12px;display:flex}",
|
|
17
54
|
".sa_title{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}",
|
|
@@ -55,49 +92,48 @@ window.__ModuleLoader__.load({
|
|
|
55
92
|
".sa_busy{opacity:.55;pointer-events:none}"
|
|
56
93
|
].join("");
|
|
57
94
|
var tagId = "@chaoset/session-archive/client.css";
|
|
58
|
-
if (typeof document !== "undefined" && document.querySelector(
|
|
59
|
-
|
|
95
|
+
if (typeof document !== "undefined" && document.querySelector('style[data-plugin-css="' + tagId + '"]') === null) {
|
|
96
|
+
tag = document.createElement("style");
|
|
60
97
|
tag.dataset.plugin = "@chaoset/session-archive";
|
|
61
98
|
tag.dataset.pluginCss = tagId;
|
|
62
99
|
tag.textContent = css;
|
|
63
100
|
document.head.appendChild(tag);
|
|
64
101
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
noMessages: "(无文本消息)",
|
|
102
|
+
var tag;
|
|
103
|
+
var NS = "sidebar.sessionArchive";
|
|
104
|
+
var zh = {
|
|
105
|
+
badge: "\u5F52\u6863",
|
|
106
|
+
panelTitle: "\u5F52\u6863\u4F1A\u8BDD",
|
|
107
|
+
refresh: "\u5237\u65B0",
|
|
108
|
+
close: "\u5173\u95ED",
|
|
109
|
+
empty: "\u6682\u65E0\u5F52\u6863\u4F1A\u8BDD\u3002\u5728\u4F1A\u8BDD\u5217\u8868\u7684\u66F4\u591A\u83DC\u5355\u4E2D\u5F52\u6863\u4F1A\u8BDD\u540E\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002",
|
|
110
|
+
loadFailed: "\u52A0\u8F7D\u5F52\u6863\u5217\u8868\u5931\u8D25",
|
|
111
|
+
selectAll: "\u5168\u9009",
|
|
112
|
+
selected: "\u5DF2\u9009 {n} \u9879",
|
|
113
|
+
restore: "\u6062\u590D\u6240\u9009",
|
|
114
|
+
restoreDone: "\u5DF2\u6062\u590D {n} \u4E2A\u5F52\u6863\u4F1A\u8BDD",
|
|
115
|
+
restoreFailed: "\u6062\u590D\u5931\u8D25",
|
|
116
|
+
delete: "\u5220\u9664\u6240\u9009",
|
|
117
|
+
deleteConfirm: "\u518D\u6B21\u70B9\u51FB\u786E\u8BA4\u5220\u9664",
|
|
118
|
+
deleteDone: "\u5DF2\u5220\u9664 {n} \u4E2A\u5F52\u6863\u4F1A\u8BDD",
|
|
119
|
+
deleteFailed: "\u90E8\u5206\u5220\u9664\u5931\u8D25\uFF1A{n} \u4E2A",
|
|
120
|
+
confirmAll: "\u786E\u8BA4\u5220\u9664\u5168\u90E8 {n} \u4E2A\uFF1F",
|
|
121
|
+
noSelection: "\u8BF7\u5148\u52FE\u9009\u4F1A\u8BDD",
|
|
122
|
+
view: "\u67E5\u770B",
|
|
123
|
+
collapse: "\u6536\u8D77",
|
|
124
|
+
live: "\u8FD0\u884C\u4E2D",
|
|
125
|
+
detailLoadFailed: "\u8BFB\u53D6\u4F1A\u8BDD\u5185\u5BB9\u5931\u8D25",
|
|
126
|
+
noneTitle: "\uFF08\u65E0\u6807\u9898\uFF09",
|
|
127
|
+
user: "\u7528\u6237",
|
|
128
|
+
assistant: "\u52A9\u624B",
|
|
129
|
+
messages: "\u5171 {n} \u6761\u6D88\u606F",
|
|
130
|
+
noMessages: "\uFF08\u65E0\u6587\u672C\u6D88\u606F\uFF09",
|
|
95
131
|
sizeBytes: "{n} B",
|
|
96
132
|
sizeKB: "{n} KB",
|
|
97
133
|
sizeMB: "{n} MB",
|
|
98
|
-
runningHint: "
|
|
134
|
+
runningHint: "\u8FD0\u884C\u4E2D\u7684\u4F1A\u8BDD\u4E0D\u80FD\u5220\u9664\uFF0C\u8BF7\u5148\u505C\u6B62"
|
|
99
135
|
};
|
|
100
|
-
|
|
136
|
+
var en = {
|
|
101
137
|
badge: "Archive",
|
|
102
138
|
panelTitle: "Archived sessions",
|
|
103
139
|
refresh: "Refresh",
|
|
@@ -107,11 +143,11 @@ window.__ModuleLoader__.load({
|
|
|
107
143
|
selectAll: "Select all",
|
|
108
144
|
selected: "{n} selected",
|
|
109
145
|
restore: "Restore",
|
|
110
|
-
restoreDone: "Restored {n} sessions",
|
|
146
|
+
restoreDone: "Restored {n} archived sessions",
|
|
111
147
|
restoreFailed: "Restore failed",
|
|
112
148
|
delete: "Delete",
|
|
113
149
|
deleteConfirm: "Click again to confirm delete",
|
|
114
|
-
deleteDone: "Deleted {n} sessions",
|
|
150
|
+
deleteDone: "Deleted {n} archived sessions",
|
|
115
151
|
deleteFailed: "Some deletions failed: {n}",
|
|
116
152
|
confirmAll: "Delete all {n}?",
|
|
117
153
|
noSelection: "Select sessions first",
|
|
@@ -129,38 +165,54 @@ window.__ModuleLoader__.load({
|
|
|
129
165
|
sizeMB: "{n} MB",
|
|
130
166
|
runningHint: "Running sessions cannot be deleted; stop them first"
|
|
131
167
|
};
|
|
132
|
-
|
|
133
|
-
// ── 工具函数 ─────────────────────────────────────────────────────────
|
|
134
168
|
function formatBytes(bytes, t) {
|
|
135
169
|
if (bytes < 1024) return t("sizeBytes").replace("{n}", String(bytes));
|
|
136
170
|
if (bytes < 1024 * 1024) return t("sizeKB").replace("{n}", (bytes / 1024).toFixed(1));
|
|
137
171
|
return t("sizeMB").replace("{n}", (bytes / (1024 * 1024)).toFixed(1));
|
|
138
172
|
}
|
|
139
173
|
function formatTime(ms) {
|
|
140
|
-
try {
|
|
174
|
+
try {
|
|
175
|
+
return new Date(ms).toLocaleString();
|
|
176
|
+
} catch {
|
|
177
|
+
return String(ms);
|
|
178
|
+
}
|
|
141
179
|
}
|
|
142
180
|
function shortId(id) {
|
|
143
|
-
return id.length > 12 ? id.slice(0, 12) + "
|
|
181
|
+
return id.length > 12 ? id.slice(0, 12) + "\u2026" : id;
|
|
144
182
|
}
|
|
145
|
-
|
|
146
|
-
// ── 归档面板 ─────────────────────────────────────────────────────────
|
|
147
183
|
function ArchivePanel(props) {
|
|
148
184
|
const t = props.t;
|
|
149
185
|
const call = props.call;
|
|
150
|
-
const
|
|
151
|
-
const [
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
186
|
+
const wideExplicit = typeof props.wide === "boolean" ? props.wide : void 0;
|
|
187
|
+
const [narrow, setNarrow] = React.useState(false);
|
|
188
|
+
const collapsed = wideExplicit === void 0 ? narrow : !wideExplicit;
|
|
189
|
+
const badgeRef = React.useRef(null);
|
|
190
|
+
React.useEffect(() => {
|
|
191
|
+
const el = badgeRef.current?.parentElement;
|
|
192
|
+
if (el === void 0 || el === null || typeof globalThis.ResizeObserver === "undefined") return;
|
|
193
|
+
const ro = new globalThis.ResizeObserver((entries) => {
|
|
194
|
+
for (const entry of entries) {
|
|
195
|
+
const w = entry.contentRect?.width ?? el.clientWidth;
|
|
196
|
+
setNarrow(w > 0 && w < 80);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
ro.observe(el);
|
|
200
|
+
return () => ro.disconnect();
|
|
201
|
+
}, []);
|
|
202
|
+
const iconOnly = collapsed;
|
|
203
|
+
const rootRef = React.useRef(null);
|
|
204
|
+
const [open, setOpen] = React.useState(false);
|
|
205
|
+
const [items, setItems] = React.useState([]);
|
|
206
|
+
const [loading, setLoading] = React.useState(false);
|
|
207
|
+
const [error, setError] = React.useState(null);
|
|
208
|
+
const [selected, setSelected] = React.useState(/* @__PURE__ */ new Set());
|
|
209
|
+
const [expanded, setExpanded] = React.useState(null);
|
|
210
|
+
const [details, setDetails] = React.useState(/* @__PURE__ */ new Map());
|
|
211
|
+
const [detailLoading, setDetailLoading] = React.useState(/* @__PURE__ */ new Set());
|
|
212
|
+
const [busy, setBusy] = React.useState(false);
|
|
213
|
+
const [confirmingDelete, setConfirmingDelete] = React.useState(false);
|
|
214
|
+
const [notice, setNotice] = React.useState(null);
|
|
215
|
+
const load = React.useCallback(async () => {
|
|
164
216
|
setLoading(true);
|
|
165
217
|
setError(null);
|
|
166
218
|
try {
|
|
@@ -172,12 +224,38 @@ window.__ModuleLoader__.load({
|
|
|
172
224
|
setLoading(false);
|
|
173
225
|
}
|
|
174
226
|
}, [call, t]);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
227
|
+
React.useEffect(() => {
|
|
228
|
+
if (open) {
|
|
229
|
+
setNotice(null);
|
|
230
|
+
load();
|
|
231
|
+
}
|
|
178
232
|
}, [open, load]);
|
|
179
|
-
|
|
180
|
-
|
|
233
|
+
const refreshSilently = React.useCallback(async () => {
|
|
234
|
+
try {
|
|
235
|
+
const result = await call("list");
|
|
236
|
+
setItems(Array.isArray(result.items) ? result.items : []);
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
}, [call]);
|
|
240
|
+
React.useEffect(() => {
|
|
241
|
+
if (open) return;
|
|
242
|
+
refreshSilently();
|
|
243
|
+
const id = globalThis.setInterval(refreshSilently, 5e3);
|
|
244
|
+
const onVis = () => {
|
|
245
|
+
if (document.visibilityState === "visible") refreshSilently();
|
|
246
|
+
};
|
|
247
|
+
document.addEventListener("visibilitychange", onVis);
|
|
248
|
+
return () => {
|
|
249
|
+
clearInterval(id);
|
|
250
|
+
document.removeEventListener("visibilitychange", onVis);
|
|
251
|
+
};
|
|
252
|
+
}, [open, refreshSilently]);
|
|
253
|
+
React.useEffect(() => {
|
|
254
|
+
if (notice === null) return;
|
|
255
|
+
const id = globalThis.setTimeout(() => setNotice(null), 4e3);
|
|
256
|
+
return () => clearTimeout(id);
|
|
257
|
+
}, [notice]);
|
|
258
|
+
React.useEffect(() => {
|
|
181
259
|
if (!open) return;
|
|
182
260
|
const onPointerDown = (event) => {
|
|
183
261
|
if (rootRef.current !== null && !rootRef.current.contains(event.target)) {
|
|
@@ -187,25 +265,23 @@ window.__ModuleLoader__.load({
|
|
|
187
265
|
document.addEventListener("pointerdown", onPointerDown);
|
|
188
266
|
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
189
267
|
}, [open]);
|
|
190
|
-
|
|
191
268
|
const selectable = items.filter((item) => !item.live);
|
|
192
269
|
const allSelected = selectable.length > 0 && selectable.every((item) => selected.has(item.sessionId));
|
|
193
|
-
|
|
194
270
|
const toggleAll = (checked) => {
|
|
195
271
|
if (checked) {
|
|
196
272
|
setSelected(new Set(selectable.map((item) => item.sessionId)));
|
|
197
273
|
} else {
|
|
198
|
-
setSelected(new Set());
|
|
274
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
199
275
|
}
|
|
200
276
|
};
|
|
201
277
|
const toggleOne = (sessionId, checked) => {
|
|
202
278
|
setSelected((current) => {
|
|
203
279
|
const next = new Set(current);
|
|
204
|
-
if (checked) next.add(sessionId);
|
|
280
|
+
if (checked) next.add(sessionId);
|
|
281
|
+
else next.delete(sessionId);
|
|
205
282
|
return next;
|
|
206
283
|
});
|
|
207
284
|
};
|
|
208
|
-
|
|
209
285
|
const toggleDetail = (item) => {
|
|
210
286
|
if (expanded === item.sessionId) {
|
|
211
287
|
setExpanded(null);
|
|
@@ -229,7 +305,6 @@ window.__ModuleLoader__.load({
|
|
|
229
305
|
});
|
|
230
306
|
}
|
|
231
307
|
};
|
|
232
|
-
|
|
233
308
|
const runBatch = async (action, doneKey, failKey) => {
|
|
234
309
|
const ids = [...selected];
|
|
235
310
|
if (ids.length === 0) {
|
|
@@ -251,7 +326,7 @@ window.__ModuleLoader__.load({
|
|
|
251
326
|
const done = new Set(doneIds);
|
|
252
327
|
setItems((current) => current.filter((item) => !done.has(item.sessionId)));
|
|
253
328
|
}
|
|
254
|
-
setSelected(new Set());
|
|
329
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
255
330
|
setConfirmingDelete(false);
|
|
256
331
|
await load();
|
|
257
332
|
} catch (actionError) {
|
|
@@ -264,49 +339,60 @@ window.__ModuleLoader__.load({
|
|
|
264
339
|
const deleteSelected = () => {
|
|
265
340
|
if (!confirmingDelete) {
|
|
266
341
|
setConfirmingDelete(true);
|
|
267
|
-
window.setTimeout(() => setConfirmingDelete(false),
|
|
342
|
+
window.setTimeout(() => setConfirmingDelete(false), 4e3);
|
|
268
343
|
return;
|
|
269
344
|
}
|
|
270
345
|
runBatch("delete", "deleteDone", "deleteFailed");
|
|
271
346
|
};
|
|
272
|
-
|
|
273
347
|
const hasSelection = selected.size > 0;
|
|
274
|
-
|
|
275
|
-
return react.createElement(
|
|
348
|
+
return React.createElement(
|
|
276
349
|
"div",
|
|
277
350
|
{ className: "sa_root", ref: rootRef },
|
|
278
|
-
|
|
351
|
+
React.createElement(
|
|
279
352
|
"button",
|
|
280
353
|
{
|
|
281
|
-
|
|
354
|
+
ref: badgeRef,
|
|
355
|
+
className: "sa_badge" + (iconOnly ? " sa_badge--collapsed" : ""),
|
|
282
356
|
type: "button",
|
|
283
357
|
onClick: () => setOpen(!open),
|
|
284
358
|
"aria-expanded": open,
|
|
285
359
|
title: t("badge")
|
|
286
360
|
},
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
361
|
+
React.createElement(
|
|
362
|
+
"span",
|
|
363
|
+
{ className: "sa_badgeIcon", "aria-hidden": true },
|
|
364
|
+
React.createElement(
|
|
365
|
+
"svg",
|
|
366
|
+
{ viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" },
|
|
367
|
+
React.createElement("rect", { x: 3, y: 4, width: 18, height: 4, rx: 1 }),
|
|
368
|
+
React.createElement("path", { d: "M5 8v11a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8" }),
|
|
369
|
+
React.createElement("path", { d: "M10 12h4" })
|
|
370
|
+
)
|
|
371
|
+
),
|
|
372
|
+
iconOnly ? null : React.createElement("span", { className: "sa_badgeLabel" }, t("badge")),
|
|
373
|
+
iconOnly ? null : React.createElement("span", { className: "sa_badgeCount" }, String(items.length))
|
|
290
374
|
),
|
|
291
|
-
open ?
|
|
375
|
+
open ? React.createElement(
|
|
292
376
|
"div",
|
|
293
377
|
{ className: "sa_panel" },
|
|
294
|
-
|
|
378
|
+
React.createElement(
|
|
295
379
|
"div",
|
|
296
380
|
{ className: "sa_header" },
|
|
297
|
-
|
|
298
|
-
|
|
381
|
+
React.createElement("span", { className: "sa_title" }, t("panelTitle")),
|
|
382
|
+
React.createElement(
|
|
299
383
|
"span",
|
|
300
384
|
{ style: { display: "inline-flex", gap: "6px", alignItems: "center" } },
|
|
301
|
-
|
|
302
|
-
|
|
385
|
+
React.createElement("button", { className: "sa_refresh", type: "button", title: t("refresh"), disabled: busy || loading, onClick: load }, t("refresh")),
|
|
386
|
+
React.createElement("button", { className: "sa_iconBtn", type: "button", title: t("close"), disabled: busy, onClick: () => setOpen(false) }, "\u2715")
|
|
303
387
|
)
|
|
304
388
|
),
|
|
305
|
-
|
|
389
|
+
React.createElement(
|
|
306
390
|
"div",
|
|
307
391
|
{ className: "sa_toolbar" },
|
|
308
|
-
|
|
309
|
-
|
|
392
|
+
React.createElement(
|
|
393
|
+
"label",
|
|
394
|
+
{ className: "sa_toolLabel" },
|
|
395
|
+
React.createElement("input", {
|
|
310
396
|
className: "sa_check",
|
|
311
397
|
type: "checkbox",
|
|
312
398
|
checked: allSelected,
|
|
@@ -315,41 +401,41 @@ window.__ModuleLoader__.load({
|
|
|
315
401
|
}),
|
|
316
402
|
t("selectAll")
|
|
317
403
|
),
|
|
318
|
-
|
|
319
|
-
|
|
404
|
+
React.createElement("span", { className: "sa_count" }, t("selected").replace("{n}", String(selected.size))),
|
|
405
|
+
React.createElement("button", {
|
|
320
406
|
className: "sa_action",
|
|
321
407
|
type: "button",
|
|
322
408
|
disabled: busy || !hasSelection,
|
|
323
409
|
onClick: restoreSelected
|
|
324
410
|
}, t("restore")),
|
|
325
|
-
|
|
411
|
+
React.createElement("button", {
|
|
326
412
|
className: "sa_action " + (confirmingDelete ? "sa_actionDanger sa_confirm" : "sa_actionDanger"),
|
|
327
413
|
type: "button",
|
|
328
414
|
disabled: busy || !hasSelection,
|
|
329
415
|
onClick: deleteSelected
|
|
330
416
|
}, confirmingDelete ? t("deleteConfirm") : t("delete"))
|
|
331
417
|
),
|
|
332
|
-
|
|
418
|
+
React.createElement(
|
|
333
419
|
"div",
|
|
334
420
|
{ className: "sa_body" },
|
|
335
|
-
notice !== null ?
|
|
336
|
-
error !== null ?
|
|
337
|
-
loading && items.length === 0 ?
|
|
338
|
-
!loading && items.length === 0 && error === null ?
|
|
339
|
-
items.length > 0 ?
|
|
421
|
+
notice !== null ? React.createElement("p", { className: "sa_error" + (notice.kind === "ok" ? "" : ""), role: "status" }, notice.text) : null,
|
|
422
|
+
error !== null ? React.createElement("p", { className: "sa_error", role: "alert" }, error) : null,
|
|
423
|
+
loading && items.length === 0 ? React.createElement("p", { className: "sa_empty" }, "\u2026") : null,
|
|
424
|
+
!loading && items.length === 0 && error === null ? React.createElement("p", { className: "sa_empty" }, t("empty")) : null,
|
|
425
|
+
items.length > 0 ? React.createElement(
|
|
340
426
|
"ul",
|
|
341
427
|
{ className: "sa_rows" },
|
|
342
428
|
items.map((item) => {
|
|
343
429
|
const isExpanded = expanded === item.sessionId;
|
|
344
430
|
const detail = details.get(item.sessionId);
|
|
345
431
|
const detailPending = detailLoading.has(item.sessionId);
|
|
346
|
-
return
|
|
432
|
+
return React.createElement(
|
|
347
433
|
"li",
|
|
348
434
|
{ className: "sa_row" + (busy ? " sa_busy" : ""), key: item.sessionId },
|
|
349
|
-
|
|
435
|
+
React.createElement(
|
|
350
436
|
"div",
|
|
351
437
|
{ className: "sa_rowHead" },
|
|
352
|
-
|
|
438
|
+
React.createElement("input", {
|
|
353
439
|
className: "sa_check",
|
|
354
440
|
type: "checkbox",
|
|
355
441
|
checked: selected.has(item.sessionId),
|
|
@@ -357,31 +443,33 @@ window.__ModuleLoader__.load({
|
|
|
357
443
|
title: item.live ? t("runningHint") : void 0,
|
|
358
444
|
onChange: (e) => toggleOne(item.sessionId, e.target.checked)
|
|
359
445
|
}),
|
|
360
|
-
|
|
446
|
+
React.createElement(
|
|
361
447
|
"span",
|
|
362
448
|
{ className: "sa_rowTitle", onClick: () => toggleDetail(item), title: t("view") },
|
|
363
449
|
item.title !== null && item.title !== void 0 && item.title !== "" ? item.title : t("noneTitle")
|
|
364
450
|
),
|
|
365
|
-
item.live ?
|
|
451
|
+
item.live ? React.createElement("span", { className: "sa_live" }, t("live")) : null
|
|
366
452
|
),
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
453
|
+
React.createElement(
|
|
454
|
+
"div",
|
|
455
|
+
{ className: "sa_rowMeta" },
|
|
456
|
+
React.createElement("span", null, formatTime(item.updatedAt)),
|
|
457
|
+
item.cwd !== null && item.cwd !== void 0 ? React.createElement("span", null, " \xB7 ", React.createElement("code", null, item.cwd)) : null,
|
|
458
|
+
React.createElement("span", null, " \xB7 ", formatBytes(item.size, t))
|
|
371
459
|
),
|
|
372
|
-
|
|
460
|
+
React.createElement(
|
|
373
461
|
"div",
|
|
374
462
|
{ className: "sa_rowFoot" },
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
463
|
+
React.createElement(
|
|
464
|
+
"span",
|
|
465
|
+
{ className: "sa_rowMeta" },
|
|
466
|
+
React.createElement("code", null, shortId(item.sessionId)),
|
|
467
|
+
detail !== void 0 && !detail.error && detail.messageCount !== void 0 ? " \xB7 " + t("messages").replace("{n}", String(detail.messageCount)) : null
|
|
380
468
|
),
|
|
381
|
-
|
|
469
|
+
React.createElement(
|
|
382
470
|
"div",
|
|
383
471
|
{ className: "sa_rowActions" },
|
|
384
|
-
|
|
472
|
+
React.createElement("button", {
|
|
385
473
|
className: "sa_action",
|
|
386
474
|
type: "button",
|
|
387
475
|
disabled: busy || detailPending,
|
|
@@ -389,19 +477,16 @@ window.__ModuleLoader__.load({
|
|
|
389
477
|
}, isExpanded ? t("collapse") : t("view"))
|
|
390
478
|
)
|
|
391
479
|
),
|
|
392
|
-
isExpanded ?
|
|
480
|
+
isExpanded ? React.createElement(
|
|
393
481
|
"div",
|
|
394
482
|
{ className: "sa_detail" },
|
|
395
|
-
detailPending ?
|
|
396
|
-
detail === void 0 ? null :
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
react.createElement("span", { className: "sa_msgRole" }, message.role === "user" ? t("user") : t("assistant") + " · " + formatTime(message.time)),
|
|
403
|
-
react.createElement("span", { className: "sa_msgText" + (message.role === "user" ? " sa_msgTextUser" : "") }, message.text)
|
|
404
|
-
))
|
|
483
|
+
detailPending ? React.createElement("p", { className: "sa_empty" }, "\u2026") : null,
|
|
484
|
+
detail === void 0 ? null : detail.error !== void 0 ? React.createElement("p", { className: "sa_error" }, detail.error) : detail.messages.length === 0 ? React.createElement("p", { className: "sa_empty" }, t("noMessages")) : detail.messages.map((message, index) => React.createElement(
|
|
485
|
+
"div",
|
|
486
|
+
{ className: "sa_msg", key: index },
|
|
487
|
+
React.createElement("span", { className: "sa_msgRole" }, message.role === "user" ? t("user") : t("assistant") + " \xB7 " + formatTime(message.time)),
|
|
488
|
+
React.createElement("span", { className: "sa_msgText" + (message.role === "user" ? " sa_msgTextUser" : "") }, message.text)
|
|
489
|
+
))
|
|
405
490
|
) : null
|
|
406
491
|
);
|
|
407
492
|
})
|
|
@@ -410,13 +495,9 @@ window.__ModuleLoader__.load({
|
|
|
410
495
|
) : null
|
|
411
496
|
);
|
|
412
497
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
// ctx.remote.$mount(contribution) 显式挂载(官方 dsh-api-remotes 即如此)。
|
|
417
|
-
const inject = ["slots", "locale", "remote"];
|
|
418
|
-
const passthroughSchema = { parse: (value) => value };
|
|
419
|
-
const REMOTE_CONTRIBUTION = {
|
|
498
|
+
var inject = ["slots", "locale", "remote"];
|
|
499
|
+
var passthroughSchema = { parse: (value) => value };
|
|
500
|
+
var REMOTE_CONTRIBUTION = {
|
|
420
501
|
package: "@chaoset/session-archive",
|
|
421
502
|
descriptors: [
|
|
422
503
|
{ id: "@chaoset/session-archive#sessionArchive/list", service: "sessionArchive", namespace: "sessionArchive", method: "list", invocation: { kind: "direct" }, parameters: [], result: { mode: "strict", typeSymbol: "sessionArchive/list:result", schema: passthroughSchema } },
|
|
@@ -444,8 +525,6 @@ window.__ModuleLoader__.load({
|
|
|
444
525
|
}, ArchivePanel));
|
|
445
526
|
}
|
|
446
527
|
|
|
447
|
-
exports.apply = apply;
|
|
448
|
-
exports.inject = inject;
|
|
449
528
|
return module.exports;
|
|
450
529
|
}
|
|
451
530
|
});
|