@lmzhen/dsh-evolution-merge-ui 0.30.17 → 0.30.18
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/lib/client.js +403 -139
- package/lib/types/client/Panel.d.ts +1 -1
- package/lib/types/client/api.d.ts +29 -5
- package/lib/types/client/routes.generated.d.ts +2 -0
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -5,14 +5,13 @@ 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
|
-
//#
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/client/api.ts
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* external), so the table is mirrored here mechanically; a rename in core regenerates all three
|
|
13
|
-
* client copies, and the generator's --check makes a stale copy red.
|
|
11
|
+
* The two read routes this panel uses. Parses the frozen wireVersion=1 envelopes
|
|
12
|
+
* and maps them to the panel view types; the panel never sees a path or a raw host body.
|
|
14
13
|
*/
|
|
15
|
-
const
|
|
14
|
+
const HOST_ROUTES = {
|
|
16
15
|
approval: {
|
|
17
16
|
pending: "/api/dsh-evolution/approval/pending",
|
|
18
17
|
preview: "/api/dsh-evolution/approval/preview",
|
|
@@ -31,56 +30,53 @@ window.__ModuleLoader__.load({
|
|
|
31
30
|
merge: {
|
|
32
31
|
view: "/api/dsh-evolution/merge/view",
|
|
33
32
|
rows: "/api/dsh-evolution/merge/rows",
|
|
33
|
+
run: "/api/dsh-evolution/merge/run",
|
|
34
|
+
runs: "/api/dsh-evolution/merge/runs",
|
|
34
35
|
body: "/api/dsh-evolution/merge/body",
|
|
35
36
|
history: "/api/dsh-evolution/merge/history"
|
|
36
37
|
},
|
|
37
38
|
diagnostics: { view: "/api/dsh-evolution/diagnostics" }
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
//#region src/client/route-client.generated.ts
|
|
41
|
-
/** Classify a non-2xx status: 401/403/404 keep their own kind, everything else is a server answer. */
|
|
42
|
-
function classify(status) {
|
|
43
|
-
if (status === 401) return {
|
|
44
|
-
kind: "unauthenticated",
|
|
45
|
-
status: 401
|
|
46
|
-
};
|
|
47
|
-
if (status === 403) return {
|
|
48
|
-
kind: "forbidden",
|
|
49
|
-
status: 403
|
|
50
|
-
};
|
|
51
|
-
if (status === 404) return {
|
|
52
|
-
kind: "unmounted",
|
|
53
|
-
status: 404
|
|
54
|
-
};
|
|
55
|
-
return {
|
|
56
|
-
kind: "server",
|
|
57
|
-
status
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* One request, no retries and no body parsing for the platform's admission answers.
|
|
62
|
-
* @param doFetch - the fetch in use (the browser's, or a spec's stub).
|
|
63
|
-
* @param path - the exact route path from the generated ROUTES table.
|
|
64
|
-
* @param init - standard RequestInit.
|
|
65
|
-
* @returns the data, or the classified failure (network/parse failures read as 'server').
|
|
66
|
-
*/
|
|
67
|
-
async function requestJson(doFetch, path, init) {
|
|
39
|
+
}.merge;
|
|
40
|
+
async function requestWire(path) {
|
|
68
41
|
let response;
|
|
69
42
|
try {
|
|
70
|
-
response = await
|
|
71
|
-
} catch
|
|
43
|
+
response = await fetch(path, { headers: { accept: "application/json" } });
|
|
44
|
+
} catch {
|
|
72
45
|
return {
|
|
73
46
|
ok: false,
|
|
74
47
|
failure: {
|
|
75
48
|
kind: "server",
|
|
76
|
-
status: 0
|
|
77
|
-
detail: error instanceof Error ? error.message : String(error)
|
|
49
|
+
status: 0
|
|
78
50
|
}
|
|
79
51
|
};
|
|
80
52
|
}
|
|
53
|
+
if (response.status === 401) return {
|
|
54
|
+
ok: false,
|
|
55
|
+
failure: {
|
|
56
|
+
kind: "unauthenticated",
|
|
57
|
+
status: 401
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
if (response.status === 403) return {
|
|
61
|
+
ok: false,
|
|
62
|
+
failure: {
|
|
63
|
+
kind: "forbidden",
|
|
64
|
+
status: 403
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
if (response.status === 404) return {
|
|
68
|
+
ok: false,
|
|
69
|
+
failure: {
|
|
70
|
+
kind: "unmounted",
|
|
71
|
+
status: 404
|
|
72
|
+
}
|
|
73
|
+
};
|
|
81
74
|
if (!response.ok) return {
|
|
82
75
|
ok: false,
|
|
83
|
-
failure:
|
|
76
|
+
failure: {
|
|
77
|
+
kind: "server",
|
|
78
|
+
status: response.status
|
|
79
|
+
}
|
|
84
80
|
};
|
|
85
81
|
let body;
|
|
86
82
|
try {
|
|
@@ -94,81 +90,158 @@ window.__ModuleLoader__.load({
|
|
|
94
90
|
}
|
|
95
91
|
};
|
|
96
92
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (record.ok === true) return {
|
|
100
|
-
ok: true,
|
|
101
|
-
data: record.data
|
|
102
|
-
};
|
|
103
|
-
const nested = record.error;
|
|
104
|
-
const errorRecord = typeof nested === "object" && nested !== null ? nested : void 0;
|
|
105
|
-
const code = typeof record.code === "string" && record.code !== "" ? record.code : typeof errorRecord?.code === "string" ? errorRecord.code : void 0;
|
|
106
|
-
const message = typeof record.message === "string" && record.message !== "" ? record.message : typeof errorRecord?.message === "string" ? errorRecord.message : void 0;
|
|
107
|
-
if (record.ok === false && code !== void 0 && message !== void 0 && message !== "") return {
|
|
108
|
-
ok: false,
|
|
109
|
-
failure: {
|
|
110
|
-
kind: "refused",
|
|
111
|
-
code,
|
|
112
|
-
message
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
93
|
+
const record = body;
|
|
94
|
+
if (record.wireVersion !== 1) return {
|
|
117
95
|
ok: false,
|
|
118
96
|
failure: {
|
|
119
97
|
kind: "server",
|
|
120
98
|
status: response.status
|
|
121
99
|
}
|
|
122
100
|
};
|
|
101
|
+
if (typeof record.code === "string") return {
|
|
102
|
+
ok: false,
|
|
103
|
+
failure: {
|
|
104
|
+
kind: "refused",
|
|
105
|
+
code: record.code,
|
|
106
|
+
message: typeof record.message === "string" ? record.message : record.code
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
return {
|
|
110
|
+
ok: true,
|
|
111
|
+
payload: body
|
|
112
|
+
};
|
|
123
113
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
114
|
+
const escapeHtml = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
115
|
+
const toRun = (run) => ({
|
|
116
|
+
id: run.id,
|
|
117
|
+
state: run.state,
|
|
118
|
+
...run.command === void 0 ? {} : { command: run.command },
|
|
119
|
+
...run.stage === void 0 ? {} : { stage: run.stage },
|
|
120
|
+
...run.progress === null || run.progress === void 0 ? {} : { progress: {
|
|
121
|
+
done: run.progress.done,
|
|
122
|
+
total: run.progress.total
|
|
123
|
+
} },
|
|
124
|
+
startedAt: run.startedAt
|
|
125
|
+
});
|
|
126
|
+
const toRow = (row) => ({
|
|
127
|
+
id: row.id,
|
|
128
|
+
pairKey: row.id,
|
|
129
|
+
a: row.a,
|
|
130
|
+
b: row.b,
|
|
131
|
+
state: row.state,
|
|
132
|
+
queue: row.queue,
|
|
133
|
+
stage: null,
|
|
134
|
+
label: row.a + " + " + row.b,
|
|
135
|
+
updatedAt: new Date(row.updatedAt).toISOString(),
|
|
136
|
+
createdAt: new Date(row.createdAt).toISOString(),
|
|
137
|
+
...row.target === void 0 ? {} : {
|
|
138
|
+
target: row.target.requested,
|
|
139
|
+
...row.target.actual === void 0 ? {} : { targetActual: row.target.actual },
|
|
140
|
+
...row.target.created === void 0 ? {} : { targetCreated: row.target.created }
|
|
141
|
+
},
|
|
142
|
+
...row.staging?.state === void 0 ? {} : { stagingState: row.staging.state },
|
|
143
|
+
...row.verifySubState === void 0 ? {} : { verifySubState: row.verifySubState },
|
|
144
|
+
...row.skipKind === void 0 ? {} : { skipKind: row.skipKind },
|
|
145
|
+
...row.bodies === void 0 ? {} : { bodies: row.bodies.map((body) => ({
|
|
146
|
+
name: body.name,
|
|
147
|
+
side: body.side
|
|
148
|
+
})) },
|
|
149
|
+
...row.confidence === void 0 ? {} : { confidence: row.confidence },
|
|
150
|
+
...row.expiresAt === void 0 ? {} : { expiresAt: row.expiresAt },
|
|
151
|
+
...row.summary === void 0 ? {} : { summary: [
|
|
152
|
+
row.summary.a,
|
|
153
|
+
row.summary.b,
|
|
154
|
+
row.summary.rationale
|
|
155
|
+
].filter((value) => value !== null) },
|
|
156
|
+
...row.reason === void 0 ? {} : { reason: row.reason },
|
|
157
|
+
...row.origin === void 0 ? {} : { origin: row.origin === "system" ? "agent" : row.origin },
|
|
158
|
+
...row.failure === void 0 ? {} : { failure: {
|
|
159
|
+
stage: row.failure.stage,
|
|
160
|
+
code: row.failure.code,
|
|
161
|
+
message: row.failure.detail ?? row.failure.code,
|
|
162
|
+
retryable: row.failure.retryable
|
|
163
|
+
} },
|
|
164
|
+
...row.staging?.expiresAt === void 0 ? {} : { stagingExpiresAt: row.staging.expiresAt },
|
|
165
|
+
...row.expired === void 0 ? {} : { expired: row.expired.kind },
|
|
166
|
+
...row.attempts === void 0 ? {} : { attempts: row.attempts },
|
|
167
|
+
actions: row.actions.map((action) => ({
|
|
168
|
+
id: action.id,
|
|
169
|
+
command: action.command,
|
|
170
|
+
confirm: action.confirm,
|
|
171
|
+
enabled: action.enabled,
|
|
172
|
+
...action.disabledReason === void 0 ? {} : { disabledReason: action.disabledReason }
|
|
173
|
+
}))
|
|
174
|
+
});
|
|
131
175
|
async function view() {
|
|
132
|
-
const answer = await
|
|
133
|
-
|
|
176
|
+
const answer = await requestWire(HOST_ROUTES.view);
|
|
177
|
+
if (!answer.ok) return answer;
|
|
178
|
+
const facts = answer.payload;
|
|
179
|
+
return {
|
|
134
180
|
ok: true,
|
|
135
|
-
payload:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
181
|
+
payload: {
|
|
182
|
+
counts: facts.counts.active,
|
|
183
|
+
expired: facts.counts.expired,
|
|
184
|
+
tabs: [
|
|
185
|
+
"verify",
|
|
186
|
+
"pending",
|
|
187
|
+
"fuse",
|
|
188
|
+
"skipped"
|
|
189
|
+
].map((queue) => ({
|
|
190
|
+
queue,
|
|
191
|
+
count: facts.counts.active[queue]
|
|
192
|
+
})),
|
|
193
|
+
commands: facts.fallback.map((item) => item.command),
|
|
194
|
+
startCommands: facts.startCommands,
|
|
195
|
+
notes: [...facts.notes],
|
|
196
|
+
degraded: facts.degraded,
|
|
197
|
+
...facts.last === null && facts.active === null ? {} : { latestRun: toRun(facts.last ?? facts.active) },
|
|
198
|
+
approval: facts.approval.mergeApproval
|
|
199
|
+
}
|
|
139
200
|
};
|
|
140
201
|
}
|
|
141
|
-
async function rows(queue, cursor =
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
ok: true,
|
|
146
|
-
payload: answer.data
|
|
147
|
-
} : {
|
|
202
|
+
async function rows(queue, cursor, expiredOnly = false) {
|
|
203
|
+
const answer = await requestWire(HOST_ROUTES.rows + "?queue=" + encodeURIComponent(queue) + (cursor === void 0 ? "" : "&cursor=" + encodeURIComponent(cursor)) + (expiredOnly ? "&expired=1" : ""));
|
|
204
|
+
if (!answer.ok) return answer;
|
|
205
|
+
if (answer.payload.queue !== queue || answer.payload.expiredOnly !== expiredOnly) return {
|
|
148
206
|
ok: false,
|
|
149
|
-
failure:
|
|
207
|
+
failure: {
|
|
208
|
+
kind: "server",
|
|
209
|
+
status: 200
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
return {
|
|
213
|
+
ok: true,
|
|
214
|
+
payload: {
|
|
215
|
+
queue: answer.payload.queue,
|
|
216
|
+
items: answer.payload.rows.map(toRow),
|
|
217
|
+
...answer.payload.nextCursor === void 0 ? {} : { nextCursor: answer.payload.nextCursor }
|
|
218
|
+
}
|
|
150
219
|
};
|
|
151
220
|
}
|
|
152
221
|
async function body(id, side) {
|
|
153
|
-
const
|
|
154
|
-
const answer = await requestJson(fetch, url, { headers: { accept: "application/json" } });
|
|
222
|
+
const answer = await requestWire(HOST_ROUTES.body + "?id=" + encodeURIComponent(id) + "&side=" + side);
|
|
155
223
|
return answer.ok ? {
|
|
156
224
|
ok: true,
|
|
157
|
-
payload:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
225
|
+
payload: {
|
|
226
|
+
content: answer.payload.text,
|
|
227
|
+
markdown: answer.payload.markdown,
|
|
228
|
+
html: escapeHtml(answer.payload.text)
|
|
229
|
+
}
|
|
230
|
+
} : answer;
|
|
162
231
|
}
|
|
163
232
|
async function history() {
|
|
164
|
-
const answer = await
|
|
233
|
+
const answer = await requestWire(HOST_ROUTES.history);
|
|
165
234
|
return answer.ok ? {
|
|
166
235
|
ok: true,
|
|
167
|
-
payload: answer.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
236
|
+
payload: { items: answer.payload.items.map((item) => ({
|
|
237
|
+
name: item.name,
|
|
238
|
+
kind: item.kind,
|
|
239
|
+
reason: item.reason,
|
|
240
|
+
lastVersion: item.lastVersion,
|
|
241
|
+
archivedAt: new Date(item.archivedAt).toISOString(),
|
|
242
|
+
...item.sourceRunId === void 0 ? {} : { sourceRunId: item.sourceRunId }
|
|
243
|
+
})) }
|
|
244
|
+
} : answer;
|
|
172
245
|
}
|
|
173
246
|
//#endregion
|
|
174
247
|
//#region src/client/seam.ts
|
|
@@ -178,6 +251,13 @@ window.__ModuleLoader__.load({
|
|
|
178
251
|
const NS = "evolution-merge";
|
|
179
252
|
const zh = {
|
|
180
253
|
"entry.label": "技能合并",
|
|
254
|
+
"title": "技能合并",
|
|
255
|
+
"start.scan": "复制扫描命令",
|
|
256
|
+
"start.pair": "复制配对命令",
|
|
257
|
+
"degraded": "读模型降级:",
|
|
258
|
+
"copied": "已复制:",
|
|
259
|
+
"row.noSummary": "无摘要",
|
|
260
|
+
"overlay.body": "正文",
|
|
181
261
|
"hint": "手动触发;后台逐对判定。这里只读,不写技能。",
|
|
182
262
|
"history": "历史",
|
|
183
263
|
"close": "关闭",
|
|
@@ -209,6 +289,55 @@ window.__ModuleLoader__.load({
|
|
|
209
289
|
"row.failure": "失败",
|
|
210
290
|
"row.noRetry": "不可重试",
|
|
211
291
|
"row.copy": "复制命令",
|
|
292
|
+
"tab.expired": "已过期",
|
|
293
|
+
"row.targetCreated": "新建",
|
|
294
|
+
"row.verify": "判定状态",
|
|
295
|
+
"row.staging": "暂存",
|
|
296
|
+
"row.skipKind": "跳过类型",
|
|
297
|
+
"row.bodies": "正文",
|
|
298
|
+
"verify.queued": "排队",
|
|
299
|
+
"verify.running": "进行中",
|
|
300
|
+
"verify.failed": "失败",
|
|
301
|
+
"verify.cancelled": "已取消",
|
|
302
|
+
"staging.none": "无",
|
|
303
|
+
"staging.kept": "保留",
|
|
304
|
+
"staging.cleared-source-ok": "已清理(源完好)",
|
|
305
|
+
"staging.cleared-source-gone": "已清理(源已缺失)",
|
|
306
|
+
"skipKind.agent-keep": "自动保留",
|
|
307
|
+
"skipKind.human-reject": "人工拒绝",
|
|
308
|
+
"skipKind.over-limit": "超限",
|
|
309
|
+
"skipKind.forced": "强制",
|
|
310
|
+
"action.approve": "复制批准",
|
|
311
|
+
"action.reject": "复制拒绝",
|
|
312
|
+
"action.retry-candidates": "重试候选",
|
|
313
|
+
"action.retry-resume": "重试续跑",
|
|
314
|
+
"action.discard": "复制丢弃",
|
|
315
|
+
"action.restore": "恢复",
|
|
316
|
+
"action.pair": "复制配对",
|
|
317
|
+
"action.status": "状态",
|
|
318
|
+
"action.report": "报告",
|
|
319
|
+
"action.cancel": "取消",
|
|
320
|
+
"action.confirm": "确认复制",
|
|
321
|
+
"disabled.expired": "已过期,不可用",
|
|
322
|
+
"disabled.invalid": "状态不允许",
|
|
323
|
+
"disabled.not-retryable": "不可重试",
|
|
324
|
+
"disabled.source-gone": "源已缺失",
|
|
325
|
+
"disabled.owned": "已有运行",
|
|
326
|
+
"disabled.unavailable": "暂不可用",
|
|
327
|
+
"history.empty": "没有历史。",
|
|
328
|
+
"failureServer": "读取失败",
|
|
329
|
+
"failureUnauthorized": "未登录",
|
|
330
|
+
"failureForbidden": "无权访问",
|
|
331
|
+
"failureUnmounted": "宿主未挂载",
|
|
332
|
+
"fallbackHint": "可复制命令见下方",
|
|
333
|
+
"body.missing": "正文不存在或不可读。",
|
|
334
|
+
"expired.target-taken": "目标已被占用",
|
|
335
|
+
"expired.source-changed": "源已变更",
|
|
336
|
+
"expired.skipped-ttl": "跳过已到期",
|
|
337
|
+
"history.kind.merged": "已合并",
|
|
338
|
+
"history.kind.deleted": "已删除",
|
|
339
|
+
"history.kind.split": "已拆分",
|
|
340
|
+
"history.kind.other": "其他",
|
|
212
341
|
"origin.agent": "自动",
|
|
213
342
|
"origin.human": "人工",
|
|
214
343
|
"state.verify": "待判定",
|
|
@@ -219,6 +348,13 @@ window.__ModuleLoader__.load({
|
|
|
219
348
|
};
|
|
220
349
|
const en = {
|
|
221
350
|
"entry.label": "Skill merge",
|
|
351
|
+
"title": "Skill merge",
|
|
352
|
+
"start.scan": "Copy scan command",
|
|
353
|
+
"start.pair": "Copy pair command",
|
|
354
|
+
"degraded": "Degraded read model:",
|
|
355
|
+
"copied": "Copied:",
|
|
356
|
+
"row.noSummary": "No summary",
|
|
357
|
+
"overlay.body": "Body",
|
|
222
358
|
"hint": "Manual only; pairs are judged in the background. Read-only here.",
|
|
223
359
|
"history": "History",
|
|
224
360
|
"close": "Close",
|
|
@@ -250,6 +386,55 @@ window.__ModuleLoader__.load({
|
|
|
250
386
|
"row.failure": "Failure",
|
|
251
387
|
"row.noRetry": "not retryable",
|
|
252
388
|
"row.copy": "Copy command",
|
|
389
|
+
"tab.expired": "Expired",
|
|
390
|
+
"row.targetCreated": "created",
|
|
391
|
+
"row.verify": "Verify state",
|
|
392
|
+
"row.staging": "Staging",
|
|
393
|
+
"row.skipKind": "Skip kind",
|
|
394
|
+
"row.bodies": "Bodies",
|
|
395
|
+
"verify.queued": "queued",
|
|
396
|
+
"verify.running": "running",
|
|
397
|
+
"verify.failed": "failed",
|
|
398
|
+
"verify.cancelled": "cancelled",
|
|
399
|
+
"staging.none": "none",
|
|
400
|
+
"staging.kept": "kept",
|
|
401
|
+
"staging.cleared-source-ok": "cleared (source ok)",
|
|
402
|
+
"staging.cleared-source-gone": "cleared (source gone)",
|
|
403
|
+
"skipKind.agent-keep": "agent keep",
|
|
404
|
+
"skipKind.human-reject": "human reject",
|
|
405
|
+
"skipKind.over-limit": "over limit",
|
|
406
|
+
"skipKind.forced": "forced",
|
|
407
|
+
"action.approve": "Copy approve",
|
|
408
|
+
"action.reject": "Copy reject",
|
|
409
|
+
"action.retry-candidates": "Retry candidates",
|
|
410
|
+
"action.retry-resume": "Retry resume",
|
|
411
|
+
"action.discard": "Copy discard",
|
|
412
|
+
"action.restore": "Restore",
|
|
413
|
+
"action.pair": "Copy pair",
|
|
414
|
+
"action.status": "Status",
|
|
415
|
+
"action.report": "Report",
|
|
416
|
+
"action.cancel": "Cancel",
|
|
417
|
+
"action.confirm": "Copy confirmation",
|
|
418
|
+
"disabled.expired": "expired",
|
|
419
|
+
"disabled.invalid": "invalid state",
|
|
420
|
+
"disabled.not-retryable": "not retryable",
|
|
421
|
+
"disabled.source-gone": "source gone",
|
|
422
|
+
"disabled.owned": "already running",
|
|
423
|
+
"disabled.unavailable": "unavailable",
|
|
424
|
+
"history.empty": "No history.",
|
|
425
|
+
"failureServer": "Read failed",
|
|
426
|
+
"failureUnauthorized": "Not signed in",
|
|
427
|
+
"failureForbidden": "Forbidden",
|
|
428
|
+
"failureUnmounted": "Host not mounted",
|
|
429
|
+
"fallbackHint": "Copy the command below",
|
|
430
|
+
"body.missing": "Body missing or unreadable.",
|
|
431
|
+
"expired.target-taken": "target taken",
|
|
432
|
+
"expired.source-changed": "source changed",
|
|
433
|
+
"expired.skipped-ttl": "skip expired",
|
|
434
|
+
"history.kind.merged": "Merged",
|
|
435
|
+
"history.kind.deleted": "Deleted",
|
|
436
|
+
"history.kind.split": "Split",
|
|
437
|
+
"history.kind.other": "Other",
|
|
253
438
|
"origin.agent": "auto",
|
|
254
439
|
"origin.human": "human",
|
|
255
440
|
"state.verify": "Unverified",
|
|
@@ -272,6 +457,16 @@ window.__ModuleLoader__.load({
|
|
|
272
457
|
".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); }",
|
|
273
458
|
".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; }",
|
|
274
459
|
".evolution-merge-panel [data-role=\"tab\"][data-active=\"true\"] { border-bottom-color:var(--dsw-alias-brand-primary); }",
|
|
460
|
+
".evolution-merge-panel button:focus-visible { outline:2px solid currentColor !important; outline-offset:2px; box-shadow:0 0 0 2px currentColor !important; }",
|
|
461
|
+
".evolution-merge-panel [data-role=\"title\"] { margin:0; font-size:var(--evo-type-lg); font-weight:600; }",
|
|
462
|
+
".evolution-merge-panel [data-role=\"start\"] { display:flex; gap:var(--evo-space-6); flex-wrap:wrap; }",
|
|
463
|
+
".evolution-merge-panel [data-role=\"degraded\"] { margin:0; color:var(--dsw-alias-state-warning-primary); font-size:var(--evo-type-xs); }",
|
|
464
|
+
".evolution-merge-panel [data-role=\"expired-toggle\"][data-active=\"true\"] { background:var(--dsw-alias-brand-primary); color:var(--dsw-alias-bg-base); }",
|
|
465
|
+
".evolution-merge-panel [data-role=\"failure\"] { display:flex; flex-direction:column; gap:var(--evo-space-6); }",
|
|
466
|
+
".evolution-merge-panel [data-role=\"failure\"] [data-tone=\"fail\"] { color:var(--dsw-alias-state-error-primary); }",
|
|
467
|
+
".evolution-merge-panel [data-role=\"fallback\"] { display:flex; gap:var(--evo-space-6); flex-wrap:wrap; }",
|
|
468
|
+
".evolution-merge-panel [data-role=\"overlay\"] { position:relative; 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); }",
|
|
469
|
+
".evolution-merge-panel [data-role=\"overlay-title\"] { margin:0; font-size:var(--evo-type-lg); }",
|
|
275
470
|
".evolution-merge-panel [data-role=\"rows\"] { display:flex; flex-direction:column; gap:var(--evo-space-6); }",
|
|
276
471
|
".evolution-merge-panel [data-role=\"row\"] { display:grid; grid-template-columns:1fr auto; gap:var(--evo-space-8); padding:var(--evo-space-8); border:var(--evo-hairline-width) solid var(--dsw-alias-border-l2); border-radius:var(--evo-radius-control); }",
|
|
277
472
|
".evolution-merge-panel [data-role=\"row-label\"] { font-weight:600; }",
|
|
@@ -338,6 +533,14 @@ window.__ModuleLoader__.load({
|
|
|
338
533
|
"skipped"
|
|
339
534
|
];
|
|
340
535
|
function failure(t, failure) {
|
|
536
|
+
if (failure.kind === "refused" && failure.code === "merge-body-missing") return FailureBlock({
|
|
537
|
+
failure: {
|
|
538
|
+
...failure,
|
|
539
|
+
message: t("body.missing")
|
|
540
|
+
},
|
|
541
|
+
t,
|
|
542
|
+
fallback: FALLBACKS["merge"]
|
|
543
|
+
});
|
|
341
544
|
return FailureBlock({
|
|
342
545
|
failure,
|
|
343
546
|
t,
|
|
@@ -348,22 +551,28 @@ window.__ModuleLoader__.load({
|
|
|
348
551
|
const t = face.t;
|
|
349
552
|
const [view, setView] = (0, react.useState)(face.view);
|
|
350
553
|
const [tab, setTab] = (0, react.useState)("pending");
|
|
554
|
+
const [expiredOnly, setExpiredOnly] = (0, react.useState)(false);
|
|
351
555
|
const [rows, setRows] = (0, react.useState)(face.rows);
|
|
352
556
|
const [loading, setLoading] = (0, react.useState)(face.loadRows !== void 0 || face.loadView !== void 0);
|
|
353
557
|
const [failed, setFailed] = (0, react.useState)(void 0);
|
|
354
558
|
const [nextCursor, setNextCursor] = (0, react.useState)(void 0);
|
|
559
|
+
const [copied, setCopied] = (0, react.useState)(void 0);
|
|
355
560
|
const [overlay, setOverlay] = (0, react.useState)(void 0);
|
|
356
561
|
const request = (0, react.useRef)(0);
|
|
357
|
-
const
|
|
562
|
+
const copyCommand = (command) => {
|
|
563
|
+
navigator.clipboard.writeText(command);
|
|
564
|
+
setCopied(command);
|
|
565
|
+
};
|
|
566
|
+
const loadRows = (queue, cursor, expired = false) => {
|
|
358
567
|
const load = face.loadRows;
|
|
359
568
|
if (load === void 0) return;
|
|
360
569
|
const token = request.current + 1;
|
|
361
570
|
request.current = token;
|
|
362
571
|
setLoading(true);
|
|
363
|
-
load(queue, cursor).then((outcome) => {
|
|
572
|
+
load(queue, cursor, queue === "pending" && expired).then((outcome) => {
|
|
364
573
|
if (token !== request.current) return;
|
|
365
574
|
if (outcome.ok) {
|
|
366
|
-
setRows((current) => [...cursor === 0 ? [] : current, ...outcome.payload.items].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)));
|
|
575
|
+
setRows((current) => [...cursor === void 0 ? [] : current, ...outcome.payload.items].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)));
|
|
367
576
|
setNextCursor(outcome.payload.nextCursor);
|
|
368
577
|
setFailed(void 0);
|
|
369
578
|
} else setFailed(outcome.failure);
|
|
@@ -384,13 +593,6 @@ window.__ModuleLoader__.load({
|
|
|
384
593
|
setFailed(outcome.failure);
|
|
385
594
|
return;
|
|
386
595
|
}
|
|
387
|
-
if (outcome.payload.schemaVersion !== void 0 && outcome.payload.schemaVersion !== 2) {
|
|
388
|
-
setFailed({
|
|
389
|
-
kind: "server",
|
|
390
|
-
status: 0
|
|
391
|
-
});
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
596
|
setView(outcome.payload);
|
|
395
597
|
}).catch(() => {
|
|
396
598
|
setFailed({
|
|
@@ -403,12 +605,14 @@ window.__ModuleLoader__.load({
|
|
|
403
605
|
const load = face.loadBody;
|
|
404
606
|
if (load === void 0) return;
|
|
405
607
|
load(id, side).then((outcome) => {
|
|
406
|
-
if (outcome.ok)
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
608
|
+
if (outcome.ok) {
|
|
609
|
+
setFailed(void 0);
|
|
610
|
+
setOverlay({
|
|
611
|
+
kind: "body",
|
|
612
|
+
html: outcome.payload.html,
|
|
613
|
+
label: id + ":" + side
|
|
614
|
+
});
|
|
615
|
+
} else setFailed(outcome.failure);
|
|
412
616
|
}).catch(() => {
|
|
413
617
|
setFailed({
|
|
414
618
|
kind: "server",
|
|
@@ -420,11 +624,13 @@ window.__ModuleLoader__.load({
|
|
|
420
624
|
const load = face.loadHistory;
|
|
421
625
|
if (load === void 0) return;
|
|
422
626
|
load().then((outcome) => {
|
|
423
|
-
if (outcome.ok)
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
627
|
+
if (outcome.ok) {
|
|
628
|
+
setFailed(void 0);
|
|
629
|
+
setOverlay({
|
|
630
|
+
kind: "history",
|
|
631
|
+
items: outcome.payload.items
|
|
632
|
+
});
|
|
633
|
+
} else setFailed(outcome.failure);
|
|
428
634
|
}).catch(() => {
|
|
429
635
|
setFailed({
|
|
430
636
|
kind: "server",
|
|
@@ -437,15 +643,11 @@ window.__ModuleLoader__.load({
|
|
|
437
643
|
loadRows("pending");
|
|
438
644
|
}, [face]);
|
|
439
645
|
(0, react.useEffect)(() => {
|
|
646
|
+
if (tab !== "pending" && expiredOnly) setExpiredOnly(false);
|
|
440
647
|
setNextCursor(void 0);
|
|
441
|
-
loadRows(tab, 0);
|
|
442
|
-
}, [tab]);
|
|
648
|
+
loadRows(tab, void 0, tab === "pending" && expiredOnly);
|
|
649
|
+
}, [tab, expiredOnly]);
|
|
443
650
|
const counts = view.counts;
|
|
444
|
-
const stats = (0, react.createElement)("div", { "data-role": "stats" }, QUEUES.map((queue) => (0, react.createElement)("div", {
|
|
445
|
-
key: queue,
|
|
446
|
-
"data-role": "stat",
|
|
447
|
-
"data-queue": queue
|
|
448
|
-
}, (0, react.createElement)("div", { "data-role": "stat-value" }, String(counts[queue])), (0, react.createElement)("div", { "data-role": "stat-label" }, t("tab." + queue)))));
|
|
449
651
|
const latest = view.latestRun;
|
|
450
652
|
const runStrip = latest === void 0 ? null : (0, react.createElement)("div", { "data-role": "run-strip" }, (0, react.createElement)("span", { "data-role": "run-id" }, latest.id), (0, react.createElement)("span", { "data-role": "run-state" }, latest.state), latest.stage === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-stage" }, t("stage." + latest.stage)), latest.progress === void 0 ? null : (0, react.createElement)("span", { "data-role": "run-progress" }, String(latest.progress.done) + "/" + String(latest.progress.total)));
|
|
451
653
|
const tabs = (0, react.createElement)("div", {
|
|
@@ -462,57 +664,102 @@ window.__ModuleLoader__.load({
|
|
|
462
664
|
setTab(queue);
|
|
463
665
|
}
|
|
464
666
|
}, t("tab." + queue) + " " + String(counts[queue]))));
|
|
667
|
+
const expiredToggle = tab === "pending" ? (0, react.createElement)("button", {
|
|
668
|
+
type: "button",
|
|
669
|
+
role: "switch",
|
|
670
|
+
"aria-checked": expiredOnly ? "true" : "false",
|
|
671
|
+
"data-role": "expired-toggle",
|
|
672
|
+
"data-active": expiredOnly ? "true" : "false",
|
|
673
|
+
onClick: () => {
|
|
674
|
+
setExpiredOnly((value) => !value);
|
|
675
|
+
}
|
|
676
|
+
}, t("tab.expired") + " " + String(view.expired)) : null;
|
|
465
677
|
const list = rows.length === 0 ? (0, react.createElement)("p", { "data-role": "note" }, t("empty." + tab)) : (0, react.createElement)("div", { "data-role": "rows" }, rows.map((row) => {
|
|
466
678
|
const facts = [
|
|
467
|
-
row.target === void 0 ? void 0 : t("row.target") + " " + row.target,
|
|
679
|
+
row.target === void 0 ? void 0 : t("row.target") + " " + row.target + (row.targetActual === void 0 ? "" : " → " + row.targetActual) + (row.targetCreated === true ? " (" + t("row.targetCreated") + ")" : ""),
|
|
680
|
+
row.verifySubState === void 0 ? void 0 : t("row.verify") + " " + t("verify." + row.verifySubState),
|
|
681
|
+
row.stagingState === void 0 || row.stagingState === "none" ? void 0 : t("row.staging") + " " + t("staging." + row.stagingState),
|
|
682
|
+
row.skipKind === void 0 ? void 0 : t("row.skipKind") + " " + t("skipKind." + row.skipKind),
|
|
683
|
+
row.bodies === void 0 ? void 0 : t("row.bodies") + " " + row.bodies.map((body) => body.name + "(" + body.side + ")").join(", "),
|
|
468
684
|
row.confidence === void 0 ? void 0 : t("row.confidence") + " " + row.confidence.toFixed(2),
|
|
469
685
|
row.attempts === void 0 ? void 0 : t("row.attempts") + " " + String(row.attempts),
|
|
470
686
|
row.origin === void 0 ? void 0 : t("row.origin") + " " + t("origin." + row.origin),
|
|
471
687
|
row.stagingExpiresAt === void 0 ? void 0 : t("row.expires") + " " + new Date(row.stagingExpiresAt).toLocaleString(),
|
|
472
|
-
row.expired === void 0 ? void 0 : t("row.expired") + " " + row.expired,
|
|
688
|
+
row.expired === void 0 ? void 0 : t("row.expired") + " " + t("expired." + row.expired),
|
|
473
689
|
row.reason === void 0 ? void 0 : t("row.reason") + " " + row.reason,
|
|
474
|
-
row.summary === void 0 ? void 0 : row.summary.filter(Boolean).join(" · "),
|
|
690
|
+
row.summary === void 0 ? void 0 : row.summary.filter(Boolean).join(" · ") || t("row.noSummary"),
|
|
475
691
|
row.failure === void 0 ? void 0 : t("row.failure") + " " + row.failure.message + (row.failure.retryable ? "" : " · " + t("row.noRetry"))
|
|
476
692
|
].filter((value) => value !== void 0).join(" · ");
|
|
477
693
|
return (0, react.createElement)("div", {
|
|
478
694
|
key: row.id,
|
|
479
695
|
"data-role": "row"
|
|
480
|
-
}, (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))
|
|
696
|
+
}, (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))), 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" }, face.loadBody === void 0 || row.bodies === void 0 ? null : (0, react.createElement)("button", {
|
|
481
697
|
type: "button",
|
|
482
698
|
"data-role": "body-a",
|
|
483
699
|
onClick: () => {
|
|
484
700
|
openBody(row.id, "a");
|
|
485
701
|
}
|
|
486
|
-
}, "A"), face.loadBody === void 0 ? null : (0, react.createElement)("button", {
|
|
702
|
+
}, "A"), face.loadBody === void 0 || row.bodies === void 0 ? null : (0, react.createElement)("button", {
|
|
487
703
|
type: "button",
|
|
488
704
|
"data-role": "body-b",
|
|
489
705
|
onClick: () => {
|
|
490
706
|
openBody(row.id, "b");
|
|
491
707
|
}
|
|
492
|
-
}, "B"), (row.actions ?? []).
|
|
493
|
-
key: action,
|
|
708
|
+
}, "B"), (row.actions ?? []).map((action) => (0, react.createElement)("button", {
|
|
709
|
+
key: action.id,
|
|
494
710
|
type: "button",
|
|
495
711
|
"data-role": "row-action",
|
|
496
|
-
|
|
712
|
+
"data-action": action.id,
|
|
713
|
+
title: action.disabledReason === void 0 ? action.command : t("disabled." + action.disabledReason),
|
|
714
|
+
disabled: !action.enabled,
|
|
497
715
|
onClick: () => {
|
|
498
|
-
|
|
716
|
+
if (!action.enabled) return;
|
|
717
|
+
if (action.confirm && globalThis.confirm !== void 0 && !globalThis.confirm(t("action.confirm") + " " + t("action." + action.id))) return;
|
|
718
|
+
copyCommand(action.command);
|
|
499
719
|
}
|
|
500
|
-
}, t("
|
|
720
|
+
}, t("action." + action.id))))));
|
|
501
721
|
}));
|
|
502
722
|
return (0, react.createElement)("section", {
|
|
503
723
|
className: CSS_TAG_ID,
|
|
504
724
|
"data-state": loading ? "loading" : failed !== void 0 ? "failed" : rows.length === 0 ? "empty" : "ready"
|
|
505
|
-
}, (0, react.createElement)("
|
|
725
|
+
}, (0, react.createElement)("h2", { "data-role": "title" }, t("title")), (0, react.createElement)("p", { "data-role": "hint" }, t("hint")), (0, react.createElement)("div", { "data-role": "start" }, (0, react.createElement)("button", {
|
|
726
|
+
type: "button",
|
|
727
|
+
"data-role": "start-scan",
|
|
728
|
+
onClick: () => {
|
|
729
|
+
copyCommand(view.startCommands.scan);
|
|
730
|
+
}
|
|
731
|
+
}, t("start.scan")), (0, react.createElement)("button", {
|
|
732
|
+
type: "button",
|
|
733
|
+
"data-role": "start-pair",
|
|
734
|
+
onClick: () => {
|
|
735
|
+
copyCommand(view.startCommands.pair);
|
|
736
|
+
}
|
|
737
|
+
}, t("start.pair"))), view.degraded ? (0, react.createElement)("p", { "data-role": "degraded" }, t("degraded") + " " + view.notes.join(",")) : null, view.approval === void 0 ? null : (0, react.createElement)("p", { "data-role": "approval" }, t(view.approval ? "approval.on" : "approval.off")), runStrip, tabs, expiredToggle, loading ? (0, react.createElement)("p", { "data-role": "note" }, t("loading")) : null, failed === void 0 ? null : (0, react.createElement)("div", { "data-role": "failure" }, failure(t, failed), (0, react.createElement)("div", { "data-role": "fallback" }, view.commands.map((command) => (0, react.createElement)("button", {
|
|
738
|
+
key: command,
|
|
739
|
+
type: "button",
|
|
740
|
+
"data-role": "fallback-command",
|
|
741
|
+
onClick: () => {
|
|
742
|
+
copyCommand(command);
|
|
743
|
+
}
|
|
744
|
+
}, command)))), copied === void 0 ? null : (0, react.createElement)("p", {
|
|
745
|
+
"data-role": "copied",
|
|
746
|
+
role: "status"
|
|
747
|
+
}, t("copied") + " " + copied), list, nextCursor === void 0 ? null : (0, react.createElement)("button", {
|
|
506
748
|
type: "button",
|
|
507
749
|
"data-role": "load-more",
|
|
508
750
|
onClick: () => {
|
|
509
|
-
loadRows(tab,
|
|
751
|
+
loadRows(tab, nextCursor, expiredOnly);
|
|
510
752
|
}
|
|
511
753
|
}, t("loadMore")), face.loadHistory === void 0 ? null : (0, react.createElement)("button", {
|
|
512
754
|
type: "button",
|
|
513
755
|
"data-role": "history",
|
|
514
756
|
onClick: openHistory
|
|
515
|
-
}, t("history")), overlay === void 0 ? null : (0, react.createElement)("section", {
|
|
757
|
+
}, t("history")), overlay === void 0 ? null : (0, react.createElement)("section", {
|
|
758
|
+
"data-role": "overlay",
|
|
759
|
+
role: "dialog",
|
|
760
|
+
"aria-modal": "true",
|
|
761
|
+
"aria-label": overlay.kind === "body" ? t("overlay.body") : t("history")
|
|
762
|
+
}, (0, react.createElement)("h3", { "data-role": "overlay-title" }, overlay.kind === "body" ? t("overlay.body") : t("history")), (0, react.createElement)("button", {
|
|
516
763
|
type: "button",
|
|
517
764
|
"data-role": "overlay-close",
|
|
518
765
|
onClick: () => {
|
|
@@ -522,12 +769,12 @@ window.__ModuleLoader__.load({
|
|
|
522
769
|
"data-role": "body",
|
|
523
770
|
"data-label": overlay.label,
|
|
524
771
|
dangerouslySetInnerHTML: { __html: overlay.html }
|
|
525
|
-
}) : (0, react.createElement)("ul", { "data-role": "history-list" }, overlay.items.map((item) => (0, react.createElement)("li", { key: item.name }, item.name + " · " + item.kind + " · " + item.reason + " · v" + String(item.lastVersion))))), (0, react.createElement)("button", {
|
|
772
|
+
}) : 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", { key: item.name }, item.name + " · " + t("history.kind." + item.kind) + " · " + item.reason + " · v" + String(item.lastVersion))))), (0, react.createElement)("button", {
|
|
526
773
|
type: "button",
|
|
527
774
|
"data-role": "refresh",
|
|
528
775
|
onClick: () => {
|
|
529
776
|
loadView();
|
|
530
|
-
loadRows(tab, 0);
|
|
777
|
+
loadRows(tab, void 0, tab === "pending" && expiredOnly);
|
|
531
778
|
}
|
|
532
779
|
}, t("refresh")));
|
|
533
780
|
}
|
|
@@ -556,6 +803,7 @@ window.__ModuleLoader__.load({
|
|
|
556
803
|
fuse: 0,
|
|
557
804
|
skipped: 0
|
|
558
805
|
},
|
|
806
|
+
expired: 0,
|
|
559
807
|
tabs: [
|
|
560
808
|
{
|
|
561
809
|
queue: "verify",
|
|
@@ -574,7 +822,23 @@ window.__ModuleLoader__.load({
|
|
|
574
822
|
count: 0
|
|
575
823
|
}
|
|
576
824
|
],
|
|
577
|
-
commands: [
|
|
825
|
+
commands: [
|
|
826
|
+
"/evolution merge scan",
|
|
827
|
+
"/evolution merge pair <a> <b>",
|
|
828
|
+
"/evolution merge candidates",
|
|
829
|
+
"/evolution merge pending",
|
|
830
|
+
"/evolution merge resume",
|
|
831
|
+
"/evolution merge skipped",
|
|
832
|
+
"/evolution merge status",
|
|
833
|
+
"/evolution merge report",
|
|
834
|
+
"/evolution merge doctor"
|
|
835
|
+
],
|
|
836
|
+
startCommands: {
|
|
837
|
+
scan: "/evolution merge scan",
|
|
838
|
+
pair: "/evolution merge pair <a> <b>"
|
|
839
|
+
},
|
|
840
|
+
notes: [],
|
|
841
|
+
degraded: false
|
|
578
842
|
};
|
|
579
843
|
}
|
|
580
844
|
function apply(ctx) {
|
|
@@ -8,7 +8,7 @@ export interface MergeFace {
|
|
|
8
8
|
view: MergeViewPayload;
|
|
9
9
|
rows: MergeRowView[];
|
|
10
10
|
loadView?: () => Promise<MergeOutcome<MergeViewPayload>>;
|
|
11
|
-
loadRows?: (queue: MergeQueue, cursor?:
|
|
11
|
+
loadRows?: (queue: MergeQueue, cursor?: string, expiredOnly?: boolean) => Promise<MergeOutcome<QueuePage>>;
|
|
12
12
|
loadBody?: (id: string, side: 'a' | 'b') => Promise<MergeOutcome<MergeBody>>;
|
|
13
13
|
loadHistory?: () => Promise<MergeOutcome<{
|
|
14
14
|
items: MergeHistoryItem[];
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { RouteFailure } from './route-client.generated.ts';
|
|
2
2
|
export declare const HOST_ROUTES: {
|
|
3
3
|
readonly view: "/api/dsh-evolution/merge/view";
|
|
4
4
|
readonly rows: "/api/dsh-evolution/merge/rows";
|
|
5
|
+
readonly run: "/api/dsh-evolution/merge/run";
|
|
6
|
+
readonly runs: "/api/dsh-evolution/merge/runs";
|
|
5
7
|
readonly body: "/api/dsh-evolution/merge/body";
|
|
6
8
|
readonly history: "/api/dsh-evolution/merge/history";
|
|
7
9
|
};
|
|
@@ -24,16 +26,29 @@ export interface MergeRunView {
|
|
|
24
26
|
startedAt: number;
|
|
25
27
|
}
|
|
26
28
|
export interface MergeViewPayload {
|
|
27
|
-
schemaVersion?: number;
|
|
28
29
|
counts: MergeCounts;
|
|
30
|
+
expired: number;
|
|
29
31
|
tabs: {
|
|
30
32
|
queue: MergeQueue;
|
|
31
33
|
count: number;
|
|
32
34
|
}[];
|
|
33
35
|
commands: string[];
|
|
36
|
+
startCommands: {
|
|
37
|
+
scan: string;
|
|
38
|
+
pair: string;
|
|
39
|
+
};
|
|
40
|
+
notes: string[];
|
|
41
|
+
degraded: boolean;
|
|
34
42
|
latestRun?: MergeRunView;
|
|
35
43
|
approval?: boolean;
|
|
36
44
|
}
|
|
45
|
+
export interface RowActionView {
|
|
46
|
+
id: string;
|
|
47
|
+
command: string;
|
|
48
|
+
confirm: boolean;
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
disabledReason?: string;
|
|
51
|
+
}
|
|
37
52
|
export interface MergeRowView {
|
|
38
53
|
id: string;
|
|
39
54
|
pairKey: string;
|
|
@@ -59,10 +74,19 @@ export interface MergeRowView {
|
|
|
59
74
|
attempts?: number;
|
|
60
75
|
origin?: 'agent' | 'human';
|
|
61
76
|
stagingExpiresAt?: number;
|
|
62
|
-
expired?: 'target-taken' | 'source-changed';
|
|
77
|
+
expired?: 'target-taken' | 'source-changed' | 'skipped-ttl';
|
|
63
78
|
reason?: string;
|
|
64
79
|
summary?: string[];
|
|
65
|
-
actions
|
|
80
|
+
actions: RowActionView[];
|
|
81
|
+
targetActual?: string;
|
|
82
|
+
targetCreated?: boolean;
|
|
83
|
+
stagingState?: 'none' | 'kept' | 'cleared-source-ok' | 'cleared-source-gone';
|
|
84
|
+
verifySubState?: 'queued' | 'running' | 'failed' | 'cancelled';
|
|
85
|
+
skipKind?: 'agent-keep' | 'human-reject' | 'over-limit' | 'forced';
|
|
86
|
+
bodies?: {
|
|
87
|
+
name: string;
|
|
88
|
+
side: 'live' | 'archive';
|
|
89
|
+
}[];
|
|
66
90
|
}
|
|
67
91
|
export interface QueuePage {
|
|
68
92
|
queue: MergeQueue;
|
|
@@ -90,7 +114,7 @@ export type MergeOutcome<T> = {
|
|
|
90
114
|
failure: RouteFailure;
|
|
91
115
|
};
|
|
92
116
|
export declare function view(): Promise<MergeOutcome<MergeViewPayload>>;
|
|
93
|
-
export declare function rows(queue: MergeQueue, cursor?:
|
|
117
|
+
export declare function rows(queue: MergeQueue, cursor?: string, expiredOnly?: boolean): Promise<MergeOutcome<QueuePage>>;
|
|
94
118
|
export declare function body(id: string, side: 'a' | 'b'): Promise<MergeOutcome<MergeBody>>;
|
|
95
119
|
export declare function history(): Promise<MergeOutcome<{
|
|
96
120
|
items: MergeHistoryItem[];
|
|
@@ -27,6 +27,8 @@ export declare const ROUTES: {
|
|
|
27
27
|
readonly merge: {
|
|
28
28
|
readonly view: "/api/dsh-evolution/merge/view";
|
|
29
29
|
readonly rows: "/api/dsh-evolution/merge/rows";
|
|
30
|
+
readonly run: "/api/dsh-evolution/merge/run";
|
|
31
|
+
readonly runs: "/api/dsh-evolution/merge/runs";
|
|
30
32
|
readonly body: "/api/dsh-evolution/merge/body";
|
|
31
33
|
readonly history: "/api/dsh-evolution/merge/history";
|
|
32
34
|
};
|