@lmzhen/dsh-evolution-merge-ui 0.32.5 → 0.33.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.md +3 -15
- package/lib/client.js +480 -222
- package/lib/types/client/MergeStore.d.ts +4 -0
- package/lib/types/client/Panel.d.ts +1 -2
- package/lib/types/client/index.d.ts +2 -2
- package/lib/types/client/platform-modal.d.ts +15 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
# @lmzhen/dsh-evolution-merge-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Skill-merge view inside the shared evolution workbench. It ships only in the `all` installation form.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The view is read-only: action buttons copy the appropriate `/evolution merge` or `/evolution doctor` command; they do not approve, execute, or undo a merge in the browser. Internal run fields (run id, stage, parent, result ref) live under the view's run-details disclosure so the queue and decision facts come first.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
## 什么时候会用到
|
|
10
|
-
|
|
11
|
-
你想看合并提议/历史时。
|
|
12
|
-
|
|
13
|
-
## 默认 / 前提
|
|
14
|
-
|
|
15
|
-
只有 all 安装形态带这个面板。
|
|
16
|
-
|
|
17
|
-
## 边界
|
|
18
|
-
|
|
19
|
-
面板只读;实际合并用命令。
|
|
7
|
+
The host entry intentionally registers nothing. The Loader discovers the `dsh.client` manifest and serves the browser bundle, which registers itself into `evolution.workbench.view` and uses the shared client-kit lifecycle and the four merge read routes.
|
package/lib/client.js
CHANGED
|
@@ -5,28 +5,24 @@ window.__ModuleLoader__.load({
|
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
7
|
let react = require("react");
|
|
8
|
-
//#region ../evolution-client-kit/src/
|
|
9
|
-
function interpolate(text, values) {
|
|
10
|
-
if (values === void 0) return text;
|
|
11
|
-
return text.replace(/\{(\w+)\}/g, (_match, key) => String(values[key] ?? ""));
|
|
12
|
-
}
|
|
8
|
+
//#region ../evolution-client-kit/src/workbench-view.ts
|
|
13
9
|
function injectStyles(doc, css, tagId) {
|
|
14
10
|
if (doc === void 0) return () => {};
|
|
15
11
|
doc.querySelector("style[data-plugin-css=\"" + tagId + "\"]")?.remove();
|
|
16
12
|
const tag = doc.createElement("style");
|
|
17
13
|
tag.setAttribute("data-plugin-css", tagId);
|
|
18
14
|
tag.textContent = css;
|
|
19
|
-
doc.head.
|
|
15
|
+
doc.head.appendChild(tag);
|
|
20
16
|
return () => {
|
|
21
17
|
tag.remove();
|
|
22
18
|
};
|
|
23
19
|
}
|
|
24
20
|
/**
|
|
25
|
-
* Register one
|
|
26
|
-
* @param ctx -
|
|
27
|
-
* @param spec -
|
|
21
|
+
* Register one view into `evolution.workbench.view`.
|
|
22
|
+
* @param ctx - client cordis context.
|
|
23
|
+
* @param spec - view identity, copy, styles, component and face factory.
|
|
28
24
|
*/
|
|
29
|
-
function
|
|
25
|
+
function registerWorkbenchView(ctx, spec) {
|
|
30
26
|
const seam = ctx;
|
|
31
27
|
let registered = false;
|
|
32
28
|
ctx.effect(() => {
|
|
@@ -35,12 +31,12 @@ window.__ModuleLoader__.load({
|
|
|
35
31
|
registered = true;
|
|
36
32
|
return dispose;
|
|
37
33
|
} catch (error) {
|
|
38
|
-
ctx.logger.warn(spec.namespace + ":
|
|
34
|
+
ctx.logger.warn(spec.namespace + ": locale refused (" + String(error) + "); the view falls back to the bundle copy");
|
|
39
35
|
return () => {};
|
|
40
36
|
}
|
|
41
37
|
}, spec.namespace + ": locale");
|
|
42
38
|
ctx.effect(() => injectStyles(typeof document === "undefined" ? void 0 : document, spec.styles.css, spec.styles.tagId), spec.namespace + ": styles");
|
|
43
|
-
const fallback = spec.dictionaries
|
|
39
|
+
const fallback = spec.dictionaries.zh;
|
|
44
40
|
const lookup = (key) => {
|
|
45
41
|
const own = fallback[key] ?? key;
|
|
46
42
|
if (!registered) return own;
|
|
@@ -50,47 +46,36 @@ window.__ModuleLoader__.load({
|
|
|
50
46
|
return own;
|
|
51
47
|
}
|
|
52
48
|
};
|
|
53
|
-
const t = (key, values) =>
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
const t = (key, values) => {
|
|
50
|
+
const template = lookup(key);
|
|
51
|
+
if (values === void 0) return template;
|
|
52
|
+
return template.replace(/\{(\w+)\}/g, (match, slot) => values[slot] === void 0 ? match : String(values[slot]));
|
|
53
|
+
};
|
|
54
|
+
seam.slots.inject("evolution.workbench.view", function* () {
|
|
56
55
|
yield seam.slots.register({
|
|
57
|
-
name: "
|
|
56
|
+
name: "evolution.workbench.view",
|
|
58
57
|
id: spec.id,
|
|
59
58
|
order: spec.order,
|
|
60
|
-
label
|
|
61
|
-
|
|
62
|
-
yield seam.slots.register({
|
|
63
|
-
name: "main",
|
|
64
|
-
key: spec.id,
|
|
65
|
-
inject: () => spec.body(t)
|
|
59
|
+
label: () => t("entry.label"),
|
|
60
|
+
inject: () => spec.face(t)
|
|
66
61
|
}, spec.component);
|
|
67
62
|
});
|
|
68
63
|
}
|
|
69
64
|
//#endregion
|
|
70
|
-
//#region ../evolution-client-kit/src/
|
|
65
|
+
//#region ../evolution-client-kit/src/generated/routes.generated.ts
|
|
71
66
|
/**
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
67
|
+
* Every family host path, generated from evolution-core's HOST_ROUTES (the ONE declaration).
|
|
68
|
+
* A browser half cannot import the host package at runtime (client bundles keep @deepseek-ai/*
|
|
69
|
+
* external), so the table is mirrored here mechanically; a rename in core regenerates all three
|
|
70
|
+
* client copies, and the generator's --check makes a stale copy red.
|
|
75
71
|
*/
|
|
76
|
-
|
|
77
|
-
const get = ctx.get;
|
|
78
|
-
if (typeof get !== "function") return void 0;
|
|
79
|
-
for (const name of ["workspace", "uiWorkspace"]) try {
|
|
80
|
-
const seat = get.call(ctx, name);
|
|
81
|
-
const id = seat?.workspaceId ?? seat?.currentWorkspaceId;
|
|
82
|
-
if (typeof id === "string" && id.trim() !== "") return id;
|
|
83
|
-
} catch {}
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region src/client/api.ts
|
|
87
|
-
/** Read-only merge wire client. Classifies every failure and never writes. */
|
|
88
|
-
const HOST_ROUTES = {
|
|
72
|
+
const ROUTES = {
|
|
89
73
|
approval: {
|
|
90
74
|
pending: "/api/dsh-evolution/approval/pending",
|
|
91
75
|
preview: "/api/dsh-evolution/approval/preview",
|
|
92
76
|
approve: "/api/dsh-evolution/approval/approve",
|
|
93
|
-
reject: "/api/dsh-evolution/approval/reject"
|
|
77
|
+
reject: "/api/dsh-evolution/approval/reject",
|
|
78
|
+
release: "/api/dsh-evolution/approval/release"
|
|
94
79
|
},
|
|
95
80
|
"skill-history": {
|
|
96
81
|
skills: "/api/dsh-evolution/skill-history/skills",
|
|
@@ -109,8 +94,166 @@ window.__ModuleLoader__.load({
|
|
|
109
94
|
body: "/api/dsh-evolution/merge/body",
|
|
110
95
|
history: "/api/dsh-evolution/merge/history"
|
|
111
96
|
},
|
|
112
|
-
diagnostics: { view: "/api/dsh-evolution/diagnostics" }
|
|
113
|
-
|
|
97
|
+
diagnostics: { view: "/api/dsh-evolution/diagnostics" },
|
|
98
|
+
settings: {
|
|
99
|
+
describe: "/api/dsh-evolution/settings/describe",
|
|
100
|
+
mutate: "/api/dsh-evolution/settings/mutate"
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region ../evolution-client-kit/src/settings-seat.ts
|
|
105
|
+
const SETTINGS_DESCRIBE = ROUTES.settings.describe;
|
|
106
|
+
const SETTINGS_MUTATE = ROUTES.settings.mutate;
|
|
107
|
+
const EMPTY = Object.freeze({
|
|
108
|
+
status: "unavailable",
|
|
109
|
+
value: void 0,
|
|
110
|
+
user: void 0,
|
|
111
|
+
writable: false,
|
|
112
|
+
base: void 0,
|
|
113
|
+
revision: void 0,
|
|
114
|
+
reason: "transport"
|
|
115
|
+
});
|
|
116
|
+
function snapshotFrom(value, ns) {
|
|
117
|
+
if (typeof value !== "object" || value === null) return EMPTY;
|
|
118
|
+
const list = value.namespaces;
|
|
119
|
+
if (!Array.isArray(list)) return EMPTY;
|
|
120
|
+
const item = list.find((candidate) => typeof candidate === "object" && candidate !== null && candidate.ns === ns);
|
|
121
|
+
return item === void 0 ? {
|
|
122
|
+
...EMPTY,
|
|
123
|
+
reason: "not-served"
|
|
124
|
+
} : item;
|
|
125
|
+
}
|
|
126
|
+
async function describe(namespace) {
|
|
127
|
+
try {
|
|
128
|
+
const response = await fetch(SETTINGS_DESCRIBE, { headers: { accept: "application/json" } });
|
|
129
|
+
if (!response.ok) return EMPTY;
|
|
130
|
+
const body = await response.json();
|
|
131
|
+
if (body.ok !== true) return EMPTY;
|
|
132
|
+
return snapshotFrom(body.data, namespace);
|
|
133
|
+
} catch {
|
|
134
|
+
return EMPTY;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function write(namespace, ops, expectedRevision) {
|
|
138
|
+
try {
|
|
139
|
+
const response = await fetch(SETTINGS_MUTATE, {
|
|
140
|
+
method: "POST",
|
|
141
|
+
headers: {
|
|
142
|
+
"content-type": "application/json",
|
|
143
|
+
accept: "application/json"
|
|
144
|
+
},
|
|
145
|
+
body: JSON.stringify({
|
|
146
|
+
ns: namespace,
|
|
147
|
+
ops,
|
|
148
|
+
...expectedRevision === void 0 ? {} : { expectedRevision }
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
if (!response.ok) return { ok: false };
|
|
152
|
+
const body = await response.json();
|
|
153
|
+
return {
|
|
154
|
+
ok: body.ok === true,
|
|
155
|
+
snapshot: snapshotFrom(body.data, namespace)
|
|
156
|
+
};
|
|
157
|
+
} catch {
|
|
158
|
+
return { ok: false };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function createForm(namespace, ctx) {
|
|
162
|
+
let snapshot = {
|
|
163
|
+
...EMPTY,
|
|
164
|
+
reason: "seat-missing"
|
|
165
|
+
};
|
|
166
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
167
|
+
let started = false;
|
|
168
|
+
let listening = false;
|
|
169
|
+
const notify = () => {
|
|
170
|
+
for (const listener of listeners) listener();
|
|
171
|
+
};
|
|
172
|
+
const refresh = async () => {
|
|
173
|
+
snapshot = await describe(namespace);
|
|
174
|
+
notify();
|
|
175
|
+
};
|
|
176
|
+
const start = () => {
|
|
177
|
+
if (started) return;
|
|
178
|
+
started = true;
|
|
179
|
+
if (!listening) {
|
|
180
|
+
listening = true;
|
|
181
|
+
(ctx.get?.("remote"))?.$on?.("settings/document-updated", (changed) => {
|
|
182
|
+
if (changed === namespace) refresh();
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
refresh();
|
|
186
|
+
};
|
|
187
|
+
const form = {
|
|
188
|
+
getSnapshot: () => snapshot,
|
|
189
|
+
subscribe: (listener) => {
|
|
190
|
+
listeners.add(listener);
|
|
191
|
+
start();
|
|
192
|
+
return () => {
|
|
193
|
+
listeners.delete(listener);
|
|
194
|
+
};
|
|
195
|
+
},
|
|
196
|
+
set: async (field, value) => await form.mutate([{
|
|
197
|
+
op: "set",
|
|
198
|
+
path: [field],
|
|
199
|
+
value
|
|
200
|
+
}]),
|
|
201
|
+
unset: async (field) => await form.mutate([{
|
|
202
|
+
op: "unset",
|
|
203
|
+
path: [field]
|
|
204
|
+
}]),
|
|
205
|
+
mutate: async (ops, expectedRevision) => {
|
|
206
|
+
const outcome = await write(namespace, ops, expectedRevision ?? snapshot.revision);
|
|
207
|
+
if (outcome.snapshot !== void 0) {
|
|
208
|
+
snapshot = outcome.snapshot;
|
|
209
|
+
notify();
|
|
210
|
+
} else await refresh();
|
|
211
|
+
return outcome.ok;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
return form;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Build one cached form per family namespace over the family settings routes.
|
|
218
|
+
* @param ctx - the client plugin context (remote subscription is optional).
|
|
219
|
+
* @returns the seat; each namespace is served by /api/dsh-evolution/settings/*.
|
|
220
|
+
*/
|
|
221
|
+
const seats = /* @__PURE__ */ new WeakMap();
|
|
222
|
+
function createSettingsSeat(ctx) {
|
|
223
|
+
const cached = seats.get(ctx);
|
|
224
|
+
if (cached !== void 0) return cached;
|
|
225
|
+
const forms = /* @__PURE__ */ new Map();
|
|
226
|
+
const seat = { get(namespace) {
|
|
227
|
+
let form = forms.get(namespace);
|
|
228
|
+
if (form === void 0) {
|
|
229
|
+
form = createForm(namespace, ctx);
|
|
230
|
+
forms.set(namespace, form);
|
|
231
|
+
}
|
|
232
|
+
return form;
|
|
233
|
+
} };
|
|
234
|
+
seats.set(ctx, seat);
|
|
235
|
+
return seat;
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
//#region ../evolution-client-kit/src/workspace.ts
|
|
239
|
+
/**
|
|
240
|
+
* Best-effort workspace id; a seat that is absent or refuses leaves the panel in local scope.
|
|
241
|
+
* @param ctx - the client context.
|
|
242
|
+
* @returns the current workspace id, or undefined.
|
|
243
|
+
*/
|
|
244
|
+
function panelWorkspaceId(ctx) {
|
|
245
|
+
const get = ctx.get;
|
|
246
|
+
if (typeof get !== "function") return void 0;
|
|
247
|
+
for (const name of ["workspace", "uiWorkspace"]) try {
|
|
248
|
+
const seat = get.call(ctx, name);
|
|
249
|
+
const id = seat?.workspaceId ?? seat?.currentWorkspaceId;
|
|
250
|
+
if (typeof id === "string" && id.trim() !== "") return id;
|
|
251
|
+
} catch {}
|
|
252
|
+
}
|
|
253
|
+
//#endregion
|
|
254
|
+
//#region src/client/api.ts
|
|
255
|
+
/** Read-only merge wire client. Classifies every failure and never writes. */
|
|
256
|
+
const HOST_ROUTES = ROUTES.merge;
|
|
114
257
|
const isBlocked = (failure) => failure.kind === "blocked";
|
|
115
258
|
const asReadiness = (value) => {
|
|
116
259
|
const raw = typeof value === "object" && value !== null ? value : {};
|
|
@@ -348,7 +491,7 @@ window.__ModuleLoader__.load({
|
|
|
348
491
|
startCommands: facts.startCommands,
|
|
349
492
|
notes: [...facts.notes],
|
|
350
493
|
degraded: facts.degraded,
|
|
351
|
-
...facts.
|
|
494
|
+
...facts.active === null && facts.last === null ? {} : { latestRun: toRun(facts.active ?? facts.last) },
|
|
352
495
|
approval: {
|
|
353
496
|
mergeApproval: facts.approval.mergeApproval,
|
|
354
497
|
...platformWrite === void 0 ? {} : { platformWrite }
|
|
@@ -426,6 +569,7 @@ window.__ModuleLoader__.load({
|
|
|
426
569
|
"start.pair": "复制配对命令模板",
|
|
427
570
|
"degraded": "读模型降级:",
|
|
428
571
|
"copied": "已复制:",
|
|
572
|
+
"copyFailed": "复制失败:浏览器没有接受剪贴板写入。",
|
|
429
573
|
"row.noSummary": "无摘要",
|
|
430
574
|
"overlay.body": "正文",
|
|
431
575
|
"hint": "手动触发;后台逐对判定。这里只读,不写技能。",
|
|
@@ -441,6 +585,7 @@ window.__ModuleLoader__.load({
|
|
|
441
585
|
"empty.fuse": "没有待合并的对。",
|
|
442
586
|
"empty.skipped": "没有标记为无需合并的对。",
|
|
443
587
|
"loading": "正在读取…",
|
|
588
|
+
"refreshing": "刷新中,下面仍是上次结果…",
|
|
444
589
|
"refresh": "刷新",
|
|
445
590
|
"loadMore": "加载更多",
|
|
446
591
|
"approval.on": "审批开:合并前需人工批准。",
|
|
@@ -489,13 +634,13 @@ window.__ModuleLoader__.load({
|
|
|
489
634
|
"skipKind.forced": "强制",
|
|
490
635
|
"action.approve": "复制批准",
|
|
491
636
|
"action.reject": "复制拒绝",
|
|
492
|
-
"action.retry-candidates": "
|
|
637
|
+
"action.retry-candidates": "复制重试候选",
|
|
493
638
|
"action.retry-resume": "重试续跑",
|
|
494
639
|
"action.discard": "复制丢弃",
|
|
495
|
-
"action.restore": "
|
|
640
|
+
"action.restore": "复制恢复命令",
|
|
496
641
|
"action.pair": "复制配对",
|
|
497
|
-
"action.status": "
|
|
498
|
-
"action.report": "
|
|
642
|
+
"action.status": "复制状态命令",
|
|
643
|
+
"action.report": "复制报告命令",
|
|
499
644
|
"action.cancel": "取消",
|
|
500
645
|
"action.confirm": "确认复制",
|
|
501
646
|
"disabled.expired": "已过期,不可用",
|
|
@@ -505,6 +650,7 @@ window.__ModuleLoader__.load({
|
|
|
505
650
|
"disabled.owned": "已有运行",
|
|
506
651
|
"disabled.unavailable": "暂不可用",
|
|
507
652
|
"history.empty": "没有历史。",
|
|
653
|
+
"history.archivedAt": "归档于 {date}",
|
|
508
654
|
"failureServer": "读取失败",
|
|
509
655
|
"failureUnauthorized": "未登录",
|
|
510
656
|
"failureForbidden": "无权访问",
|
|
@@ -540,6 +686,7 @@ window.__ModuleLoader__.load({
|
|
|
540
686
|
"stage.state.absent": "无暂存",
|
|
541
687
|
"origin.system": "系统",
|
|
542
688
|
"row.id": "编号",
|
|
689
|
+
"row.details": "详情",
|
|
543
690
|
"row.requestedTarget": "请求目标",
|
|
544
691
|
"row.stage": "合并暂存",
|
|
545
692
|
"row.summaryA": "摘要 A",
|
|
@@ -582,6 +729,7 @@ window.__ModuleLoader__.load({
|
|
|
582
729
|
"settings.capabilityMissing": "宿主未提供该能力",
|
|
583
730
|
"settings.capabilityDisabled": "当前部署不可用",
|
|
584
731
|
"settings.readonly": "只读显示;修改请到平台设置页。",
|
|
732
|
+
"settings.mergeApprovalPath": "设置 → 插件 → 自进化 → 技能自动合并",
|
|
585
733
|
"run.title": "运行",
|
|
586
734
|
"run.id": "运行编号",
|
|
587
735
|
"run.state": "状态",
|
|
@@ -592,6 +740,7 @@ window.__ModuleLoader__.load({
|
|
|
592
740
|
"run.currentPair": "当前对",
|
|
593
741
|
"run.parent": "父运行",
|
|
594
742
|
"run.report": "报告",
|
|
743
|
+
"run.details": "运行详情",
|
|
595
744
|
"run.noReport": "暂无报告",
|
|
596
745
|
"run.resultRef": "报告位置",
|
|
597
746
|
"run.actions": "运行操作",
|
|
@@ -609,7 +758,7 @@ window.__ModuleLoader__.load({
|
|
|
609
758
|
"error.title": "读取失败",
|
|
610
759
|
"error.retry": "重试",
|
|
611
760
|
"error.raw": "原始信息",
|
|
612
|
-
"doctor.open": "
|
|
761
|
+
"doctor.open": "复制诊断命令",
|
|
613
762
|
"sort.updatedAt": "按更新时间",
|
|
614
763
|
"sort.score": "按分数",
|
|
615
764
|
"pin": "置顶",
|
|
@@ -622,6 +771,7 @@ window.__ModuleLoader__.load({
|
|
|
622
771
|
"start.pair": "Copy pair command template",
|
|
623
772
|
"degraded": "Degraded read model:",
|
|
624
773
|
"copied": "Copied:",
|
|
774
|
+
"copyFailed": "Copy failed: the browser did not accept the clipboard write.",
|
|
625
775
|
"row.noSummary": "No summary",
|
|
626
776
|
"overlay.body": "Body",
|
|
627
777
|
"hint": "Manual only; pairs are judged in the background. Read-only here.",
|
|
@@ -637,6 +787,7 @@ window.__ModuleLoader__.load({
|
|
|
637
787
|
"empty.fuse": "No pairs ready to merge.",
|
|
638
788
|
"empty.skipped": "No pairs marked as not worth merging.",
|
|
639
789
|
"loading": "Loading…",
|
|
790
|
+
"refreshing": "Refreshing; the rows below are the previous result…",
|
|
640
791
|
"refresh": "Refresh",
|
|
641
792
|
"loadMore": "Load more",
|
|
642
793
|
"approval.on": "Approval on: merges wait for a human.",
|
|
@@ -685,13 +836,13 @@ window.__ModuleLoader__.load({
|
|
|
685
836
|
"skipKind.forced": "forced",
|
|
686
837
|
"action.approve": "Copy approve",
|
|
687
838
|
"action.reject": "Copy reject",
|
|
688
|
-
"action.retry-candidates": "
|
|
839
|
+
"action.retry-candidates": "Copy retry candidates",
|
|
689
840
|
"action.retry-resume": "Retry resume",
|
|
690
841
|
"action.discard": "Copy discard",
|
|
691
|
-
"action.restore": "
|
|
842
|
+
"action.restore": "Copy restore command",
|
|
692
843
|
"action.pair": "Copy pair",
|
|
693
|
-
"action.status": "
|
|
694
|
-
"action.report": "
|
|
844
|
+
"action.status": "Copy status command",
|
|
845
|
+
"action.report": "Copy report command",
|
|
695
846
|
"action.cancel": "Cancel",
|
|
696
847
|
"action.confirm": "Copy confirmation",
|
|
697
848
|
"disabled.expired": "expired",
|
|
@@ -701,6 +852,7 @@ window.__ModuleLoader__.load({
|
|
|
701
852
|
"disabled.owned": "already running",
|
|
702
853
|
"disabled.unavailable": "unavailable",
|
|
703
854
|
"history.empty": "No history.",
|
|
855
|
+
"history.archivedAt": "Archived {date}",
|
|
704
856
|
"failureServer": "Read failed",
|
|
705
857
|
"failureUnauthorized": "Not signed in",
|
|
706
858
|
"failureForbidden": "Forbidden",
|
|
@@ -736,6 +888,7 @@ window.__ModuleLoader__.load({
|
|
|
736
888
|
"stage.state.absent": "Not staged",
|
|
737
889
|
"origin.system": "System",
|
|
738
890
|
"row.id": "ID",
|
|
891
|
+
"row.details": "Details",
|
|
739
892
|
"row.requestedTarget": "Requested target",
|
|
740
893
|
"row.stage": "Merge staging",
|
|
741
894
|
"row.summaryA": "Summary A",
|
|
@@ -778,6 +931,7 @@ window.__ModuleLoader__.load({
|
|
|
778
931
|
"settings.capabilityMissing": "Host did not provide this capability",
|
|
779
932
|
"settings.capabilityDisabled": "Not available in this deployment",
|
|
780
933
|
"settings.readonly": "Read-only here; edit in platform settings.",
|
|
934
|
+
"settings.mergeApprovalPath": "Settings → Plugins → Evolution → Skill auto-merge",
|
|
781
935
|
"run.title": "Run",
|
|
782
936
|
"run.id": "Run ID",
|
|
783
937
|
"run.state": "State",
|
|
@@ -788,6 +942,7 @@ window.__ModuleLoader__.load({
|
|
|
788
942
|
"run.currentPair": "Current pair",
|
|
789
943
|
"run.parent": "Parent run",
|
|
790
944
|
"run.report": "Report",
|
|
945
|
+
"run.details": "Run details",
|
|
791
946
|
"run.noReport": "No report yet",
|
|
792
947
|
"run.resultRef": "Report location",
|
|
793
948
|
"run.actions": "Run actions",
|
|
@@ -805,7 +960,7 @@ window.__ModuleLoader__.load({
|
|
|
805
960
|
"error.title": "Read failed",
|
|
806
961
|
"error.retry": "Retry",
|
|
807
962
|
"error.raw": "Raw message",
|
|
808
|
-
"doctor.open": "
|
|
963
|
+
"doctor.open": "Copy diagnostics command",
|
|
809
964
|
"sort.updatedAt": "Last updated",
|
|
810
965
|
"sort.score": "Score",
|
|
811
966
|
"pin": "Pin",
|
|
@@ -815,12 +970,14 @@ window.__ModuleLoader__.load({
|
|
|
815
970
|
"settings.saved": "已保存",
|
|
816
971
|
"settings.saveFailed": "保存失败",
|
|
817
972
|
"settings.openPlatform": "打开平台设置",
|
|
973
|
+
"settings.openPlatformPath": "设置 → 内置插件 → 插件配置 → 技能自动合并",
|
|
818
974
|
"settings.live": "可直接在此保存;platformWrite 能力来自宿主。"
|
|
819
975
|
});
|
|
820
976
|
Object.assign(en, {
|
|
821
977
|
"settings.saved": "Saved",
|
|
822
978
|
"settings.saveFailed": "Save failed",
|
|
823
979
|
"settings.openPlatform": "Open platform settings",
|
|
980
|
+
"settings.openPlatformPath": "Settings → Built-in plugins → Plugin configuration → Skill auto-merge",
|
|
824
981
|
"settings.live": "Save directly here; platformWrite capability comes from the host."
|
|
825
982
|
});
|
|
826
983
|
Object.assign(zh, { "settings.platformWriteLinkHint": "此开关属于平台设置,这里只读;请到平台设置修改。" });
|
|
@@ -850,7 +1007,7 @@ window.__ModuleLoader__.load({
|
|
|
850
1007
|
".evolution-merge-panel [data-role=\"stat\"] { border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2); border-radius:var(--evo-radius-control); padding:var(--evo-space-6) var(--evo-space-10); min-width:calc(var(--evo-space-16) * 4); }",
|
|
851
1008
|
".evolution-merge-panel [data-role=\"stat-value\"] { font-size:var(--evo-type-lg); font-weight:600; }",
|
|
852
1009
|
".evolution-merge-panel [data-role=\"stat-label\"] { font-size:var(--evo-type-xs); color:var(--dsw-alias-label-tertiary); }",
|
|
853
|
-
".evolution-merge-panel [data-role=\"tabs\"] { display:flex; gap:var(--evo-space-6); border-bottom:var(--evo-hairline-width) solid var(--dsw-alias-border-l2); }",
|
|
1010
|
+
".evolution-merge-panel [data-role=\"tabs\"] { display:flex; flex-wrap:wrap; gap:var(--evo-space-6); border-bottom:var(--evo-hairline-width) solid var(--dsw-alias-border-l2); }",
|
|
854
1011
|
".evolution-merge-panel [data-role=\"tab\"] { background:none; border:0; border-bottom:var(--evo-hairline-width) solid transparent; padding:var(--evo-space-6) var(--evo-space-8); cursor:pointer; color:inherit; }",
|
|
855
1012
|
".evolution-merge-panel [data-role=\"tab\"][data-active=\"true\"] { border-bottom-color:var(--dsw-alias-brand-primary); }",
|
|
856
1013
|
".evolution-merge-panel button:focus-visible { outline:2px solid currentColor !important; outline-offset:2px; box-shadow:0 0 0 2px currentColor !important; }",
|
|
@@ -862,6 +1019,13 @@ window.__ModuleLoader__.load({
|
|
|
862
1019
|
".evolution-merge-panel [data-role=\"failure\"] [data-tone=\"fail\"] { color:var(--dsw-alias-state-error-primary); }",
|
|
863
1020
|
".evolution-merge-panel [data-role=\"fallback\"] { display:flex; gap:var(--evo-space-6); flex-wrap:wrap; }",
|
|
864
1021
|
".evolution-merge-panel [data-role=\"overlay\"] { position:fixed; z-index:60; top:8vh; left:50%; transform:translateX(-50%); width:min(820px, calc(100vw - 64px)); max-height:78vh; overflow:auto; display:flex; flex-direction:column; gap:var(--evo-space-8); padding:var(--evo-space-12); border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2); border-radius:var(--evo-radius-control); background:var(--dsw-alias-bg-layer-1); box-shadow:0 0 var(--evo-space-8) var(--dsw-alias-border-l2); }",
|
|
1022
|
+
".evo-merge-modal { width:min(820px, calc(100vw - 48px)); max-width:calc(100vw - 48px); max-height:min(78vh, 720px); }",
|
|
1023
|
+
".evo-merge-modal [data-role=\"overlay\"][data-platform-modal] { position:static; z-index:auto; top:auto; left:auto; transform:none; width:auto; box-sizing:border-box; max-height:none; overflow:auto; padding:var(--evo-space-20); border:0; border-radius:0; background:transparent; box-shadow:none; gap:var(--evo-space-8); }",
|
|
1024
|
+
".evo-merge-modal [data-role=\"overlay-head\"] { display:flex; align-items:center; justify-content:space-between; gap:var(--evo-space-8); }",
|
|
1025
|
+
".evo-merge-modal [data-role=\"overlay-title\"] { margin:0; font-size:var(--evo-type-lg); }",
|
|
1026
|
+
".evo-merge-modal [data-role=\"body-text\"] { margin:0; max-height:52vh; overflow:auto; white-space:pre-wrap; }",
|
|
1027
|
+
".evo-merge-modal [data-role=\"history-list\"] { margin:0; padding-left:var(--evo-space-20); }",
|
|
1028
|
+
".evo-merge-modal [data-role=\"history-item\"] { padding:var(--evo-space-4) 0; }",
|
|
865
1029
|
".evolution-merge-panel [data-role=\"overlay-head\"] { display:flex; align-items:center; justify-content:space-between; gap:var(--evo-space-8); }",
|
|
866
1030
|
".evolution-merge-panel [data-role=\"overlay-title\"] { margin:0; font-size:var(--evo-type-lg); }",
|
|
867
1031
|
".evolution-merge-panel [data-role=\"rows\"] { display:flex; flex-direction:column; gap:var(--evo-space-6); }",
|
|
@@ -902,6 +1066,25 @@ window.__ModuleLoader__.load({
|
|
|
902
1066
|
".evolution-merge-panel [data-role=\"refresh\"] { align-self:flex-start; }"
|
|
903
1067
|
].join("\n");
|
|
904
1068
|
//#endregion
|
|
1069
|
+
//#region src/client/platform-modal.ts
|
|
1070
|
+
const PLATFORM_UI_MODULE$1 = "@deepseek-ai/dsh-client-ui-primitives";
|
|
1071
|
+
let cached;
|
|
1072
|
+
/** The platform Modal, or undefined in a non-browser/SSR render or a deployment without the row. */
|
|
1073
|
+
function platformModal() {
|
|
1074
|
+
if (cached !== void 0) return cached ?? void 0;
|
|
1075
|
+
if (typeof window === "undefined") {
|
|
1076
|
+
cached = null;
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
try {
|
|
1080
|
+
const row = require(PLATFORM_UI_MODULE$1);
|
|
1081
|
+
cached = typeof row.Modal === "function" ? row.Modal : null;
|
|
1082
|
+
} catch {
|
|
1083
|
+
cached = null;
|
|
1084
|
+
}
|
|
1085
|
+
return cached ?? void 0;
|
|
1086
|
+
}
|
|
1087
|
+
//#endregion
|
|
905
1088
|
//#region src/client/platform-menu.ts
|
|
906
1089
|
/**
|
|
907
1090
|
* The one seam onto the platform's menu material and rows.
|
|
@@ -1061,13 +1244,6 @@ window.__ModuleLoader__.load({
|
|
|
1061
1244
|
//#endregion
|
|
1062
1245
|
//#region src/client/Panel.ts
|
|
1063
1246
|
/** Batch 4 merge panel: keyed read store, four tabs, local overlays, localized errors. */
|
|
1064
|
-
async function saveSetting(form, field, value) {
|
|
1065
|
-
try {
|
|
1066
|
-
return await form.set(field, value);
|
|
1067
|
-
} catch {
|
|
1068
|
-
return false;
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
1247
|
const QUEUES = [
|
|
1072
1248
|
"verify",
|
|
1073
1249
|
"pending",
|
|
@@ -1171,19 +1347,43 @@ window.__ModuleLoader__.load({
|
|
|
1171
1347
|
if (run === void 0) return null;
|
|
1172
1348
|
const report = run.actions.find((action) => action.id === "report");
|
|
1173
1349
|
const reportEnabled = report?.enabled === true;
|
|
1350
|
+
const internals = [
|
|
1351
|
+
(0, react.createElement)("span", {
|
|
1352
|
+
key: "id",
|
|
1353
|
+
"data-role": "run-id",
|
|
1354
|
+
title: run.id
|
|
1355
|
+
}, t("run.id") + " " + run.id),
|
|
1356
|
+
run.stage === void 0 ? null : (0, react.createElement)("span", {
|
|
1357
|
+
key: "stage",
|
|
1358
|
+
"data-role": "run-stage"
|
|
1359
|
+
}, t("stage." + run.stage)),
|
|
1360
|
+
run.endedAt === void 0 ? null : (0, react.createElement)("span", {
|
|
1361
|
+
key: "ended",
|
|
1362
|
+
"data-role": "run-ended"
|
|
1363
|
+
}, t("run.endedAt") + " " + new Date(run.endedAt).toLocaleString()),
|
|
1364
|
+
run.failure === void 0 ? null : (0, react.createElement)("span", {
|
|
1365
|
+
key: "failure",
|
|
1366
|
+
"data-role": "run-failure",
|
|
1367
|
+
title: run.failure.detail
|
|
1368
|
+
}, t("run.failure") + " " + run.failure.code),
|
|
1369
|
+
run.currentPairKey === void 0 ? null : (0, react.createElement)("span", {
|
|
1370
|
+
key: "pair",
|
|
1371
|
+
"data-role": "run-current-pair"
|
|
1372
|
+
}, t("run.currentPair") + " " + run.currentPairKey),
|
|
1373
|
+
run.parentRunId === void 0 ? null : (0, react.createElement)("span", {
|
|
1374
|
+
key: "parent",
|
|
1375
|
+
"data-role": "run-parent"
|
|
1376
|
+
}, t("run.parent") + " " + run.parentRunId),
|
|
1377
|
+
run.resultRef === void 0 ? null : (0, react.createElement)("span", {
|
|
1378
|
+
key: "ref",
|
|
1379
|
+
"data-role": "run-result-ref",
|
|
1380
|
+
title: run.resultRef
|
|
1381
|
+
}, t("run.resultRef"))
|
|
1382
|
+
];
|
|
1174
1383
|
return (0, react.createElement)("div", {
|
|
1175
1384
|
"data-role": "run-strip",
|
|
1176
1385
|
"data-run-state": run.state
|
|
1177
|
-
}, (0, react.createElement)("span", {
|
|
1178
|
-
"data-role": "run-id",
|
|
1179
|
-
title: run.id
|
|
1180
|
-
}, t("run.id") + " " + run.id), (0, react.createElement)("span", { "data-role": "run-state" }, t("run.state") + " " + t("run." + run.state)), run.stage === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-stage" }, t("stage." + run.stage)), run.progress === null || run.progress === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-progress" }, t("run.progress") + " " + String(run.progress.done) + "/" + String(run.progress.total)), run.endedAt === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-ended" }, t("run.endedAt") + " " + new Date(run.endedAt).toLocaleString()), run.failure === void 0 ? null : (0, react.createElement)("span", {
|
|
1181
|
-
"data-role": "run-failure",
|
|
1182
|
-
title: run.failure.detail
|
|
1183
|
-
}, t("run.failure") + " " + run.failure.code), run.currentPairKey === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-current-pair" }, t("run.currentPair") + " " + run.currentPairKey), run.parentRunId === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-parent" }, t("run.parent") + " " + run.parentRunId), run.resultRef === void 0 ? null : (0, react.createElement)("span", {
|
|
1184
|
-
"data-role": "run-result-ref",
|
|
1185
|
-
title: run.resultRef
|
|
1186
|
-
}, t("run.resultRef")), (0, react.createElement)("button", {
|
|
1386
|
+
}, (0, react.createElement)("span", { "data-role": "run-state" }, t("run.state") + " " + t("run." + run.state)), run.progress === null || run.progress === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-progress" }, t("run.progress") + " " + String(run.progress.done) + "/" + String(run.progress.total)), (0, react.createElement)("button", {
|
|
1187
1387
|
type: "button",
|
|
1188
1388
|
"data-role": "run-report",
|
|
1189
1389
|
"data-action": "report",
|
|
@@ -1202,7 +1402,7 @@ window.__ModuleLoader__.load({
|
|
|
1202
1402
|
onClick: () => {
|
|
1203
1403
|
if (action.enabled) copy(action.command);
|
|
1204
1404
|
}
|
|
1205
|
-
}, t("action." + action.id))));
|
|
1405
|
+
}, t("action." + action.id))), (0, react.createElement)("details", { "data-role": "run-details" }, (0, react.createElement)("summary", null, t("run.details")), ...internals));
|
|
1206
1406
|
}
|
|
1207
1407
|
function ReadOnlySetting({ section, label, value, disabled, missing, note, link, t }) {
|
|
1208
1408
|
const text = missing ? t("settings.capabilityMissing") : disabled ? t("settings.capabilityDisabled") : value === true ? t("settings.on") : t("settings.off");
|
|
@@ -1213,86 +1413,21 @@ window.__ModuleLoader__.load({
|
|
|
1213
1413
|
}, (0, react.createElement)("span", { "data-role": "settings-label" }, label), (0, react.createElement)("span", {
|
|
1214
1414
|
"data-role": "settings-value",
|
|
1215
1415
|
"data-value": missing ? "missing" : disabled ? "unavailable" : value === true ? "on" : "off"
|
|
1216
|
-
}, text), note === void 0 ? null : (0, react.createElement)("span", { "data-role": "settings-note" }, note), link === true ? (0, react.createElement)("
|
|
1217
|
-
"data-role": "settings-link",
|
|
1218
|
-
href: "#/settings",
|
|
1219
|
-
onClick: () => {
|
|
1220
|
-
window.dispatchEvent(new KeyboardEvent("keydown", {
|
|
1221
|
-
key: ",",
|
|
1222
|
-
code: "Comma",
|
|
1223
|
-
ctrlKey: true,
|
|
1224
|
-
altKey: true,
|
|
1225
|
-
bubbles: true
|
|
1226
|
-
}));
|
|
1227
|
-
}
|
|
1228
|
-
}, t("settings.openPlatform")) : null);
|
|
1229
|
-
}
|
|
1230
|
-
function EditableSetting({ form, field, label, fallback, capability, t }) {
|
|
1231
|
-
const subscribe = (0, react.useCallback)((listener) => form.subscribe(listener), [form]);
|
|
1232
|
-
const readSnapshot = (0, react.useCallback)(() => form["getSnapshot"](), [form]);
|
|
1233
|
-
const snapshot = (0, react.useSyncExternalStore)(subscribe, readSnapshot, readSnapshot);
|
|
1234
|
-
const fieldPresent = snapshot.status !== "ready" || snapshot.value === void 0 || Object.prototype.hasOwnProperty.call(snapshot.value, field);
|
|
1235
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
1236
|
-
const [saved, setSaved] = (0, react.useState)(void 0);
|
|
1237
|
-
const value = snapshot.status === "ready" && typeof snapshot.value?.[field] === "boolean" ? snapshot.value[field] : fallback;
|
|
1238
|
-
const disabled = !capability || busy || snapshot.status !== "ready" || !snapshot.writable;
|
|
1239
|
-
const toggle = async () => {
|
|
1240
|
-
if (disabled) return;
|
|
1241
|
-
setBusy(true);
|
|
1242
|
-
setSaved(void 0);
|
|
1243
|
-
const ok = await saveSetting(form, field, !value);
|
|
1244
|
-
setBusy(false);
|
|
1245
|
-
setSaved(ok ? "saved" : "failed");
|
|
1246
|
-
};
|
|
1247
|
-
if (!fieldPresent) return (0, react.createElement)(ReadOnlySetting, {
|
|
1248
|
-
section: "platform-write",
|
|
1249
|
-
label,
|
|
1250
|
-
value: fallback,
|
|
1251
|
-
disabled: !capability,
|
|
1252
|
-
missing: false,
|
|
1253
|
-
note: t("settings.platformWriteLinkHint"),
|
|
1254
|
-
link: true,
|
|
1255
|
-
t
|
|
1256
|
-
});
|
|
1257
|
-
return (0, react.createElement)("div", {
|
|
1258
|
-
"data-role": "settings-section",
|
|
1259
|
-
"data-section": field === "mergeApproval" ? "merge-approval" : "platform-write",
|
|
1260
|
-
...disabled ? { "data-disabled": "true" } : {}
|
|
1261
|
-
}, (0, react.createElement)("label", { "data-role": "settings-label" }, label), (0, react.createElement)("input", {
|
|
1262
|
-
type: "checkbox",
|
|
1263
|
-
role: "switch",
|
|
1264
|
-
"data-role": "settings-toggle",
|
|
1265
|
-
"data-field": field,
|
|
1266
|
-
"data-value": value ? "on" : "off",
|
|
1267
|
-
checked: value,
|
|
1268
|
-
disabled,
|
|
1269
|
-
onChange: () => {
|
|
1270
|
-
toggle();
|
|
1271
|
-
}
|
|
1272
|
-
}), (0, react.createElement)("span", { "data-role": "settings-value" }, value ? t("settings.on") : t("settings.off")), ...saved === void 0 ? [] : [(0, react.createElement)("span", {
|
|
1273
|
-
"data-role": "settings-save-state",
|
|
1274
|
-
"data-save": saved
|
|
1275
|
-
}, t(saved === "saved" ? "settings.saved" : "settings.saveFailed"))]);
|
|
1416
|
+
}, text), note === void 0 ? null : (0, react.createElement)("span", { "data-role": "settings-note" }, note), link === true ? (0, react.createElement)("span", { "data-role": "settings-link" }, t("settings.openPlatformPath")) : null);
|
|
1276
1417
|
}
|
|
1277
|
-
function SettingsCard({ view,
|
|
1418
|
+
function SettingsCard({ view, t }) {
|
|
1278
1419
|
const platform = view.approval.platformWrite;
|
|
1279
|
-
const platformCapability = platform?.capability
|
|
1420
|
+
const platformCapability = platform?.capability === true;
|
|
1280
1421
|
const platformFallback = platform?.enabled ?? false;
|
|
1281
|
-
const mergeCapability = settings?.merge !== void 0;
|
|
1282
1422
|
const mergeFallback = view.approval.mergeApproval;
|
|
1283
|
-
return (0, react.createElement)("div", { "data-role": "settings-card" }, (0, react.createElement)("h3", { "data-role": "settings-title" }, t("settings.title")), (0, react.createElement)("p", { "data-role": "settings-hint" }, t("settings.hint")),
|
|
1423
|
+
return (0, react.createElement)("div", { "data-role": "settings-card" }, (0, react.createElement)("h3", { "data-role": "settings-title" }, t("settings.title")), (0, react.createElement)("p", { "data-role": "settings-hint" }, t("settings.hint")), (0, react.createElement)(ReadOnlySetting, {
|
|
1284
1424
|
section: "merge-approval",
|
|
1285
1425
|
label: t("settings.mergeApproval"),
|
|
1286
1426
|
value: mergeFallback,
|
|
1287
1427
|
disabled: false,
|
|
1288
1428
|
missing: false,
|
|
1289
|
-
t
|
|
1290
|
-
|
|
1291
|
-
form: settings.merge,
|
|
1292
|
-
field: "mergeApproval",
|
|
1293
|
-
label: t("settings.mergeApproval"),
|
|
1294
|
-
fallback: mergeFallback,
|
|
1295
|
-
capability: mergeCapability,
|
|
1429
|
+
note: t("settings.mergeApprovalPath"),
|
|
1430
|
+
link: true,
|
|
1296
1431
|
t
|
|
1297
1432
|
}), (0, react.createElement)(ReadOnlySetting, {
|
|
1298
1433
|
section: "platform-write",
|
|
@@ -1303,22 +1438,22 @@ window.__ModuleLoader__.load({
|
|
|
1303
1438
|
note: t("settings.platformWriteLinkHint"),
|
|
1304
1439
|
link: true,
|
|
1305
1440
|
t
|
|
1306
|
-
}),
|
|
1307
|
-
"data-role": "settings-link",
|
|
1308
|
-
href: "#/settings"
|
|
1309
|
-
}, t("settings.openPlatform")) : null, (0, react.createElement)("p", { "data-role": "settings-readonly" }, settings?.merge === void 0 ? t("settings.readonly") : t("settings.live")));
|
|
1441
|
+
}), (0, react.createElement)("p", { "data-role": "settings-readonly" }, t("settings.readonly")));
|
|
1310
1442
|
}
|
|
1311
|
-
function rowNode(row,
|
|
1312
|
-
const
|
|
1443
|
+
function rowNode(row, t, copy, sort, openBody) {
|
|
1444
|
+
const first = [
|
|
1313
1445
|
row.target === void 0 ? void 0 : t("row.target") + " " + row.target,
|
|
1446
|
+
row.failure === void 0 ? void 0 : t("row.failure") + " " + row.failure.code + (row.failure.retryable ? "" : " · " + t("row.noRetry")),
|
|
1447
|
+
row.expired === void 0 ? void 0 : t("row.expired") + " " + t("expired." + row.expired),
|
|
1448
|
+
row.reasonCode === void 0 && row.reason === void 0 ? void 0 : t("row.reason") + " " + reasonText(t, row.reasonCode, row.reason ?? "")
|
|
1449
|
+
].filter((value) => value !== void 0).join(" · ");
|
|
1450
|
+
const details = [
|
|
1451
|
+
t("row.id") + " " + row.id,
|
|
1314
1452
|
row.targetActual === void 0 ? void 0 : t("row.actualTarget") + " " + row.targetActual,
|
|
1315
1453
|
row.verifySubState === void 0 ? void 0 : t("row.verify") + " " + t("verify." + row.verifySubState),
|
|
1316
1454
|
row.origin === void 0 ? void 0 : t("row.origin") + " " + t("origin." + row.origin),
|
|
1317
1455
|
row.attempts === void 0 ? void 0 : t("row.attempts") + " " + String(row.attempts),
|
|
1318
|
-
row.confidence === void 0 ? void 0 : t("row.confidence") + " " + row.confidence.toFixed(2)
|
|
1319
|
-
row.failure === void 0 ? void 0 : t("row.failure") + " " + row.failure.code + (row.failure.retryable ? "" : " · " + t("row.noRetry")),
|
|
1320
|
-
row.expired === void 0 ? void 0 : t("row.expired") + " " + t("expired." + row.expired),
|
|
1321
|
-
row.reasonCode === void 0 && row.reason === void 0 ? void 0 : t("row.reason") + " " + reasonText(t, row.reasonCode, row.reason ?? "")
|
|
1456
|
+
row.confidence === void 0 ? void 0 : t("row.confidence") + " " + row.confidence.toFixed(2)
|
|
1322
1457
|
].filter((value) => value !== void 0).join(" · ");
|
|
1323
1458
|
const actions = row.actions.map((action) => (0, react.createElement)("button", {
|
|
1324
1459
|
key: action.id,
|
|
@@ -1330,7 +1465,6 @@ window.__ModuleLoader__.load({
|
|
|
1330
1465
|
disabled: !action.enabled,
|
|
1331
1466
|
onClick: () => {
|
|
1332
1467
|
if (!action.enabled) return;
|
|
1333
|
-
if (action.confirm && globalThis.confirm !== void 0 && !globalThis.confirm(t("action.confirm") + " " + (t("action." + action.id) || action.id))) return;
|
|
1334
1468
|
copy(action.command);
|
|
1335
1469
|
}
|
|
1336
1470
|
}, t("action." + action.id)));
|
|
@@ -1341,7 +1475,15 @@ window.__ModuleLoader__.load({
|
|
|
1341
1475
|
"data-row-state": row.state,
|
|
1342
1476
|
"data-row-queue": row.queue,
|
|
1343
1477
|
draggable: true,
|
|
1478
|
+
tabIndex: 0,
|
|
1344
1479
|
title: t("sort.drag"),
|
|
1480
|
+
"aria-haspopup": "menu",
|
|
1481
|
+
onKeyDown: (event) => {
|
|
1482
|
+
if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
|
|
1483
|
+
event.preventDefault();
|
|
1484
|
+
const box = event.currentTarget.getBoundingClientRect();
|
|
1485
|
+
sort.menu(row.id, box.left + 12, box.top + 12);
|
|
1486
|
+
},
|
|
1345
1487
|
onDragStart: (event) => {
|
|
1346
1488
|
if (event.dataTransfer != null) {
|
|
1347
1489
|
event.dataTransfer.setData("text/plain", row.id);
|
|
@@ -1365,52 +1507,99 @@ window.__ModuleLoader__.load({
|
|
|
1365
1507
|
event.preventDefault();
|
|
1366
1508
|
sort.menu(row.id, event.clientX, event.clientY);
|
|
1367
1509
|
}
|
|
1368
|
-
}, (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-label" }, row.label), (0, react.createElement)("div", {
|
|
1369
|
-
"data-role": "row-id",
|
|
1370
|
-
title: row.id
|
|
1371
|
-
}, t("row.id") + " " + row.id), (0, react.createElement)("div", { "data-role": "row-meta" }, t("state." + row.state) + (row.stage === null ? "" : " · " + t("stage." + row.stage))), stageNode(row, t), summaryNode(row, t), facts === "" ? null : (0, react.createElement)("div", { "data-role": "row-facts" }, facts)), (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-meta" }, new Date(row.updatedAt).toLocaleString()), (0, react.createElement)("div", { "data-role": "row-actions" }, (() => {
|
|
1510
|
+
}, (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-label" }, row.label), (0, react.createElement)("div", { "data-role": "row-meta" }, t("state." + row.state) + (row.stage === null ? "" : " · " + t("stage." + row.stage))), stageNode(row, t), summaryNode(row, t), first === "" ? null : (0, react.createElement)("div", { "data-role": "row-facts" }, first), (0, react.createElement)("details", { "data-role": "row-details" }, (0, react.createElement)("summary", null, t("row.details")), (0, react.createElement)("p", null, details))), (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-meta" }, new Date(row.updatedAt).toLocaleString()), (0, react.createElement)("div", { "data-role": "row-actions" }, (() => {
|
|
1372
1511
|
const bodyA = row.bodies?.find((body) => body.name === row.a);
|
|
1373
1512
|
const bodyB = row.bodies?.find((body) => body.name === row.b);
|
|
1374
1513
|
return [bodyA === void 0 ? null : (0, react.createElement)("button", {
|
|
1375
1514
|
key: "a",
|
|
1376
1515
|
type: "button",
|
|
1377
1516
|
"data-role": "body-a",
|
|
1517
|
+
"aria-label": t("body." + bodyA.side) + " " + bodyA.name,
|
|
1518
|
+
title: t("body." + bodyA.side) + " " + bodyA.name,
|
|
1378
1519
|
onClick: () => {
|
|
1379
|
-
|
|
1520
|
+
openBody(bodyA.name, bodyA.side, bodyA.rowId);
|
|
1380
1521
|
}
|
|
1381
|
-
}, "A"), bodyB === void 0 ? null : (0, react.createElement)("button", {
|
|
1522
|
+
}, "A · " + bodyA.name), bodyB === void 0 ? null : (0, react.createElement)("button", {
|
|
1382
1523
|
key: "b",
|
|
1383
1524
|
type: "button",
|
|
1384
1525
|
"data-role": "body-b",
|
|
1526
|
+
"aria-label": t("body." + bodyB.side) + " " + bodyB.name,
|
|
1527
|
+
title: t("body." + bodyB.side) + " " + bodyB.name,
|
|
1385
1528
|
onClick: () => {
|
|
1386
|
-
|
|
1529
|
+
openBody(bodyB.name, bodyB.side, bodyB.rowId);
|
|
1387
1530
|
}
|
|
1388
|
-
}, "B")];
|
|
1531
|
+
}, "B · " + bodyB.name)];
|
|
1389
1532
|
})(), actions)));
|
|
1390
1533
|
}
|
|
1534
|
+
const overlayKey = (event, onClose) => {
|
|
1535
|
+
if (event.key === "Escape") {
|
|
1536
|
+
event.preventDefault();
|
|
1537
|
+
onClose();
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
if (event.key !== "Tab") return;
|
|
1541
|
+
const nodes = [...event.currentTarget.querySelectorAll("button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])")].filter((node) => !node.hasAttribute("disabled"));
|
|
1542
|
+
if (nodes.length === 0) return;
|
|
1543
|
+
const first = nodes[0];
|
|
1544
|
+
const last = nodes[nodes.length - 1];
|
|
1545
|
+
if (event.shiftKey && document.activeElement === first) {
|
|
1546
|
+
event.preventDefault();
|
|
1547
|
+
last.focus();
|
|
1548
|
+
} else if (!event.shiftKey && document.activeElement === last) {
|
|
1549
|
+
event.preventDefault();
|
|
1550
|
+
first.focus();
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1391
1553
|
function bodyNode(overlay, t, onClose) {
|
|
1392
|
-
|
|
1554
|
+
const Modal = platformModal();
|
|
1555
|
+
const title = t("overlay.body") + " · " + overlay.name;
|
|
1556
|
+
const inner = (0, react.createElement)("section", {
|
|
1393
1557
|
"data-role": "overlay",
|
|
1394
1558
|
"data-overlay": "body",
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1559
|
+
"aria-label": title,
|
|
1560
|
+
...Modal === void 0 ? {
|
|
1561
|
+
role: "dialog",
|
|
1562
|
+
"aria-modal": "true",
|
|
1563
|
+
onKeyDown: (event) => {
|
|
1564
|
+
overlayKey(event, onClose);
|
|
1565
|
+
}
|
|
1566
|
+
} : { "data-platform-modal": "true" }
|
|
1567
|
+
}, (0, react.createElement)("div", { "data-role": "overlay-head" }, (0, react.createElement)("h3", { "data-role": "overlay-title" }, title), (0, react.createElement)("button", {
|
|
1399
1568
|
type: "button",
|
|
1400
1569
|
"data-role": "overlay-close",
|
|
1570
|
+
...Modal === void 0 ? { autoFocus: true } : { "data-modal-autofocus": "true" },
|
|
1401
1571
|
onClick: onClose
|
|
1402
1572
|
}, t("close"))), (0, react.createElement)("p", { "data-role": "overlay-meta" }, t("body." + overlay.side) + " · " + (overlay.status === "ready" ? t("body.totalBytes") + " " + String(overlay.body?.totalBytes ?? 0) : "")), overlay.status === "loading" ? (0, react.createElement)("p", { "data-role": "overlay-loading" }, t("loading")) : null, overlay.status === "error" && overlay.failure !== void 0 ? failureNode(t, overlay.failure, [], () => {}) : null, overlay.status === "ready" && overlay.body !== void 0 ? (0, react.createElement)("div", null, overlay.body.truncated ? (0, react.createElement)("p", { "data-role": "body-truncated" }, t("body.truncated")) : null, overlay.body.text === "" ? (0, react.createElement)("p", { "data-role": "body-empty" }, t("body.empty")) : (0, react.createElement)("pre", { "data-role": "body-text" }, overlay.body.text)) : null);
|
|
1573
|
+
return Modal === void 0 ? inner : (0, react.createElement)(Modal, {
|
|
1574
|
+
open: true,
|
|
1575
|
+
onClose,
|
|
1576
|
+
title,
|
|
1577
|
+
closeLabel: t("close"),
|
|
1578
|
+
headless: true,
|
|
1579
|
+
className: "evo-merge-modal"
|
|
1580
|
+
}, inner);
|
|
1403
1581
|
}
|
|
1404
1582
|
function historyNode(overlay, t, onClose) {
|
|
1405
|
-
|
|
1583
|
+
const Modal = platformModal();
|
|
1584
|
+
const title = t("history");
|
|
1585
|
+
const inner = (0, react.createElement)("section", {
|
|
1406
1586
|
"data-role": "overlay",
|
|
1407
1587
|
"data-overlay": "history",
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1588
|
+
"aria-label": title,
|
|
1589
|
+
...Modal === void 0 ? {
|
|
1590
|
+
role: "dialog",
|
|
1591
|
+
"aria-modal": "true",
|
|
1592
|
+
onKeyDown: (event) => {
|
|
1593
|
+
if (event.key === "Escape") {
|
|
1594
|
+
event.preventDefault();
|
|
1595
|
+
onClose();
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
} : { "data-platform-modal": "true" }
|
|
1599
|
+
}, (0, react.createElement)("div", { "data-role": "overlay-head" }, (0, react.createElement)("h3", { "data-role": "overlay-title" }, title), (0, react.createElement)("button", {
|
|
1412
1600
|
type: "button",
|
|
1413
1601
|
"data-role": "overlay-close",
|
|
1602
|
+
...Modal === void 0 ? { autoFocus: true } : { "data-modal-autofocus": "true" },
|
|
1414
1603
|
onClick: onClose
|
|
1415
1604
|
}, t("close"))), overlay.status === "loading" ? (0, react.createElement)("p", { "data-role": "overlay-loading" }, t("loading")) : null, overlay.status === "error" && overlay.failure !== void 0 ? failureNode(t, overlay.failure, [], () => {}) : null, overlay.status === "ready" ? overlay.items === void 0 || overlay.items.length === 0 ? (0, react.createElement)("p", { "data-role": "history-empty" }, t("history.empty")) : (0, react.createElement)("ul", { "data-role": "history-list" }, overlay.items.map((item) => (0, react.createElement)("li", {
|
|
1416
1605
|
key: item.name + ":" + item.archivedAt,
|
|
@@ -1419,20 +1608,59 @@ window.__ModuleLoader__.load({
|
|
|
1419
1608
|
const kind = t("history.kind." + item.kind);
|
|
1420
1609
|
const reason = reasonText(t, item.reasonCode, item.reason);
|
|
1421
1610
|
return kind === reason ? kind : kind + " · " + reason;
|
|
1422
|
-
})() + " · v" + String(item.lastVersion)))) : null);
|
|
1611
|
+
})() + " · v" + String(item.lastVersion) + " · " + t("history.archivedAt", { date: new Date(item.archivedAt).toLocaleString() })))) : null);
|
|
1612
|
+
return Modal === void 0 ? inner : (0, react.createElement)(Modal, {
|
|
1613
|
+
open: true,
|
|
1614
|
+
onClose,
|
|
1615
|
+
title,
|
|
1616
|
+
closeLabel: t("close"),
|
|
1617
|
+
headless: true,
|
|
1618
|
+
className: "evo-merge-modal"
|
|
1619
|
+
}, inner);
|
|
1423
1620
|
}
|
|
1424
1621
|
function MergePanel(face) {
|
|
1425
1622
|
const { store, t } = face;
|
|
1426
1623
|
const snapshot = (0, react.useSyncExternalStore)(store.subscribe, store.read, store.read);
|
|
1427
|
-
const [
|
|
1624
|
+
const [copyState, setCopyState] = (0, react.useState)({ kind: "idle" });
|
|
1428
1625
|
const [orders, setOrders] = (0, react.useState)({});
|
|
1429
1626
|
const [dragId, setDragId] = (0, react.useState)(void 0);
|
|
1430
1627
|
const [menu, setMenu] = (0, react.useState)(void 0);
|
|
1628
|
+
const returnFocus = (0, react.useRef)(null);
|
|
1629
|
+
const captureFocus = () => {
|
|
1630
|
+
returnFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
1631
|
+
};
|
|
1632
|
+
const openBody = (name, side, rowId) => {
|
|
1633
|
+
captureFocus();
|
|
1634
|
+
store.openBody(name, side, rowId);
|
|
1635
|
+
};
|
|
1636
|
+
const openHistory = () => {
|
|
1637
|
+
captureFocus();
|
|
1638
|
+
store.openHistory();
|
|
1639
|
+
};
|
|
1640
|
+
const closeOverlay = () => {
|
|
1641
|
+
store.closeOverlay();
|
|
1642
|
+
requestAnimationFrame(() => {
|
|
1643
|
+
returnFocus.current?.focus();
|
|
1644
|
+
});
|
|
1645
|
+
};
|
|
1431
1646
|
const workspaceId = resolveWorkspaceId(face.workspaceId);
|
|
1432
1647
|
const orderStore = (0, react.useMemo)(() => createRowOrderStore(), []);
|
|
1433
1648
|
const copy = (command) => {
|
|
1434
|
-
|
|
1435
|
-
|
|
1649
|
+
(async () => {
|
|
1650
|
+
try {
|
|
1651
|
+
if (navigator.clipboard?.writeText === void 0) throw new Error("clipboard unavailable");
|
|
1652
|
+
await navigator.clipboard.writeText(command);
|
|
1653
|
+
setCopyState({
|
|
1654
|
+
kind: "copied",
|
|
1655
|
+
text: command
|
|
1656
|
+
});
|
|
1657
|
+
} catch {
|
|
1658
|
+
setCopyState({
|
|
1659
|
+
kind: "failed",
|
|
1660
|
+
text: command
|
|
1661
|
+
});
|
|
1662
|
+
}
|
|
1663
|
+
})();
|
|
1436
1664
|
};
|
|
1437
1665
|
const doctorCommand = face.doctorCommand ?? DOCTOR_COMMAND;
|
|
1438
1666
|
(0, react.useEffect)(() => {
|
|
@@ -1503,19 +1731,37 @@ window.__ModuleLoader__.load({
|
|
|
1503
1731
|
saveOrder(pinRow(visibleRows.map((row) => row.id), menu.id, edge));
|
|
1504
1732
|
setMenu(void 0);
|
|
1505
1733
|
};
|
|
1734
|
+
const onTabKey = (event, current) => {
|
|
1735
|
+
const delta = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
|
1736
|
+
const isEdge = event.key === "Home" || event.key === "End";
|
|
1737
|
+
if (delta === 0 && !isEdge) return;
|
|
1738
|
+
event.preventDefault();
|
|
1739
|
+
const index = QUEUES.indexOf(current);
|
|
1740
|
+
const next = event.key === "Home" ? QUEUES[0] : event.key === "End" ? QUEUES[QUEUES.length - 1] : QUEUES[(index + delta + QUEUES.length) % QUEUES.length];
|
|
1741
|
+
store.select(next);
|
|
1742
|
+
requestAnimationFrame(() => {
|
|
1743
|
+
document.getElementById("merge-tab-" + next)?.focus();
|
|
1744
|
+
});
|
|
1745
|
+
};
|
|
1506
1746
|
const tabs = (0, react.createElement)("div", {
|
|
1507
1747
|
"data-role": "tabs",
|
|
1508
1748
|
role: "tablist"
|
|
1509
1749
|
}, QUEUES.map((item) => (0, react.createElement)("button", {
|
|
1510
1750
|
key: item,
|
|
1751
|
+
id: "merge-tab-" + item,
|
|
1511
1752
|
type: "button",
|
|
1512
1753
|
role: "tab",
|
|
1513
1754
|
"aria-selected": snapshot.queue === item ? "true" : "false",
|
|
1755
|
+
"aria-controls": "merge-rows",
|
|
1756
|
+
tabIndex: snapshot.queue === item ? 0 : -1,
|
|
1514
1757
|
"data-role": "tab",
|
|
1515
1758
|
"data-active": snapshot.queue === item ? "true" : "false",
|
|
1516
1759
|
onClick: () => {
|
|
1517
1760
|
setMenu(void 0);
|
|
1518
1761
|
store.select(item);
|
|
1762
|
+
},
|
|
1763
|
+
onKeyDown: (event) => {
|
|
1764
|
+
onTabKey(event, item);
|
|
1519
1765
|
}
|
|
1520
1766
|
}, t("tab." + item) + " " + String(view.counts[item]))));
|
|
1521
1767
|
const expiredToggle = snapshot.queue === "pending" ? (0, react.createElement)("button", {
|
|
@@ -1528,14 +1774,20 @@ window.__ModuleLoader__.load({
|
|
|
1528
1774
|
store.toggleExpired();
|
|
1529
1775
|
}
|
|
1530
1776
|
}, t("tab.expired") + " " + String(view.expired)) : null;
|
|
1531
|
-
const list = uiState === "ready" && queue.status === "ready" ? (0, react.createElement)("div", {
|
|
1777
|
+
const list = uiState === "ready" && queue.status === "ready" ? (0, react.createElement)("div", {
|
|
1778
|
+
"data-role": "rows",
|
|
1779
|
+
id: "merge-rows",
|
|
1780
|
+
role: "tabpanel"
|
|
1781
|
+
}, visibleRows.map((row) => rowNode(row, t, copy, sortHandlers, openBody))) : null;
|
|
1532
1782
|
const empty = uiState === "empty" ? (0, react.createElement)("div", null, (0, react.createElement)("p", { "data-role": "note" }, t("empty." + snapshot.queue)), (0, react.createElement)("p", { "data-role": "empty-scope" }, t("empty.scope"))) : null;
|
|
1533
|
-
const
|
|
1783
|
+
const staleViewFailure = snapshot.viewState === "ready" ? snapshot.viewFailure : void 0;
|
|
1784
|
+
const activeFailure = viewFailure !== void 0 ? viewFailure : staleViewFailure !== void 0 ? staleViewFailure : queue.status === "error" ? queue.failure : void 0;
|
|
1534
1785
|
const overlay = snapshot.overlay;
|
|
1535
1786
|
const menuStyle = menu === void 0 ? void 0 : {
|
|
1536
1787
|
position: "fixed",
|
|
1537
1788
|
zIndex: 70,
|
|
1538
|
-
minWidth: "
|
|
1789
|
+
minWidth: "160px",
|
|
1790
|
+
maxWidth: "min(320px, calc(100vw - 16px))",
|
|
1539
1791
|
left: String(Math.min(menu.x, Math.max(0, (globalThis.innerWidth || 1440) - 180))) + "px",
|
|
1540
1792
|
top: String(Math.min(menu.y, Math.max(0, (globalThis.innerHeight || 800) - 110))) + "px"
|
|
1541
1793
|
};
|
|
@@ -1606,12 +1858,17 @@ window.__ModuleLoader__.load({
|
|
|
1606
1858
|
}
|
|
1607
1859
|
}, t("start.pair"))), view.degraded ? (0, react.createElement)("p", { "data-role": "degraded" }, t("degraded") + " " + view.notes.join(",")) : null, (0, react.createElement)(SettingsCard, {
|
|
1608
1860
|
view,
|
|
1609
|
-
settings: face.settings,
|
|
1610
1861
|
t
|
|
1611
|
-
}), runNode(view, t, copy), tabs, expiredToggle, snapshot.viewState === "loading" || queue.status === "loading" ? (0, react.createElement)("p", { "data-role": "note" }, t("loading")) :
|
|
1862
|
+
}), runNode(view, t, copy), tabs, expiredToggle, snapshot.viewState === "loading" || queue.status === "loading" ? (0, react.createElement)("p", { "data-role": "note" }, t("loading")) : queue.refreshing === true ? (0, react.createElement)("p", {
|
|
1863
|
+
"data-role": "note",
|
|
1864
|
+
role: "status"
|
|
1865
|
+
}, t("refreshing")) : null, activeFailure === void 0 ? null : failureNode(t, activeFailure, fallback, copy), copyState.kind === "idle" ? null : copyState.kind === "copied" ? (0, react.createElement)("p", {
|
|
1612
1866
|
"data-role": "copied",
|
|
1613
1867
|
role: "status"
|
|
1614
|
-
}, t("copied") + " " +
|
|
1868
|
+
}, t("copied") + " " + (copyState.text ?? "")) : (0, react.createElement)("p", {
|
|
1869
|
+
"data-role": "copy-failed",
|
|
1870
|
+
role: "alert"
|
|
1871
|
+
}, t("copyFailed")), list, empty, queue.nextCursor === void 0 || uiState !== "ready" ? null : (0, react.createElement)("button", {
|
|
1615
1872
|
type: "button",
|
|
1616
1873
|
"data-role": "load-more",
|
|
1617
1874
|
disabled: queue.status === "loading",
|
|
@@ -1622,7 +1879,7 @@ window.__ModuleLoader__.load({
|
|
|
1622
1879
|
type: "button",
|
|
1623
1880
|
"data-role": "history",
|
|
1624
1881
|
onClick: () => {
|
|
1625
|
-
|
|
1882
|
+
openHistory();
|
|
1626
1883
|
}
|
|
1627
1884
|
}, t("history")), (0, react.createElement)("button", {
|
|
1628
1885
|
type: "button",
|
|
@@ -1630,11 +1887,7 @@ window.__ModuleLoader__.load({
|
|
|
1630
1887
|
onClick: () => {
|
|
1631
1888
|
copy(doctorCommand);
|
|
1632
1889
|
}
|
|
1633
|
-
}, t("doctor.open")), overlay === void 0 ? null : overlay.kind === "body" ? bodyNode(overlay, t, ()
|
|
1634
|
-
store.closeOverlay();
|
|
1635
|
-
}) : historyNode(overlay, t, () => {
|
|
1636
|
-
store.closeOverlay();
|
|
1637
|
-
}), (0, react.createElement)("button", {
|
|
1890
|
+
}, t("doctor.open")), overlay === void 0 ? null : overlay.kind === "body" ? bodyNode(overlay, t, closeOverlay) : historyNode(overlay, t, closeOverlay), (0, react.createElement)("button", {
|
|
1638
1891
|
type: "button",
|
|
1639
1892
|
"data-role": "refresh",
|
|
1640
1893
|
onClick: () => {
|
|
@@ -1693,6 +1946,7 @@ window.__ModuleLoader__.load({
|
|
|
1693
1946
|
overlayToken = 0;
|
|
1694
1947
|
snapshot;
|
|
1695
1948
|
started = false;
|
|
1949
|
+
loadedView = false;
|
|
1696
1950
|
disposed = false;
|
|
1697
1951
|
constructor(source, initial = {}) {
|
|
1698
1952
|
this.source = source;
|
|
@@ -1738,7 +1992,11 @@ window.__ModuleLoader__.load({
|
|
|
1738
1992
|
}
|
|
1739
1993
|
async loadView(showLoading = true) {
|
|
1740
1994
|
const token = ++this.viewToken;
|
|
1741
|
-
if (showLoading) this.set({
|
|
1995
|
+
if (showLoading) if (this.snapshot.viewState === "ready") this.set({
|
|
1996
|
+
...this.snapshot,
|
|
1997
|
+
viewRefreshing: true
|
|
1998
|
+
});
|
|
1999
|
+
else this.set({
|
|
1742
2000
|
...this.snapshot,
|
|
1743
2001
|
viewState: "loading",
|
|
1744
2002
|
viewFailure: void 0
|
|
@@ -1762,19 +2020,23 @@ window.__ModuleLoader__.load({
|
|
|
1762
2020
|
});
|
|
1763
2021
|
return;
|
|
1764
2022
|
}
|
|
2023
|
+
const keeping = this.loadedView;
|
|
1765
2024
|
this.set({
|
|
1766
2025
|
...this.snapshot,
|
|
1767
|
-
viewState: "error",
|
|
1768
|
-
viewFailure: outcome.failure
|
|
2026
|
+
viewState: keeping ? "ready" : "error",
|
|
2027
|
+
viewFailure: outcome.failure,
|
|
2028
|
+
viewRefreshing: false
|
|
1769
2029
|
});
|
|
1770
2030
|
return;
|
|
1771
2031
|
}
|
|
2032
|
+
this.loadedView = true;
|
|
1772
2033
|
const wasBlocked = this.snapshot.viewState === "blocked";
|
|
1773
2034
|
this.set({
|
|
1774
2035
|
...this.snapshot,
|
|
1775
2036
|
view: outcome.payload,
|
|
1776
2037
|
viewState: "ready",
|
|
1777
|
-
viewFailure: void 0
|
|
2038
|
+
viewFailure: void 0,
|
|
2039
|
+
viewRefreshing: false
|
|
1778
2040
|
});
|
|
1779
2041
|
if (wasBlocked && this.snapshot.current.status === "idle") this.loadQueue(this.snapshot.queue, this.snapshot.expiredOnly);
|
|
1780
2042
|
}
|
|
@@ -1783,7 +2045,13 @@ window.__ModuleLoader__.load({
|
|
|
1783
2045
|
const token = (this.tokens.get(key) ?? 0) + 1;
|
|
1784
2046
|
this.tokens.set(key, token);
|
|
1785
2047
|
const previous = this.cache.get(key);
|
|
1786
|
-
const
|
|
2048
|
+
const keepRows = cursor === void 0 && (previous?.rows.length ?? 0) > 0;
|
|
2049
|
+
const next = cursor === void 0 ? keepRows ? {
|
|
2050
|
+
status: "ready",
|
|
2051
|
+
refreshing: true,
|
|
2052
|
+
rows: previous.rows,
|
|
2053
|
+
...previous.nextCursor === void 0 ? {} : { nextCursor: previous.nextCursor }
|
|
2054
|
+
} : {
|
|
1787
2055
|
status: "loading",
|
|
1788
2056
|
rows: []
|
|
1789
2057
|
} : {
|
|
@@ -1815,7 +2083,12 @@ window.__ModuleLoader__.load({
|
|
|
1815
2083
|
});
|
|
1816
2084
|
return;
|
|
1817
2085
|
}
|
|
1818
|
-
const failed = {
|
|
2086
|
+
const failed = keepRows ? {
|
|
2087
|
+
status: "ready",
|
|
2088
|
+
refreshing: false,
|
|
2089
|
+
rows: previous.rows,
|
|
2090
|
+
failure: outcome.failure
|
|
2091
|
+
} : {
|
|
1819
2092
|
status: "error",
|
|
1820
2093
|
rows: [],
|
|
1821
2094
|
failure: outcome.failure
|
|
@@ -1830,6 +2103,7 @@ window.__ModuleLoader__.load({
|
|
|
1830
2103
|
const items = cursor === void 0 ? outcome.payload.items : [...previous?.rows ?? [], ...outcome.payload.items];
|
|
1831
2104
|
const ready = {
|
|
1832
2105
|
status: items.length === 0 ? "empty" : "ready",
|
|
2106
|
+
refreshing: false,
|
|
1833
2107
|
rows: items,
|
|
1834
2108
|
...outcome.payload.nextCursor === void 0 ? {} : { nextCursor: outcome.payload.nextCursor }
|
|
1835
2109
|
};
|
|
@@ -1981,26 +2255,16 @@ window.__ModuleLoader__.load({
|
|
|
1981
2255
|
//#endregion
|
|
1982
2256
|
//#region src/client/index.ts
|
|
1983
2257
|
const inject = ["slots", "locale"];
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
return
|
|
1987
|
-
"aria-hidden": "true",
|
|
1988
|
-
width: String(size),
|
|
1989
|
-
height: String(size),
|
|
1990
|
-
viewBox: "0 0 16 16",
|
|
1991
|
-
fill: "none",
|
|
1992
|
-
stroke: "currentColor",
|
|
1993
|
-
strokeWidth: "1.5",
|
|
1994
|
-
strokeLinecap: "round",
|
|
1995
|
-
strokeLinejoin: "round"
|
|
1996
|
-
}, (0, react.createElement)("path", { d: "M3 4h10M3 8h6M3 12h8" }));
|
|
2258
|
+
/** The view component receives the workbench's activeView marker alongside its face. */
|
|
2259
|
+
function MergeView(props) {
|
|
2260
|
+
return props.activeView === "merge" ? MergePanel(props) : null;
|
|
1997
2261
|
}
|
|
1998
2262
|
/**
|
|
1999
|
-
* Register the merge
|
|
2263
|
+
* Register the merge view on the workbench page.
|
|
2000
2264
|
* @param ctx - the client context.
|
|
2001
2265
|
*/
|
|
2002
2266
|
function apply(ctx) {
|
|
2003
|
-
|
|
2267
|
+
registerWorkbenchView(ctx, {
|
|
2004
2268
|
id: PANEL_ID,
|
|
2005
2269
|
order: 45,
|
|
2006
2270
|
namespace: NS,
|
|
@@ -2012,30 +2276,24 @@ window.__ModuleLoader__.load({
|
|
|
2012
2276
|
css: CSS,
|
|
2013
2277
|
tagId: CSS_TAG_ID
|
|
2014
2278
|
},
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
body: (t) => {
|
|
2279
|
+
component: MergeView,
|
|
2280
|
+
face: (t) => {
|
|
2018
2281
|
const source = {
|
|
2019
2282
|
view,
|
|
2020
2283
|
rows,
|
|
2021
2284
|
body,
|
|
2022
2285
|
history
|
|
2023
2286
|
};
|
|
2024
|
-
|
|
2025
|
-
try {
|
|
2026
|
-
seat = ctx.get?.("configForms");
|
|
2027
|
-
} catch {
|
|
2028
|
-
seat = void 0;
|
|
2029
|
-
}
|
|
2287
|
+
const seat = createSettingsSeat(ctx);
|
|
2030
2288
|
const workspaceId = panelWorkspaceId(ctx);
|
|
2031
2289
|
return {
|
|
2032
2290
|
store: new MergeStore(source),
|
|
2033
2291
|
t,
|
|
2034
2292
|
doctorCommand: "/evolution doctor",
|
|
2035
|
-
settings: {
|
|
2036
|
-
merge: seat.get("evolution-merge"),
|
|
2037
|
-
platform: seat.get("evolution-approval")
|
|
2038
|
-
}
|
|
2293
|
+
settings: {
|
|
2294
|
+
...seat.get("evolution-merge") === void 0 ? {} : { merge: seat.get("evolution-merge") },
|
|
2295
|
+
...seat.get("evolution-approval") === void 0 ? {} : { platform: seat.get("evolution-approval") }
|
|
2296
|
+
},
|
|
2039
2297
|
...workspaceId === void 0 ? {} : { workspaceId }
|
|
2040
2298
|
};
|
|
2041
2299
|
}
|
|
@@ -11,6 +11,8 @@ export interface MergeSource {
|
|
|
11
11
|
export type QueueStatus = 'idle' | 'loading' | 'ready' | 'empty' | 'error';
|
|
12
12
|
export interface QueueState {
|
|
13
13
|
status: QueueStatus;
|
|
14
|
+
/** A background refresh is in flight; the old rows remain visible. */
|
|
15
|
+
refreshing?: boolean | undefined;
|
|
14
16
|
rows: MergeRowView[];
|
|
15
17
|
nextCursor?: string | undefined;
|
|
16
18
|
failure?: MergeFailure | undefined;
|
|
@@ -31,6 +33,7 @@ export type OverlayState = {
|
|
|
31
33
|
export interface StoreSnapshot {
|
|
32
34
|
view: MergeViewPayload;
|
|
33
35
|
viewState: 'loading' | 'ready' | 'error' | 'blocked';
|
|
36
|
+
viewRefreshing?: boolean | undefined;
|
|
34
37
|
viewFailure?: MergeFailure | undefined;
|
|
35
38
|
queue: MergeQueue;
|
|
36
39
|
expiredOnly: boolean;
|
|
@@ -52,6 +55,7 @@ export declare class MergeStore {
|
|
|
52
55
|
private overlayToken;
|
|
53
56
|
private snapshot;
|
|
54
57
|
private started;
|
|
58
|
+
private loadedView;
|
|
55
59
|
private disposed;
|
|
56
60
|
constructor(source: MergeSource, initial?: MergeStoreInitial);
|
|
57
61
|
readonly read: () => StoreSnapshot;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Batch 4 merge panel: keyed read store, four tabs, local overlays, localized errors. */
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
3
|
import type { MergeStore } from './MergeStore.ts';
|
|
4
|
-
import type {
|
|
4
|
+
import type { SettingsFace } from '@lmzhen/dsh-evolution-client-kit';
|
|
5
5
|
export type Translate = (key: string, values?: Readonly<Record<string, string | number>>) => string;
|
|
6
6
|
export interface MergeFace {
|
|
7
7
|
store: MergeStore;
|
|
@@ -10,6 +10,5 @@ export interface MergeFace {
|
|
|
10
10
|
settings?: SettingsFace;
|
|
11
11
|
workspaceId?: string;
|
|
12
12
|
}
|
|
13
|
-
export declare function saveSetting(form: ConfigFormLike, field: string, value: boolean): Promise<boolean>;
|
|
14
13
|
export declare function MergePanel(face: MergeFace): ReactNode;
|
|
15
14
|
//# sourceMappingURL=Panel.d.ts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/** Browser half: one
|
|
1
|
+
/** Browser half: one read-only merge view inside the shared evolution workbench. */
|
|
2
2
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
3
3
|
export declare const inject: string[];
|
|
4
4
|
/**
|
|
5
|
-
* Register the merge
|
|
5
|
+
* Register the merge view on the workbench page.
|
|
6
6
|
* @param ctx - the client context.
|
|
7
7
|
*/
|
|
8
8
|
export declare function apply(ctx: ClientContext): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Platform Modal reached through the rc.3 client module table. */
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export interface PlatformModalProps {
|
|
4
|
+
readonly open: boolean;
|
|
5
|
+
readonly onClose: () => void;
|
|
6
|
+
readonly title: string;
|
|
7
|
+
readonly closeLabel: string;
|
|
8
|
+
readonly children?: ReactNode;
|
|
9
|
+
readonly headless?: boolean;
|
|
10
|
+
readonly className?: string;
|
|
11
|
+
}
|
|
12
|
+
export type PlatformModalComponent = (props: PlatformModalProps) => ReactNode;
|
|
13
|
+
/** The platform Modal, or undefined in a non-browser/SSR render or a deployment without the row. */
|
|
14
|
+
export declare function platformModal(): PlatformModalComponent | undefined;
|
|
15
|
+
//# sourceMappingURL=platform-modal.d.ts.map
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
]
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.33.0",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"react-dom": "^18.2.0"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@lmzhen/dsh-evolution-client-kit": "^0.
|
|
54
|
+
"@lmzhen/dsh-evolution-client-kit": "^0.33.0"
|
|
55
55
|
},
|
|
56
56
|
"engines": {
|
|
57
57
|
"dsh": ">=0.2.1-rc.2 <0.2.2-0"
|