@lmzhen/dsh-evolution-merge-ui 0.29.0 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -31,8 +31,8 @@ window.__ModuleLoader__.load({
31
31
  merge: {
32
32
  view: "/api/dsh-evolution/merge/view",
33
33
  rows: "/api/dsh-evolution/merge/rows",
34
- run: "/api/dsh-evolution/merge/run",
35
- runs: "/api/dsh-evolution/merge/runs"
34
+ body: "/api/dsh-evolution/merge/body",
35
+ history: "/api/dsh-evolution/merge/history"
36
36
  },
37
37
  diagnostics: { view: "/api/dsh-evolution/diagnostics" }
38
38
  };
@@ -149,6 +149,27 @@ window.__ModuleLoader__.load({
149
149
  failure: answer.failure
150
150
  };
151
151
  }
152
+ async function body(id, side) {
153
+ const url = HOST_ROUTES.body + "?id=" + encodeURIComponent(id) + "&side=" + side;
154
+ const answer = await requestJson(fetch, url, { headers: { accept: "application/json" } });
155
+ return answer.ok ? {
156
+ ok: true,
157
+ payload: answer.data
158
+ } : {
159
+ ok: false,
160
+ failure: answer.failure
161
+ };
162
+ }
163
+ async function history() {
164
+ const answer = await requestJson(fetch, HOST_ROUTES.history, { headers: { accept: "application/json" } });
165
+ return answer.ok ? {
166
+ ok: true,
167
+ payload: answer.data
168
+ } : {
169
+ ok: false,
170
+ failure: answer.failure
171
+ };
172
+ }
152
173
  //#endregion
153
174
  //#region src/client/seam.ts
154
175
  const PANEL_ID = "merge";
@@ -158,11 +179,15 @@ window.__ModuleLoader__.load({
158
179
  const zh = {
159
180
  "entry.label": "技能合并",
160
181
  "hint": "手动触发;后台逐对判定。这里只读,不写技能。",
182
+ "history": "历史",
183
+ "close": "关闭",
184
+ "tab.verify": "待判断",
161
185
  "tab.pending": "待批准",
162
- "tab.retry": "待重跑",
186
+ "tab.fuse": "待合并",
163
187
  "tab.skipped": "无需合并",
188
+ "empty.verify": "没有待判断的对。",
164
189
  "empty.pending": "没有待批准的合并。",
165
- "empty.retry": "没有待重跑的对。",
190
+ "empty.fuse": "没有待合并的对。",
166
191
  "empty.skipped": "没有标记为无需合并的对。",
167
192
  "loading": "正在读取…",
168
193
  "refresh": "刷新",
@@ -179,6 +204,8 @@ window.__ModuleLoader__.load({
179
204
  "row.attempts": "尝试",
180
205
  "row.origin": "来源",
181
206
  "row.expires": "暂存到期",
207
+ "row.expired": "已过期",
208
+ "row.reason": "原因",
182
209
  "row.failure": "失败",
183
210
  "row.noRetry": "不可重试",
184
211
  "row.copy": "复制命令",
@@ -186,17 +213,22 @@ window.__ModuleLoader__.load({
186
213
  "origin.human": "人工",
187
214
  "state.verify": "待判定",
188
215
  "state.pending": "待批准",
189
- "state.fuse": "待融合",
216
+ "state.approved": "已批准",
217
+ "state.fuse": "待合并",
190
218
  "state.skipped": "已跳过"
191
219
  };
192
220
  const en = {
193
221
  "entry.label": "Skill merge",
194
222
  "hint": "Manual only; pairs are judged in the background. Read-only here.",
195
- "tab.pending": "Pending",
196
- "tab.retry": "Retry",
223
+ "history": "History",
224
+ "close": "Close",
225
+ "tab.verify": "To judge",
226
+ "tab.pending": "Pending approval",
227
+ "tab.fuse": "Ready to merge",
197
228
  "tab.skipped": "Skipped",
229
+ "empty.verify": "No pairs to judge.",
198
230
  "empty.pending": "No pending merges.",
199
- "empty.retry": "No pairs waiting to retry.",
231
+ "empty.fuse": "No pairs ready to merge.",
200
232
  "empty.skipped": "No pairs marked as not worth merging.",
201
233
  "loading": "Loading…",
202
234
  "refresh": "Refresh",
@@ -213,6 +245,8 @@ window.__ModuleLoader__.load({
213
245
  "row.attempts": "Attempts",
214
246
  "row.origin": "Origin",
215
247
  "row.expires": "Staging expires",
248
+ "row.expired": "Expired",
249
+ "row.reason": "Reason",
216
250
  "row.failure": "Failure",
217
251
  "row.noRetry": "not retryable",
218
252
  "row.copy": "Copy command",
@@ -220,7 +254,8 @@ window.__ModuleLoader__.load({
220
254
  "origin.human": "human",
221
255
  "state.verify": "Unverified",
222
256
  "state.pending": "Pending approval",
223
- "state.fuse": "Ready to fuse",
257
+ "state.approved": "Approved",
258
+ "state.fuse": "Ready to merge",
224
259
  "state.skipped": "Skipped"
225
260
  };
226
261
  //#endregion
@@ -297,8 +332,9 @@ window.__ModuleLoader__.load({
297
332
  * intentionally copied commands, not buttons that write from the browser.
298
333
  */
299
334
  const QUEUES = [
335
+ "verify",
300
336
  "pending",
301
- "retry",
337
+ "fuse",
302
338
  "skipped"
303
339
  ];
304
340
  function failure(t, failure) {
@@ -316,6 +352,7 @@ window.__ModuleLoader__.load({
316
352
  const [loading, setLoading] = (0, react.useState)(face.loadRows !== void 0 || face.loadView !== void 0);
317
353
  const [failed, setFailed] = (0, react.useState)(void 0);
318
354
  const [nextCursor, setNextCursor] = (0, react.useState)(void 0);
355
+ const [overlay, setOverlay] = (0, react.useState)(void 0);
319
356
  const request = (0, react.useRef)(0);
320
357
  const loadRows = (queue, cursor = 0) => {
321
358
  const load = face.loadRows;
@@ -347,7 +384,7 @@ window.__ModuleLoader__.load({
347
384
  setFailed(outcome.failure);
348
385
  return;
349
386
  }
350
- if (outcome.payload.schemaVersion !== void 0 && outcome.payload.schemaVersion !== 1) {
387
+ if (outcome.payload.schemaVersion !== void 0 && outcome.payload.schemaVersion !== 2) {
351
388
  setFailed({
352
389
  kind: "server",
353
390
  status: 0
@@ -362,6 +399,39 @@ window.__ModuleLoader__.load({
362
399
  });
363
400
  });
364
401
  };
402
+ const openBody = (id, side) => {
403
+ const load = face.loadBody;
404
+ if (load === void 0) return;
405
+ load(id, side).then((outcome) => {
406
+ if (outcome.ok) setOverlay({
407
+ kind: "body",
408
+ html: outcome.payload.html,
409
+ label: id + ":" + side
410
+ });
411
+ else setFailed(outcome.failure);
412
+ }).catch(() => {
413
+ setFailed({
414
+ kind: "server",
415
+ status: 0
416
+ });
417
+ });
418
+ };
419
+ const openHistory = () => {
420
+ const load = face.loadHistory;
421
+ if (load === void 0) return;
422
+ load().then((outcome) => {
423
+ if (outcome.ok) setOverlay({
424
+ kind: "history",
425
+ items: outcome.payload.items
426
+ });
427
+ else setFailed(outcome.failure);
428
+ }).catch(() => {
429
+ setFailed({
430
+ kind: "server",
431
+ status: 0
432
+ });
433
+ });
434
+ };
365
435
  (0, react.useEffect)(() => {
366
436
  loadView();
367
437
  loadRows("pending");
@@ -399,12 +469,27 @@ window.__ModuleLoader__.load({
399
469
  row.attempts === void 0 ? void 0 : t("row.attempts") + " " + String(row.attempts),
400
470
  row.origin === void 0 ? void 0 : t("row.origin") + " " + t("origin." + row.origin),
401
471
  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,
473
+ row.reason === void 0 ? void 0 : t("row.reason") + " " + row.reason,
474
+ row.summary === void 0 ? void 0 : row.summary.filter(Boolean).join(" · "),
402
475
  row.failure === void 0 ? void 0 : t("row.failure") + " " + row.failure.message + (row.failure.retryable ? "" : " · " + t("row.noRetry"))
403
476
  ].filter((value) => value !== void 0).join(" · ");
404
477
  return (0, react.createElement)("div", {
405
478
  key: row.id,
406
479
  "data-role": "row"
407
- }, (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" }, row.updatedAt), (0, react.createElement)("div", { "data-role": "row-actions" }, (row.actions ?? []).filter((action) => view.approval !== false || !action.includes("/evolution merge approve")).map((action) => (0, react.createElement)("button", {
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))), facts === "" ? null : (0, react.createElement)("div", { "data-role": "row-facts" }, facts)), (0, react.createElement)("div", null, (0, react.createElement)("div", { "data-role": "row-meta" }, row.updatedAt), (0, react.createElement)("div", { "data-role": "row-actions" }, face.loadBody === void 0 ? null : (0, react.createElement)("button", {
481
+ type: "button",
482
+ "data-role": "body-a",
483
+ onClick: () => {
484
+ openBody(row.id, "a");
485
+ }
486
+ }, "A"), face.loadBody === void 0 ? null : (0, react.createElement)("button", {
487
+ type: "button",
488
+ "data-role": "body-b",
489
+ onClick: () => {
490
+ openBody(row.id, "b");
491
+ }
492
+ }, "B"), (row.actions ?? []).filter((action) => view.approval !== false || !action.includes("/evolution merge approve")).map((action) => (0, react.createElement)("button", {
408
493
  key: action,
409
494
  type: "button",
410
495
  "data-role": "row-action",
@@ -423,7 +508,21 @@ window.__ModuleLoader__.load({
423
508
  onClick: () => {
424
509
  loadRows(tab, Number(nextCursor));
425
510
  }
426
- }, t("loadMore")), (0, react.createElement)("button", {
511
+ }, t("loadMore")), face.loadHistory === void 0 ? null : (0, react.createElement)("button", {
512
+ type: "button",
513
+ "data-role": "history",
514
+ onClick: openHistory
515
+ }, t("history")), overlay === void 0 ? null : (0, react.createElement)("section", { "data-role": "overlay" }, (0, react.createElement)("button", {
516
+ type: "button",
517
+ "data-role": "overlay-close",
518
+ onClick: () => {
519
+ setOverlay(void 0);
520
+ }
521
+ }, t("close")), overlay.kind === "body" ? (0, react.createElement)("div", {
522
+ "data-role": "body",
523
+ "data-label": overlay.label,
524
+ 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", {
427
526
  type: "button",
428
527
  "data-role": "refresh",
429
528
  onClick: () => {
@@ -452,17 +551,22 @@ window.__ModuleLoader__.load({
452
551
  function seedView() {
453
552
  return {
454
553
  counts: {
554
+ verify: 0,
455
555
  pending: 0,
456
- retry: 0,
556
+ fuse: 0,
457
557
  skipped: 0
458
558
  },
459
559
  tabs: [
560
+ {
561
+ queue: "verify",
562
+ count: 0
563
+ },
460
564
  {
461
565
  queue: "pending",
462
566
  count: 0
463
567
  },
464
568
  {
465
- queue: "retry",
569
+ queue: "fuse",
466
570
  count: 0
467
571
  },
468
572
  {
@@ -524,6 +628,8 @@ window.__ModuleLoader__.load({
524
628
  rows: [],
525
629
  loadView: view,
526
630
  loadRows: rows,
631
+ loadBody: body,
632
+ loadHistory: history,
527
633
  t
528
634
  })
529
635
  }, MergePanel);
@@ -3,12 +3,16 @@
3
3
  * intentionally copied commands, not buttons that write from the browser.
4
4
  */
5
5
  import { type ReactNode } from 'react';
6
- import type { MergeOutcome, MergeQueue, MergeRowView, MergeViewPayload, QueuePage } from './api.ts';
6
+ import type { MergeBody, MergeHistoryItem, MergeOutcome, MergeQueue, MergeRowView, MergeViewPayload, QueuePage } from './api.ts';
7
7
  export interface MergeFace {
8
8
  view: MergeViewPayload;
9
9
  rows: MergeRowView[];
10
10
  loadView?: () => Promise<MergeOutcome<MergeViewPayload>>;
11
11
  loadRows?: (queue: MergeQueue, cursor?: number) => Promise<MergeOutcome<QueuePage>>;
12
+ loadBody?: (id: string, side: 'a' | 'b') => Promise<MergeOutcome<MergeBody>>;
13
+ loadHistory?: () => Promise<MergeOutcome<{
14
+ items: MergeHistoryItem[];
15
+ }>>;
12
16
  t: (key: string) => string;
13
17
  }
14
18
  export declare function MergePanel(face: MergeFace): ReactNode;
@@ -2,13 +2,14 @@ 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
+ readonly body: "/api/dsh-evolution/merge/body";
6
+ readonly history: "/api/dsh-evolution/merge/history";
7
7
  };
8
- export type MergeQueue = 'pending' | 'retry' | 'skipped';
8
+ export type MergeQueue = 'verify' | 'pending' | 'fuse' | 'skipped';
9
9
  export interface MergeCounts {
10
+ verify: number;
10
11
  pending: number;
11
- retry: number;
12
+ fuse: number;
12
13
  skipped: number;
13
14
  }
14
15
  export interface MergeRunView {
@@ -55,6 +56,9 @@ export interface MergeRowView {
55
56
  attempts?: number;
56
57
  origin?: 'agent' | 'human';
57
58
  stagingExpiresAt?: number;
59
+ expired?: 'target-taken' | 'source-changed';
60
+ reason?: string;
61
+ summary?: string[];
58
62
  actions?: string[];
59
63
  }
60
64
  export interface QueuePage {
@@ -62,6 +66,19 @@ export interface QueuePage {
62
66
  items: MergeRowView[];
63
67
  nextCursor?: string;
64
68
  }
69
+ export interface MergeBody {
70
+ content: string;
71
+ markdown: boolean;
72
+ html: string;
73
+ }
74
+ export interface MergeHistoryItem {
75
+ name: string;
76
+ kind: 'merged' | 'deleted' | 'split' | 'other';
77
+ reason: string;
78
+ lastVersion: number;
79
+ archivedAt: string;
80
+ sourceRunId?: string;
81
+ }
65
82
  export type MergeOutcome<T> = {
66
83
  ok: true;
67
84
  payload: T;
@@ -71,4 +88,8 @@ export type MergeOutcome<T> = {
71
88
  };
72
89
  export declare function view(): Promise<MergeOutcome<MergeViewPayload>>;
73
90
  export declare function rows(queue: MergeQueue, cursor?: number): Promise<MergeOutcome<QueuePage>>;
91
+ export declare function body(id: string, side: 'a' | 'b'): Promise<MergeOutcome<MergeBody>>;
92
+ export declare function history(): Promise<MergeOutcome<{
93
+ items: MergeHistoryItem[];
94
+ }>>;
74
95
  //# sourceMappingURL=api.d.ts.map
@@ -27,8 +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
+ readonly body: "/api/dsh-evolution/merge/body";
31
+ readonly history: "/api/dsh-evolution/merge/history";
32
32
  };
33
33
  readonly diagnostics: {
34
34
  readonly view: "/api/dsh-evolution/diagnostics";
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  ]
12
12
  }
13
13
  },
14
- "version": "0.29.0",
14
+ "version": "0.30.1",
15
15
  "publishConfig": {
16
16
  "access": "public"
17
17
  },