@lmzhen/dsh-evolution-merge-ui 0.30.18 → 0.30.19
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 +1395 -373
- package/lib/types/client/MergeStore.d.ts +74 -0
- package/lib/types/client/Panel.d.ts +10 -14
- package/lib/types/client/api.d.ts +80 -20
- package/lib/types/client/fallbacks.d.ts +3 -0
- package/lib/types/client/index.d.ts +1 -4
- package/lib/types/client/seam.d.ts +20 -0
- package/lib/types/client/sorting.d.ts +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** Keyed read store for the merge panel. It never writes and keeps DOM state out. */
|
|
2
|
+
import type { MergeBody, MergeFailure, MergeHistoryItem, MergeOutcome, MergeQueue, MergeRowView, MergeViewPayload, QueuePage } from './api.ts';
|
|
3
|
+
export interface MergeSource {
|
|
4
|
+
view(): Promise<MergeOutcome<MergeViewPayload>>;
|
|
5
|
+
rows(queue: MergeQueue, cursor?: string, expiredOnly?: boolean): Promise<MergeOutcome<QueuePage>>;
|
|
6
|
+
body(name: string, side: 'live' | 'archive'): Promise<MergeOutcome<MergeBody>>;
|
|
7
|
+
history(): Promise<MergeOutcome<{
|
|
8
|
+
items: MergeHistoryItem[];
|
|
9
|
+
}>>;
|
|
10
|
+
}
|
|
11
|
+
export type QueueStatus = 'idle' | 'loading' | 'ready' | 'empty' | 'error';
|
|
12
|
+
export interface QueueState {
|
|
13
|
+
status: QueueStatus;
|
|
14
|
+
rows: MergeRowView[];
|
|
15
|
+
nextCursor?: string | undefined;
|
|
16
|
+
failure?: MergeFailure | undefined;
|
|
17
|
+
}
|
|
18
|
+
export type OverlayState = {
|
|
19
|
+
kind: 'body';
|
|
20
|
+
name: string;
|
|
21
|
+
side: 'live' | 'archive';
|
|
22
|
+
status: 'loading' | 'ready' | 'error';
|
|
23
|
+
body?: MergeBody;
|
|
24
|
+
failure?: MergeFailure;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'history';
|
|
27
|
+
status: 'loading' | 'ready' | 'error';
|
|
28
|
+
items?: MergeHistoryItem[];
|
|
29
|
+
failure?: MergeFailure;
|
|
30
|
+
};
|
|
31
|
+
export interface StoreSnapshot {
|
|
32
|
+
view: MergeViewPayload;
|
|
33
|
+
viewState: 'loading' | 'ready' | 'error' | 'blocked';
|
|
34
|
+
viewFailure?: MergeFailure | undefined;
|
|
35
|
+
queue: MergeQueue;
|
|
36
|
+
expiredOnly: boolean;
|
|
37
|
+
current: QueueState;
|
|
38
|
+
overlay?: OverlayState | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface MergeStoreInitial {
|
|
41
|
+
view?: MergeViewPayload;
|
|
42
|
+
rows?: MergeRowView[];
|
|
43
|
+
queue?: MergeQueue;
|
|
44
|
+
expiredOnly?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare class MergeStore {
|
|
47
|
+
private readonly source;
|
|
48
|
+
private readonly listeners;
|
|
49
|
+
private readonly cache;
|
|
50
|
+
private readonly tokens;
|
|
51
|
+
private viewToken;
|
|
52
|
+
private overlayToken;
|
|
53
|
+
private snapshot;
|
|
54
|
+
private started;
|
|
55
|
+
private disposed;
|
|
56
|
+
constructor(source: MergeSource, initial?: MergeStoreInitial);
|
|
57
|
+
readonly read: () => StoreSnapshot;
|
|
58
|
+
readonly subscribe: (listener: () => void) => (() => void);
|
|
59
|
+
private emit;
|
|
60
|
+
private set;
|
|
61
|
+
private isCurrent;
|
|
62
|
+
start(): void;
|
|
63
|
+
loadView(showLoading?: boolean): Promise<void>;
|
|
64
|
+
loadQueue(queue: MergeQueue, expiredOnly: boolean, cursor?: string): Promise<void>;
|
|
65
|
+
select(queue: MergeQueue): void;
|
|
66
|
+
toggleExpired(): void;
|
|
67
|
+
refresh(): void;
|
|
68
|
+
loadMore(): void;
|
|
69
|
+
openBody(name: string, side: 'live' | 'archive'): Promise<void>;
|
|
70
|
+
openHistory(): Promise<void>;
|
|
71
|
+
closeOverlay(): void;
|
|
72
|
+
dispose(): void;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=MergeStore.d.ts.map
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The merge panel body: three queues, counts, and a read-only row list. Actions are
|
|
3
|
-
* intentionally copied commands, not buttons that write from the browser.
|
|
4
|
-
*/
|
|
1
|
+
/** Batch 4 merge panel: keyed read store, four tabs, local overlays, localized errors. */
|
|
5
2
|
import { type ReactNode } from 'react';
|
|
6
|
-
import type {
|
|
3
|
+
import type { MergeStore } from './MergeStore.ts';
|
|
4
|
+
import type { ConfigFormLike, SettingsFace } from './seam.ts';
|
|
5
|
+
export type Translate = (key: string, values?: Readonly<Record<string, string | number>>) => string;
|
|
7
6
|
export interface MergeFace {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
loadHistory?: () => Promise<MergeOutcome<{
|
|
14
|
-
items: MergeHistoryItem[];
|
|
15
|
-
}>>;
|
|
16
|
-
t: (key: string) => string;
|
|
7
|
+
store: MergeStore;
|
|
8
|
+
t: Translate;
|
|
9
|
+
doctorCommand?: string;
|
|
10
|
+
settings?: SettingsFace;
|
|
11
|
+
workspaceId?: string;
|
|
17
12
|
}
|
|
13
|
+
export declare function saveSetting(form: ConfigFormLike, field: string, value: boolean): Promise<boolean>;
|
|
18
14
|
export declare function MergePanel(face: MergeFace): ReactNode;
|
|
19
15
|
//# sourceMappingURL=Panel.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { RouteFailure } from './route-client.generated.ts';
|
|
2
1
|
export declare const HOST_ROUTES: {
|
|
3
2
|
readonly view: "/api/dsh-evolution/merge/view";
|
|
4
3
|
readonly rows: "/api/dsh-evolution/merge/rows";
|
|
@@ -8,12 +7,28 @@ export declare const HOST_ROUTES: {
|
|
|
8
7
|
readonly history: "/api/dsh-evolution/merge/history";
|
|
9
8
|
};
|
|
10
9
|
export type MergeQueue = 'verify' | 'pending' | 'fuse' | 'skipped';
|
|
10
|
+
export type StageState = 'reserved' | 'present' | 'expired' | 'lost' | 'absent';
|
|
11
11
|
export interface MergeCounts {
|
|
12
12
|
verify: number;
|
|
13
13
|
pending: number;
|
|
14
14
|
fuse: number;
|
|
15
15
|
skipped: number;
|
|
16
16
|
}
|
|
17
|
+
export interface PlatformWrite {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
capability: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface MergeApproval {
|
|
22
|
+
mergeApproval: boolean;
|
|
23
|
+
platformWrite?: PlatformWrite;
|
|
24
|
+
}
|
|
25
|
+
export interface MergeRunAction {
|
|
26
|
+
id: string;
|
|
27
|
+
command: string;
|
|
28
|
+
confirm: boolean;
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
disabledReason?: string;
|
|
31
|
+
}
|
|
17
32
|
export interface MergeRunView {
|
|
18
33
|
id: string;
|
|
19
34
|
state: string;
|
|
@@ -22,8 +37,19 @@ export interface MergeRunView {
|
|
|
22
37
|
progress?: {
|
|
23
38
|
done: number;
|
|
24
39
|
total: number;
|
|
25
|
-
};
|
|
40
|
+
} | null;
|
|
26
41
|
startedAt: number;
|
|
42
|
+
endedAt?: number;
|
|
43
|
+
failure?: {
|
|
44
|
+
stage: string;
|
|
45
|
+
code: string;
|
|
46
|
+
retryable: boolean;
|
|
47
|
+
detail?: string;
|
|
48
|
+
};
|
|
49
|
+
parentRunId?: string;
|
|
50
|
+
currentPairKey?: string;
|
|
51
|
+
resultRef?: string;
|
|
52
|
+
actions: MergeRunAction[];
|
|
27
53
|
}
|
|
28
54
|
export interface MergeViewPayload {
|
|
29
55
|
counts: MergeCounts;
|
|
@@ -40,7 +66,7 @@ export interface MergeViewPayload {
|
|
|
40
66
|
notes: string[];
|
|
41
67
|
degraded: boolean;
|
|
42
68
|
latestRun?: MergeRunView;
|
|
43
|
-
approval
|
|
69
|
+
approval: MergeApproval;
|
|
44
70
|
}
|
|
45
71
|
export interface RowActionView {
|
|
46
72
|
id: string;
|
|
@@ -49,6 +75,15 @@ export interface RowActionView {
|
|
|
49
75
|
enabled: boolean;
|
|
50
76
|
disabledReason?: string;
|
|
51
77
|
}
|
|
78
|
+
export interface MergeStageView {
|
|
79
|
+
state: StageState;
|
|
80
|
+
expiresAt?: number;
|
|
81
|
+
}
|
|
82
|
+
export interface MergeSummarySlots {
|
|
83
|
+
a: string | null;
|
|
84
|
+
b: string | null;
|
|
85
|
+
rationale: string | null;
|
|
86
|
+
}
|
|
52
87
|
export interface MergeRowView {
|
|
53
88
|
id: string;
|
|
54
89
|
pairKey: string;
|
|
@@ -61,61 +96,86 @@ export interface MergeRowView {
|
|
|
61
96
|
updatedAt: string;
|
|
62
97
|
createdAt?: string;
|
|
63
98
|
target?: string;
|
|
99
|
+
targetActual?: string;
|
|
100
|
+
targetCreated?: boolean;
|
|
64
101
|
confidence?: number;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
102
|
+
summary?: MergeSummarySlots;
|
|
103
|
+
reason?: string;
|
|
104
|
+
reasonCode?: string;
|
|
105
|
+
origin?: 'agent' | 'human' | 'system';
|
|
106
|
+
attempts?: number;
|
|
107
|
+
stagingExpiresAt?: number;
|
|
108
|
+
expired?: 'target-taken' | 'source-changed' | 'source-gone' | 'skipped-ttl';
|
|
109
|
+
stageView?: MergeStageView;
|
|
68
110
|
failure?: {
|
|
69
111
|
stage: string;
|
|
70
112
|
code: string;
|
|
71
113
|
message: string;
|
|
72
114
|
retryable: boolean;
|
|
73
115
|
};
|
|
74
|
-
attempts?: number;
|
|
75
|
-
origin?: 'agent' | 'human';
|
|
76
|
-
stagingExpiresAt?: number;
|
|
77
|
-
expired?: 'target-taken' | 'source-changed' | 'skipped-ttl';
|
|
78
|
-
reason?: string;
|
|
79
|
-
summary?: string[];
|
|
80
|
-
actions: RowActionView[];
|
|
81
|
-
targetActual?: string;
|
|
82
|
-
targetCreated?: boolean;
|
|
83
|
-
stagingState?: 'none' | 'kept' | 'cleared-source-ok' | 'cleared-source-gone';
|
|
84
116
|
verifySubState?: 'queued' | 'running' | 'failed' | 'cancelled';
|
|
85
117
|
skipKind?: 'agent-keep' | 'human-reject' | 'over-limit' | 'forced';
|
|
86
118
|
bodies?: {
|
|
87
119
|
name: string;
|
|
88
120
|
side: 'live' | 'archive';
|
|
89
121
|
}[];
|
|
122
|
+
actions: RowActionView[];
|
|
90
123
|
}
|
|
91
124
|
export interface QueuePage {
|
|
92
125
|
queue: MergeQueue;
|
|
93
126
|
items: MergeRowView[];
|
|
94
127
|
nextCursor?: string;
|
|
128
|
+
counts: MergeCounts;
|
|
129
|
+
expiredOnly: boolean;
|
|
95
130
|
}
|
|
96
131
|
export interface MergeBody {
|
|
97
|
-
|
|
132
|
+
name: string;
|
|
133
|
+
side: 'live' | 'archive';
|
|
134
|
+
text: string;
|
|
98
135
|
markdown: boolean;
|
|
99
|
-
|
|
136
|
+
truncated: boolean;
|
|
137
|
+
totalBytes: number;
|
|
100
138
|
}
|
|
101
139
|
export interface MergeHistoryItem {
|
|
102
140
|
name: string;
|
|
103
141
|
kind: 'merged' | 'deleted' | 'split' | 'other';
|
|
104
142
|
reason: string;
|
|
143
|
+
reasonCode?: string;
|
|
105
144
|
lastVersion: number;
|
|
106
145
|
archivedAt: string;
|
|
107
146
|
sourceRunId?: string;
|
|
108
147
|
}
|
|
148
|
+
export interface MergeStateReadiness {
|
|
149
|
+
readonly ok?: boolean;
|
|
150
|
+
readonly code?: string;
|
|
151
|
+
readonly message?: string;
|
|
152
|
+
readonly steps?: readonly string[];
|
|
153
|
+
}
|
|
154
|
+
export type MergeProblemKind = 'unauthenticated' | 'forbidden' | 'unmounted' | 'capability' | 'wire-version' | 'body-missing' | 'body-ambiguous' | 'bad-query' | 'refused' | 'server';
|
|
155
|
+
export interface MergeProblem {
|
|
156
|
+
readonly kind: 'problem';
|
|
157
|
+
readonly code: MergeProblemKind;
|
|
158
|
+
readonly status: number;
|
|
159
|
+
readonly wireCode?: string;
|
|
160
|
+
readonly message?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface MergeBlocked {
|
|
163
|
+
readonly kind: 'blocked';
|
|
164
|
+
readonly code: string;
|
|
165
|
+
readonly readiness: MergeStateReadiness;
|
|
166
|
+
}
|
|
167
|
+
export type MergeFailure = MergeProblem | MergeBlocked;
|
|
109
168
|
export type MergeOutcome<T> = {
|
|
110
169
|
ok: true;
|
|
111
170
|
payload: T;
|
|
112
171
|
} | {
|
|
113
172
|
ok: false;
|
|
114
|
-
failure:
|
|
173
|
+
failure: MergeFailure;
|
|
115
174
|
};
|
|
175
|
+
export declare const isBlocked: (failure: MergeFailure) => failure is MergeBlocked;
|
|
116
176
|
export declare function view(): Promise<MergeOutcome<MergeViewPayload>>;
|
|
117
177
|
export declare function rows(queue: MergeQueue, cursor?: string, expiredOnly?: boolean): Promise<MergeOutcome<QueuePage>>;
|
|
118
|
-
export declare function body(
|
|
178
|
+
export declare function body(name: string, side: 'live' | 'archive'): Promise<MergeOutcome<MergeBody>>;
|
|
119
179
|
export declare function history(): Promise<MergeOutcome<{
|
|
120
180
|
items: MergeHistoryItem[];
|
|
121
181
|
}>>;
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser half: one sidebar row ("技能合并") and the read-only main body it opens.
|
|
3
|
-
* All facts arrive through the generated routes; the bundle holds no service and writes nothing.
|
|
4
|
-
*/
|
|
1
|
+
/** Browser half: one sidebar row and the read-only Batch 4 panel. */
|
|
5
2
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
6
3
|
export declare const inject: string[];
|
|
7
4
|
export declare function apply(ctx: ClientContext): void;
|
|
@@ -31,4 +31,24 @@ export interface ClientSeam {
|
|
|
31
31
|
slots: SlotsSeat;
|
|
32
32
|
locale: LocaleSeat;
|
|
33
33
|
}
|
|
34
|
+
/** One client settings row's readable/writable face (platform configForms). */
|
|
35
|
+
export interface ConfigFormSnapshotLike {
|
|
36
|
+
status: 'loading' | 'ready' | 'unavailable';
|
|
37
|
+
value: Record<string, unknown> | undefined;
|
|
38
|
+
writable: boolean;
|
|
39
|
+
revision?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface ConfigFormLike {
|
|
42
|
+
getSnapshot(): ConfigFormSnapshotLike;
|
|
43
|
+
subscribe(listener: () => void): () => void;
|
|
44
|
+
set(field: string, value: unknown): Promise<boolean>;
|
|
45
|
+
unset(field: string): Promise<boolean>;
|
|
46
|
+
}
|
|
47
|
+
export interface ConfigFormsSeat {
|
|
48
|
+
get(entryId: string): ConfigFormLike;
|
|
49
|
+
}
|
|
50
|
+
export interface SettingsFace {
|
|
51
|
+
merge?: ConfigFormLike;
|
|
52
|
+
platform?: ConfigFormLike;
|
|
53
|
+
}
|
|
34
54
|
//# sourceMappingURL=seam.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Display-only row ordering for merge tabs; never part of the wire read. */
|
|
2
|
+
import type { MergeQueue } from './api.ts';
|
|
3
|
+
export interface StorageLike {
|
|
4
|
+
getItem(key: string): string | null;
|
|
5
|
+
setItem(key: string, value: string): void;
|
|
6
|
+
}
|
|
7
|
+
export type RowOrderEdge = 'top' | 'bottom';
|
|
8
|
+
/** Workspace scope for one tab. A missing panel workspace is the local scope. */
|
|
9
|
+
export declare function resolveWorkspaceId(workspaceId: string | null | undefined): string;
|
|
10
|
+
/** Stable localStorage key for one workspace and queue. */
|
|
11
|
+
export declare function rowOrderKey(workspaceId: string | null | undefined, queue: MergeQueue): string;
|
|
12
|
+
/** One tab's persisted order; failures degrade to an empty (wire) order. */
|
|
13
|
+
export declare function createRowOrderStore(storage?: StorageLike | undefined): {
|
|
14
|
+
read(workspaceId: string | null | undefined, queue: MergeQueue): readonly string[];
|
|
15
|
+
write(workspaceId: string | null | undefined, queue: MergeQueue, ids: readonly string[]): void;
|
|
16
|
+
};
|
|
17
|
+
/** Apply persisted ids first, then append unknown rows in their wire order. */
|
|
18
|
+
export declare function orderRows<T extends {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
}>(rows: readonly T[], order: readonly string[]): readonly T[];
|
|
21
|
+
/** Move one visible row before another; unknown ids leave the order unchanged. */
|
|
22
|
+
export declare function moveRow(order: readonly string[], fromId: string, beforeId: string | undefined): readonly string[];
|
|
23
|
+
/** Pin one visible row to the top or bottom of the full visible order. */
|
|
24
|
+
export declare function pinRow(order: readonly string[], id: string, edge: RowOrderEdge): readonly string[];
|
|
25
|
+
//# sourceMappingURL=sorting.d.ts.map
|