@inventec/dsh-copilot-auth 1.2.17 → 1.2.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/README.md +25 -21
- package/lib/client.js +305 -214
- package/package.json +2 -2
- package/src/auth-flow.mjs +11 -15
- package/src/auth-host.mjs +24 -41
- package/src/host.mjs +0 -18
- package/src/model-update.mjs +107 -82
- package/src/refresh-flow.mjs +115 -33
- package/src/refresh-service.mjs +28 -13
- package/src/shared.mjs +1 -2
package/lib/client.js
CHANGED
|
@@ -34,13 +34,12 @@ var import_react = require("react");
|
|
|
34
34
|
|
|
35
35
|
// src/shared.mjs
|
|
36
36
|
var ROUTE_PREFIX = "/copilot-auth";
|
|
37
|
-
var PROTOCOL_VERSION =
|
|
37
|
+
var PROTOCOL_VERSION = 3;
|
|
38
38
|
var routes = () => ({
|
|
39
39
|
start: `${ROUTE_PREFIX}/start`,
|
|
40
40
|
state: `${ROUTE_PREFIX}/state`,
|
|
41
41
|
status: `${ROUTE_PREFIX}/status`,
|
|
42
42
|
logout: `${ROUTE_PREFIX}/logout`,
|
|
43
|
-
cancel: `${ROUTE_PREFIX}/cancel`,
|
|
44
43
|
refreshPreview: `${ROUTE_PREFIX}/refresh/preview`,
|
|
45
44
|
refreshApply: `${ROUTE_PREFIX}/refresh/apply`,
|
|
46
45
|
refreshRetire: `${ROUTE_PREFIX}/refresh/retire`
|
|
@@ -134,6 +133,41 @@ function refreshBlocked(flags) {
|
|
|
134
133
|
const mode = flags?.catalogMode;
|
|
135
134
|
return flags?.scopeAvailable === false || mode === "blocked" || mode === "unknown";
|
|
136
135
|
}
|
|
136
|
+
function selectionFields(lastSelection = {}) {
|
|
137
|
+
const out = {};
|
|
138
|
+
if (lastSelection.selectedIds !== void 0) out.selectedIds = lastSelection.selectedIds;
|
|
139
|
+
if (lastSelection.clearOverrides !== void 0) out.clearOverrides = lastSelection.clearOverrides;
|
|
140
|
+
if (lastSelection.confirmEmpty !== void 0) out.confirmEmpty = lastSelection.confirmEmpty;
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
function upgradeCandidate(state) {
|
|
144
|
+
const p = state.preview;
|
|
145
|
+
if (!p || state.liveUpgradeUsed) return null;
|
|
146
|
+
if ((p.diff?.removed?.length ?? 0) === 0) return null;
|
|
147
|
+
if (p.evidence?.source !== "cache" || p.evidence?.stale === true) return null;
|
|
148
|
+
if (p.catalogSource !== "latest") return null;
|
|
149
|
+
return {
|
|
150
|
+
type: "preview",
|
|
151
|
+
operation: p.operation,
|
|
152
|
+
catalogSource: p.catalogSource,
|
|
153
|
+
...selectionFields(state.lastSelection)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function enterConfirming({ flags, preview, staleNotice, lastSelection }) {
|
|
157
|
+
const state = {
|
|
158
|
+
name: "confirming",
|
|
159
|
+
flags: flags ?? initial.flags,
|
|
160
|
+
preview,
|
|
161
|
+
staleNotice: staleNotice === true,
|
|
162
|
+
materializing: false,
|
|
163
|
+
awaitingUpgrade: false,
|
|
164
|
+
liveUpgradeUsed: false,
|
|
165
|
+
lastSelection: lastSelection ?? {}
|
|
166
|
+
};
|
|
167
|
+
const effect = upgradeCandidate(state);
|
|
168
|
+
if (!effect) return [state, null];
|
|
169
|
+
return [{ ...state, liveUpgradeUsed: true, awaitingUpgrade: true, materializing: true }, effect];
|
|
170
|
+
}
|
|
137
171
|
function reduce(state, event) {
|
|
138
172
|
switch (state.name) {
|
|
139
173
|
case "idle":
|
|
@@ -146,14 +180,10 @@ function reduce(state, event) {
|
|
|
146
180
|
return [{
|
|
147
181
|
name: "previewing",
|
|
148
182
|
flags: state.flags ?? initial.flags,
|
|
149
|
-
operation:
|
|
183
|
+
operation: "manage",
|
|
150
184
|
catalogSource: event.catalogSource,
|
|
151
185
|
stale: false
|
|
152
|
-
}, {
|
|
153
|
-
type: "preview",
|
|
154
|
-
operation: event.operation === "rebuild" ? "rebuild" : "supplement",
|
|
155
|
-
catalogSource: event.catalogSource
|
|
156
|
-
}];
|
|
186
|
+
}, { type: "preview", operation: "manage", catalogSource: event.catalogSource }];
|
|
157
187
|
}
|
|
158
188
|
if (event.type === "init" && state.name === "idle") return [state, { type: "status" }];
|
|
159
189
|
if (event.type === "check" && state.name === "resultUnknown") {
|
|
@@ -184,7 +214,7 @@ function reduce(state, event) {
|
|
|
184
214
|
}
|
|
185
215
|
case "previewing": {
|
|
186
216
|
if (event.type === "preview-ok") {
|
|
187
|
-
return
|
|
217
|
+
return enterConfirming({ flags: state.flags ?? initial.flags, preview: event.preview, staleNotice: state.stale === true });
|
|
188
218
|
}
|
|
189
219
|
if (event.type === "preview-fail") return [{ name: "failed", flags: state.flags ?? initial.flags, error: event.error }, null];
|
|
190
220
|
return [state, null];
|
|
@@ -192,25 +222,63 @@ function reduce(state, event) {
|
|
|
192
222
|
case "confirming": {
|
|
193
223
|
const p = state.preview;
|
|
194
224
|
if (event.type === "select") {
|
|
225
|
+
const lastSelection = { ...selectionFields({
|
|
226
|
+
selectedIds: event.selectedIds,
|
|
227
|
+
clearOverrides: event.clearOverrides,
|
|
228
|
+
confirmEmpty: event.confirmEmpty
|
|
229
|
+
}) };
|
|
195
230
|
return [{
|
|
196
231
|
name: "confirming",
|
|
197
232
|
flags: state.flags ?? initial.flags,
|
|
198
233
|
preview: p,
|
|
199
234
|
materializing: true,
|
|
235
|
+
awaitingUpgrade: false,
|
|
236
|
+
liveUpgradeUsed: state.liveUpgradeUsed ?? false,
|
|
237
|
+
lastSelection,
|
|
200
238
|
staleNotice: state.staleNotice
|
|
201
239
|
}, {
|
|
202
240
|
type: "preview",
|
|
203
241
|
operation: p.operation,
|
|
204
242
|
catalogSource: p.catalogSource,
|
|
205
243
|
basePreviewId: p.previewId,
|
|
206
|
-
|
|
207
|
-
confirmEmpty: event.confirmEmpty === true
|
|
244
|
+
...selectionFields(lastSelection)
|
|
208
245
|
}];
|
|
209
246
|
}
|
|
210
247
|
if (event.type === "preview-ok") {
|
|
211
|
-
|
|
248
|
+
const wasUpgrade = state.awaitingUpgrade === true;
|
|
249
|
+
const landed = {
|
|
250
|
+
name: "confirming",
|
|
251
|
+
flags: state.flags ?? initial.flags,
|
|
252
|
+
preview: event.preview,
|
|
253
|
+
materializing: false,
|
|
254
|
+
awaitingUpgrade: false,
|
|
255
|
+
liveUpgradeUsed: state.liveUpgradeUsed ?? false,
|
|
256
|
+
lastSelection: state.lastSelection ?? {},
|
|
257
|
+
staleNotice: wasUpgrade && event.preview?.evidence?.source !== "live" || state.staleNotice === true
|
|
258
|
+
};
|
|
259
|
+
const effect = upgradeCandidate(landed);
|
|
260
|
+
if (effect) return [{ ...landed, liveUpgradeUsed: true, awaitingUpgrade: true, materializing: true }, effect];
|
|
261
|
+
return [landed, null];
|
|
212
262
|
}
|
|
213
263
|
if (event.type === "preview-fail") {
|
|
264
|
+
if (state.awaitingUpgrade === true && p) {
|
|
265
|
+
return [{
|
|
266
|
+
name: "confirming",
|
|
267
|
+
flags: state.flags ?? initial.flags,
|
|
268
|
+
preview: p,
|
|
269
|
+
materializing: true,
|
|
270
|
+
awaitingUpgrade: false,
|
|
271
|
+
liveUpgradeUsed: state.liveUpgradeUsed ?? true,
|
|
272
|
+
lastSelection: state.lastSelection ?? {},
|
|
273
|
+
staleNotice: true
|
|
274
|
+
}, {
|
|
275
|
+
type: "preview",
|
|
276
|
+
operation: p.operation,
|
|
277
|
+
catalogSource: p.catalogSource,
|
|
278
|
+
basePreviewId: p.previewId,
|
|
279
|
+
...selectionFields(state.lastSelection)
|
|
280
|
+
}];
|
|
281
|
+
}
|
|
214
282
|
return [{ name: "failed", flags: state.flags ?? initial.flags, error: event.error }, null];
|
|
215
283
|
}
|
|
216
284
|
if (event.type === "start") {
|
|
@@ -219,19 +287,14 @@ function reduce(state, event) {
|
|
|
219
287
|
flags: state.flags ?? initial.flags,
|
|
220
288
|
preview: p,
|
|
221
289
|
materializing: true,
|
|
290
|
+
awaitingUpgrade: false,
|
|
291
|
+
liveUpgradeUsed: state.liveUpgradeUsed ?? false,
|
|
292
|
+
lastSelection: state.lastSelection ?? {},
|
|
222
293
|
staleNotice: state.staleNotice
|
|
223
|
-
}, {
|
|
224
|
-
type: "preview",
|
|
225
|
-
operation: event.operation === "rebuild" ? "rebuild" : p.operation,
|
|
226
|
-
catalogSource: event.catalogSource
|
|
227
|
-
}];
|
|
294
|
+
}, { type: "preview", operation: p.operation, catalogSource: event.catalogSource }];
|
|
228
295
|
}
|
|
229
296
|
if (event.type === "confirm") {
|
|
230
297
|
if (state.materializing) return [state, null];
|
|
231
|
-
const isRebuild = p.operation === "rebuild";
|
|
232
|
-
const emptyTarget = isRebuild && (p.diff?.targetView?.models ?? []).length === 0;
|
|
233
|
-
if (isRebuild && event.second !== true) return [state, null];
|
|
234
|
-
if (emptyTarget && event.empty !== true) return [state, null];
|
|
235
298
|
if (p.evidence?.stale === true) return [state, null];
|
|
236
299
|
return [{ name: "applying", flags: state.flags ?? initial.flags, preview: p }, { type: "apply", previewId: p.previewId, operationId: p.operationId }];
|
|
237
300
|
}
|
|
@@ -303,8 +366,10 @@ async function runEffect(effect, fetchImpl) {
|
|
|
303
366
|
const res = await post(r.refreshPreview, {
|
|
304
367
|
operation: effect.operation,
|
|
305
368
|
...effect.catalogSource ? { catalogSource: effect.catalogSource } : {},
|
|
306
|
-
...effect.basePreviewId ? { basePreviewId: effect.basePreviewId
|
|
307
|
-
...effect.
|
|
369
|
+
...effect.basePreviewId !== void 0 ? { basePreviewId: effect.basePreviewId } : {},
|
|
370
|
+
...effect.selectedIds !== void 0 ? { selectedIds: effect.selectedIds } : {},
|
|
371
|
+
...effect.clearOverrides !== void 0 ? { clearOverrides: effect.clearOverrides } : {},
|
|
372
|
+
...effect.confirmEmpty !== void 0 ? { confirmEmpty: effect.confirmEmpty } : {}
|
|
308
373
|
});
|
|
309
374
|
if (res.ok) return { type: "preview-ok", preview: res.body };
|
|
310
375
|
return { type: "preview-fail", error: res.error?.details?.errorCode ?? res.error?.messageKey };
|
|
@@ -406,7 +471,7 @@ function createAuthFlow({ fetchImpl, clock = defaultClock(), onState = () => {
|
|
|
406
471
|
emit({ phase: "failed", error: s?.error ?? "authorization-failed" });
|
|
407
472
|
return;
|
|
408
473
|
}
|
|
409
|
-
if (s?.status === "
|
|
474
|
+
if (s?.status === "timed-out-unverified") {
|
|
410
475
|
emit({ phase: "risk", riskKind: s.status });
|
|
411
476
|
return;
|
|
412
477
|
}
|
|
@@ -486,6 +551,10 @@ function createAuthFlow({ fetchImpl, clock = defaultClock(), onState = () => {
|
|
|
486
551
|
emit({ phase: "idle", error: r.error?.messageKey, connectivity: "manual" });
|
|
487
552
|
return;
|
|
488
553
|
}
|
|
554
|
+
if (r.body?.status === "authorized" && body.configured !== true) {
|
|
555
|
+
emit({ phase: "idle" });
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
489
558
|
applySnapshot(gen, r.body);
|
|
490
559
|
}
|
|
491
560
|
async function start() {
|
|
@@ -521,14 +590,6 @@ function createAuthFlow({ fetchImpl, clock = defaultClock(), onState = () => {
|
|
|
521
590
|
}
|
|
522
591
|
emit({ phase: "failed", error: errorCode ?? r.error?.messageKey });
|
|
523
592
|
}
|
|
524
|
-
async function cancel() {
|
|
525
|
-
const r = await requestJson(fetchImpl, "/copilot-auth/cancel", { method: "POST" });
|
|
526
|
-
if (r.ok) {
|
|
527
|
-
emit({ withdrawalDelivery: r.body?.withdrawalDelivery ?? "unavailable" });
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
emit({ withdrawalDelivery: "failed", error: r.error?.details?.errorCode ?? r.error?.messageKey });
|
|
531
|
-
}
|
|
532
593
|
async function logout() {
|
|
533
594
|
const gen = ++generation;
|
|
534
595
|
clearTimer();
|
|
@@ -553,7 +614,7 @@ function createAuthFlow({ fetchImpl, clock = defaultClock(), onState = () => {
|
|
|
553
614
|
generation += 1;
|
|
554
615
|
clearTimer();
|
|
555
616
|
}
|
|
556
|
-
return { init, start,
|
|
617
|
+
return { init, start, logout, refresh, dispose };
|
|
557
618
|
}
|
|
558
619
|
|
|
559
620
|
// src/client.jsx
|
|
@@ -572,9 +633,6 @@ var DICTS = {
|
|
|
572
633
|
loading: "\u2026",
|
|
573
634
|
login: "Sign in",
|
|
574
635
|
logout: "Sign out",
|
|
575
|
-
withdrawAuth: "Request withdrawal",
|
|
576
|
-
withdrawal: "Withdrawal requested; the outcome remains unverified.",
|
|
577
|
-
withdrawalUnavailable: "The withdrawal request could not be sent to the host; the outcome remains unverified.",
|
|
578
636
|
authUnsafe: "Safe completion of the authorization flow is unconfirmed. Sign-out and a new authorization attempt are unavailable.",
|
|
579
637
|
attemptTimeout: "Authorization wait timed out; the outcome remains unverified. A new authorization attempt is unavailable. Check the status or verify it manually.",
|
|
580
638
|
attemptShared: "An authorization attempt is already running in this instance.",
|
|
@@ -587,6 +645,10 @@ var DICTS = {
|
|
|
587
645
|
copy: "Copy",
|
|
588
646
|
copied: "Copied \u2713",
|
|
589
647
|
unknown: "Unknown error",
|
|
648
|
+
netConnect: "Cannot reach GitHub. Check this machine's network or proxy settings.",
|
|
649
|
+
netDns: "Cannot resolve github.com. Check DNS or network settings.",
|
|
650
|
+
netCert: "GitHub certificate verification failed. A corporate proxy or TLS inspection may be intercepting the connection.",
|
|
651
|
+
netGeneric: "The authorization request failed over the network.",
|
|
590
652
|
statusUnknown: "Status unknown",
|
|
591
653
|
errNetwork: "Network error: cannot reach the authorization service. Retrying automatically.",
|
|
592
654
|
errGateway: "Gateway error: the DSH service may be restarting. Retrying automatically.",
|
|
@@ -594,28 +656,30 @@ var DICTS = {
|
|
|
594
656
|
errHttp: "The authorization request failed. Check status and retry.",
|
|
595
657
|
logoutScope: "This removes Copilot authorization from this credential store and affects other instances using it. It does not delete your GitHub account.",
|
|
596
658
|
logoutFailed: "Sign-out did not complete; authorization credentials may remain. Please retry.",
|
|
597
|
-
// ---- Model management (protocol
|
|
598
|
-
|
|
599
|
-
rebuild: "Rebuild model list",
|
|
600
|
-
supplementTitle: "Add models",
|
|
601
|
-
rebuildTitle: "Rebuild model list",
|
|
602
|
-
candidates: "Models available to add",
|
|
659
|
+
// ---- Model management (protocol v3, design §5 / ADR 0005) ----
|
|
660
|
+
manageModels: "Manage model list",
|
|
603
661
|
selectAll: "Select all",
|
|
604
662
|
selectNone: "Deselect all",
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
663
|
+
alignAction: "Align with account & catalog",
|
|
664
|
+
groupAddable: "Available to add",
|
|
665
|
+
groupListed: "In list",
|
|
666
|
+
groupRemoval: "Proposed for removal",
|
|
667
|
+
retain: "Keep: re-check to retain",
|
|
668
|
+
customizedBadge: "Customized",
|
|
669
|
+
clearOverrides: "Also clear all model customizations.",
|
|
670
|
+
inheritedOverrides: "Inherited model customizations cannot be cleared here.",
|
|
671
|
+
clearRisk: "Clearing hides nothing \u2014 all available models stay listed; to trim, keep only the ones you check.",
|
|
609
672
|
applyChanges: "Apply changes",
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
673
|
+
removalRisk: "{count} listed model(s) will be removed; their customizations are removed with them.",
|
|
674
|
+
summaryLine: "After applying: {total} model(s) \u2014 {kept} kept \xB7 {added} added \xB7 {removed} removed",
|
|
675
|
+
catalogNotice: "{count} catalog entries will be added",
|
|
676
|
+
noChanges: "No changes and no new catalog entries.",
|
|
677
|
+
removalNeedsLive: "Removals require live account evidence",
|
|
678
|
+
removedAccount: "Not reported by this account",
|
|
614
679
|
removedUnresolvable: "Not resolvable by the current catalog",
|
|
615
|
-
warnings: "Warnings",
|
|
616
680
|
skippedModels: "Upstream entries skipped by validation",
|
|
617
681
|
srcLive: "Account models: live",
|
|
618
|
-
srcCache: "Account models: cached at {time};
|
|
682
|
+
srcCache: "Account models: cached at {time}; removals require upgrading to live evidence",
|
|
619
683
|
srcStale: "The cache has no trusted timestamp, is expired, or belongs to changed authorization; reference only.",
|
|
620
684
|
srcLatest: "Catalog source: latest pi-ai from npm",
|
|
621
685
|
srcLocal: "Catalog source: local (npm fetch failed)",
|
|
@@ -657,9 +721,6 @@ var DICTS = {
|
|
|
657
721
|
loading: "\u2026",
|
|
658
722
|
login: "\u6388\u6743\u767B\u5F55",
|
|
659
723
|
logout: "\u9000\u51FA\u767B\u5F55",
|
|
660
|
-
withdrawAuth: "\u8BF7\u6C42\u64A4\u56DE",
|
|
661
|
-
withdrawal: "\u64A4\u56DE\u8BF7\u6C42\u5DF2\u53D1\u9001\uFF0C\u7ED3\u679C\u4ECD\u5F85\u6838\u5B9E\u3002",
|
|
662
|
-
withdrawalUnavailable: "\u672A\u80FD\u5411\u5BBF\u4E3B\u53D1\u9001\u64A4\u56DE\u8BF7\u6C42\uFF0C\u7ED3\u679C\u4ECD\u5F85\u6838\u5B9E\u3002",
|
|
663
724
|
authUnsafe: "\u5C1A\u4E0D\u80FD\u786E\u8BA4\u6388\u6743\u6D41\u7A0B\u5DF2\u5B89\u5168\u7ED3\u675F\uFF0C\u6682\u4E0D\u80FD\u9000\u51FA\u6216\u53D1\u8D77\u65B0\u7684\u6388\u6743\u5C1D\u8BD5\u3002",
|
|
664
725
|
attemptTimeout: "\u7B49\u5F85\u6388\u6743\u8D85\u65F6\uFF0C\u7ED3\u679C\u4ECD\u5F85\u6838\u5B9E\u3002\u5F53\u524D\u4E0D\u80FD\u53D1\u8D77\u65B0\u7684\u6388\u6743\u5C1D\u8BD5\uFF0C\u8BF7\u67E5\u8BE2\u72B6\u6001\u6216\u4EBA\u5DE5\u6838\u5B9E\u3002",
|
|
665
726
|
attemptShared: "\u6B64\u5B9E\u4F8B\u5DF2\u6709\u6388\u6743\u6B63\u5728\u8FDB\u884C\u3002",
|
|
@@ -671,6 +732,10 @@ var DICTS = {
|
|
|
671
732
|
copy: "\u590D\u5236",
|
|
672
733
|
copied: "\u5DF2\u590D\u5236 \u2713",
|
|
673
734
|
unknown: "\u672A\u77E5\u9519\u8BEF",
|
|
735
|
+
netConnect: "\u65E0\u6CD5\u8FDE\u63A5 GitHub\uFF1A\u8BF7\u68C0\u67E5\u672C\u673A\u7F51\u7EDC\u6216\u4EE3\u7406\u8BBE\u7F6E\u3002",
|
|
736
|
+
netDns: "\u65E0\u6CD5\u89E3\u6790 GitHub \u57DF\u540D\uFF1A\u8BF7\u68C0\u67E5 DNS \u6216\u7F51\u7EDC\u8BBE\u7F6E\u3002",
|
|
737
|
+
netCert: "GitHub \u8BC1\u4E66\u6821\u9A8C\u5931\u8D25\uFF1A\u53EF\u80FD\u5B58\u5728\u4F01\u4E1A\u4EE3\u7406\u6216 TLS \u68C0\u67E5\u62E6\u622A\u3002",
|
|
738
|
+
netGeneric: "\u6388\u6743\u8BF7\u6C42\u7F51\u7EDC\u5931\u8D25\u3002",
|
|
674
739
|
statusUnknown: "\u72B6\u6001\u672A\u77E5",
|
|
675
740
|
errNetwork: "\u7F51\u7EDC\u5F02\u5E38\uFF1A\u65E0\u6CD5\u8FDE\u63A5\u6388\u6743\u670D\u52A1\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
676
741
|
errGateway: "\u7F51\u5173\u9519\u8BEF\uFF1ADSH \u670D\u52A1\u53EF\u80FD\u6B63\u5728\u91CD\u542F\uFF0C\u6B63\u5728\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
@@ -678,28 +743,30 @@ var DICTS = {
|
|
|
678
743
|
errHttp: "\u6388\u6743\u8BF7\u6C42\u5931\u8D25\u3002\u8BF7\u67E5\u8BE2\u72B6\u6001\u540E\u91CD\u8BD5\u3002",
|
|
679
744
|
logoutScope: "\u5C06\u6E05\u9664\u6B64\u51ED\u636E\u5E93\u4E2D\u7684 Copilot \u6388\u6743\uFF0C\u4F7F\u7528\u540C\u4E00\u51ED\u636E\u5E93\u7684\u5176\u4ED6\u5B9E\u4F8B\u4E5F\u4F1A\u53D7\u5230\u5F71\u54CD\u3002\u6B64\u64CD\u4F5C\u4E0D\u6CE8\u9500 GitHub \u8D26\u53F7\u3002",
|
|
680
745
|
logoutFailed: "\u9000\u51FA\u767B\u5F55\u672A\u5B8C\u6210\uFF0C\u6388\u6743\u51ED\u636E\u4ECD\u53EF\u80FD\u5B58\u5728\u3002\u8BF7\u91CD\u8BD5\u3002",
|
|
681
|
-
// ---- 模型管理(协议
|
|
682
|
-
|
|
683
|
-
rebuild: "\u91CD\u5EFA\u6A21\u578B\u5217\u8868",
|
|
684
|
-
supplementTitle: "\u8865\u5145\u6A21\u578B",
|
|
685
|
-
rebuildTitle: "\u91CD\u5EFA\u6A21\u578B\u5217\u8868",
|
|
686
|
-
candidates: "\u53EF\u65B0\u589E\u7684\u6A21\u578B",
|
|
746
|
+
// ---- 模型管理(协议 v3,设计§5 / ADR 0005) ----
|
|
747
|
+
manageModels: "\u7BA1\u7406\u6A21\u578B\u5217\u8868",
|
|
687
748
|
selectAll: "\u5168\u9009",
|
|
688
749
|
selectNone: "\u53D6\u6D88\u5168\u9009",
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
750
|
+
alignAction: "\u5BF9\u9F50\u8D26\u53F7\u4E0E\u76EE\u5F55",
|
|
751
|
+
groupAddable: "\u53EF\u65B0\u589E",
|
|
752
|
+
groupListed: "\u5728\u5217",
|
|
753
|
+
groupRemoval: "\u5F85\u5220\u9664\u5019\u9009",
|
|
754
|
+
retain: "\u633D\u7559\uFF1A\u91CD\u65B0\u52FE\u9009\u4EE5\u4FDD\u7559",
|
|
755
|
+
customizedBadge: "\u6709\u5B9A\u5236",
|
|
756
|
+
clearOverrides: "\u540C\u65F6\u6E05\u9664\u5168\u90E8\u6A21\u578B\u5B9A\u5236\u3002",
|
|
757
|
+
inheritedOverrides: "\u5B58\u5728\u7EE7\u627F\u7684\u6A21\u578B\u5B9A\u5236\uFF0C\u65E0\u6CD5\u5728\u6B64\u6E05\u9664\u3002",
|
|
758
|
+
clearRisk: "\u6E05\u7A7A\u4E0D\u4F1A\u9690\u85CF\u6A21\u578B\u2014\u2014\u4F1A\u8BDD\u5185\u5C06\u663E\u793A\u5168\u90E8\u53EF\u7528\u6A21\u578B\uFF1B\u8981\u7CBE\u7B80\uFF0C\u53EA\u9700\u52FE\u9009\u4FDD\u7559\u9879\u3002",
|
|
693
759
|
applyChanges: "\u5E94\u7528\u66F4\u6539",
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
760
|
+
removalRisk: "\u5C06\u79FB\u9664 {count} \u4E2A\u5728\u5217\u6A21\u578B\uFF0C\u5176\u5B9A\u5236\u968F\u4E4B\u6E05\u9664\u3002",
|
|
761
|
+
summaryLine: "\u5E94\u7528\u540E\u5171 {total} \u4E2A\uFF1A\u4FDD\u7559 {kept} \xB7 \u65B0\u589E {added} \xB7 \u79FB\u9664 {removed}",
|
|
762
|
+
catalogNotice: "\u76EE\u5F55\u5C06\u65B0\u589E {count} \u6761\u63CF\u8FF0",
|
|
763
|
+
noChanges: "\u65E0\u9700\u66F4\u6539\uFF0C\u76EE\u5F55\u4E5F\u65E0\u65B0\u6570\u636E\u3002",
|
|
764
|
+
removalNeedsLive: "\u79FB\u9664\u7C7B\u66F4\u6539\u9700\u8981\u5B9E\u65F6\u8D26\u53F7\u8BC1\u636E",
|
|
765
|
+
removedAccount: "\u8D26\u53F7\u672A\u62A5\u544A",
|
|
766
|
+
removedUnresolvable: "\u76EE\u5F55\u65E0\u6CD5\u89E3\u6790",
|
|
700
767
|
skippedModels: "\u88AB\u6821\u9A8C\u8DF3\u8FC7\u7684\u4E0A\u6E38\u6761\u76EE",
|
|
701
768
|
srcLive: "\u8D26\u53F7\u6A21\u578B\uFF1A\u5B9E\u65F6\u83B7\u53D6",
|
|
702
|
-
srcCache: "\u8D26\u53F7\u6A21\u578B\uFF1A\u7F13\u5B58\uFF0C\u83B7\u53D6\u4E8E {time}\
|
|
769
|
+
srcCache: "\u8D26\u53F7\u6A21\u578B\uFF1A\u7F13\u5B58\uFF0C\u83B7\u53D6\u4E8E {time}\uFF1B\u79FB\u9664\u7C7B\u66F4\u6539\u9700\u5347\u7EA7\u4E3A\u5B9E\u65F6\u8BC1\u636E",
|
|
703
770
|
srcStale: "\u7F13\u5B58\u7F3A\u5C11\u53EF\u4FE1\u65F6\u95F4\u3001\u5DF2\u8FC7\u671F\u6216\u6388\u6743\u5DF2\u53D8\u5316\uFF0C\u4EC5\u4F9B\u53C2\u8003\u3002",
|
|
704
771
|
srcLatest: "\u76EE\u5F55\u6765\u6E90\uFF1Anpm \u6700\u65B0 pi-ai",
|
|
705
772
|
srcLocal: "\u76EE\u5F55\u6765\u6E90\uFF1A\u672C\u5730\u76EE\u5F55\uFF08npm \u62C9\u53D6\u5931\u8D25\uFF09",
|
|
@@ -864,134 +931,134 @@ function sampleThemeSurface() {
|
|
|
864
931
|
}
|
|
865
932
|
function RefreshModal({ t, flow, onSelect, onConfirm, onCancel, onOverlay }) {
|
|
866
933
|
const p = flow.preview;
|
|
867
|
-
const
|
|
868
|
-
const
|
|
869
|
-
const
|
|
870
|
-
const
|
|
934
|
+
const isStale = p.evidence?.stale === true;
|
|
935
|
+
const degradedCatalog = p.catalogSource === "local" || p.catalogSource === "overlay";
|
|
936
|
+
const locked = isStale || degradedCatalog;
|
|
937
|
+
const rows = p.rows ?? [];
|
|
938
|
+
const addableIds = rows.filter((r) => r.status === "addable").map((r) => r.id);
|
|
939
|
+
const rawAllIds = rows.filter((r) => r.status !== "addable").map((r) => r.id);
|
|
940
|
+
const removalRows = rows.filter((r) => r.status === "removal-proposal");
|
|
871
941
|
const [localSel, setLocalSel] = (0, import_react.useState)(null);
|
|
942
|
+
const [coChecked, setCoChecked] = (0, import_react.useState)(false);
|
|
872
943
|
(0, import_react.useEffect)(() => {
|
|
873
944
|
setLocalSel(null);
|
|
945
|
+
setCoChecked(p.clearOverrides === true);
|
|
874
946
|
}, [p.diff]);
|
|
875
|
-
const
|
|
876
|
-
const
|
|
877
|
-
|
|
878
|
-
|
|
947
|
+
const lockedIds = rows.filter((r) => r.status === "removal-proposal" && locked).map((r) => r.id);
|
|
948
|
+
const selected = (() => {
|
|
949
|
+
const s = new Set(localSel ?? (p.diff?.selectedIds ?? []));
|
|
950
|
+
for (const id of lockedIds) s.add(id);
|
|
951
|
+
return s;
|
|
952
|
+
})();
|
|
953
|
+
const confirmEmptyOf = (set) => set.size === 0 && p.hadModels === true;
|
|
954
|
+
const emitSel = (nextSet) => {
|
|
955
|
+
setLocalSel(nextSet);
|
|
956
|
+
const ce = confirmEmptyOf(nextSet);
|
|
957
|
+
onSelect({ selectedIds: [...nextSet], clearOverrides: coChecked, ...ce ? { confirmEmpty: true } : {} });
|
|
958
|
+
};
|
|
959
|
+
const toggle = (id) => {
|
|
960
|
+
const next = new Set(selected);
|
|
961
|
+
if (next.has(id)) next.delete(id);
|
|
962
|
+
else next.add(id);
|
|
963
|
+
emitSel(next);
|
|
964
|
+
};
|
|
965
|
+
const toggleClearOverrides = (v) => {
|
|
966
|
+
setCoChecked(v);
|
|
967
|
+
const ce = confirmEmptyOf(selected);
|
|
968
|
+
onSelect({ selectedIds: [...selected], clearOverrides: v, ...ce ? { confirmEmpty: true } : {} });
|
|
879
969
|
};
|
|
880
|
-
const
|
|
970
|
+
const keptCount = rawAllIds.filter((id) => selected.has(id)).length;
|
|
971
|
+
const addedCount = addableIds.filter((id) => selected.has(id)).length;
|
|
972
|
+
const removedCount = rawAllIds.length - keptCount;
|
|
973
|
+
const total = keptCount + addedCount;
|
|
974
|
+
const emptyTarget = confirmEmptyOf(selected);
|
|
975
|
+
const applyBlocked = isStale || removedCount > 0 && (p.evidence?.source !== "live" || degradedCatalog);
|
|
881
976
|
const cancelRef = (0, import_react.useRef)(null);
|
|
882
977
|
const surface = (0, import_react.useRef)(null);
|
|
883
978
|
if (!surface.current) surface.current = sampleThemeSurface();
|
|
884
|
-
(0, import_react.useEffect)(() => {
|
|
885
|
-
setStage(0);
|
|
886
|
-
}, [p.previewId]);
|
|
887
|
-
(0, import_react.useEffect)(() => {
|
|
888
|
-
if (stage > 0) cancelRef.current?.focus();
|
|
889
|
-
}, [stage]);
|
|
890
979
|
const escCancel = (e) => {
|
|
891
980
|
if (e.key === "Escape") onCancel();
|
|
892
981
|
};
|
|
893
982
|
const confirmClick = () => {
|
|
894
|
-
if (
|
|
895
|
-
|
|
896
|
-
onConfirm({ second: false, empty: false });
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
if (stage === 0) {
|
|
900
|
-
setStage(1);
|
|
901
|
-
return;
|
|
902
|
-
}
|
|
903
|
-
if (emptyTarget && stage === 1) {
|
|
904
|
-
setStage(2);
|
|
905
|
-
return;
|
|
906
|
-
}
|
|
907
|
-
onConfirm({ second: true, empty: emptyTarget });
|
|
983
|
+
if (isStale || applyBlocked) return;
|
|
984
|
+
onConfirm({});
|
|
908
985
|
};
|
|
909
986
|
const sourceLine = [
|
|
910
987
|
p.evidence?.source === "live" ? t("srcLive") : p.evidence?.source === "cache" ? t("srcCache").replace("{time}", String(p.evidence?.fetchedAt ?? "")) : null,
|
|
911
988
|
p.catalogSource === "latest" ? t("srcLatest") : p.catalogSource === "overlay" ? t("srcOverlay") : t("srcLocal")
|
|
912
989
|
].filter(Boolean).join(" \xB7 ");
|
|
913
|
-
const
|
|
990
|
+
const groupDefs = [
|
|
991
|
+
{ key: "groupAddable", items: rows.filter((r) => r.status === "addable") },
|
|
992
|
+
{ key: "groupListed", items: rows.filter((r) => r.status === "listed") },
|
|
993
|
+
{ key: "groupRemoval", items: removalRows, retain: true }
|
|
994
|
+
];
|
|
914
995
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.modalMask, role: "dialog", "aria-modal": "true", onKeyDown: escCancel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...styles.modal, background: surface.current.bg, color: surface.current.fg, height: "min(80vh, 680px)", padding: 0, overflow: "hidden" }, children: [
|
|
915
996
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "18px 20px 6px" }, children: [
|
|
916
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { style: styles.modalTitle, children: t(
|
|
917
|
-
flow.staleNotice && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
997
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { style: styles.modalTitle, children: t("manageModels") }),
|
|
998
|
+
flow.staleNotice && !(!isStale && p.evidence?.source !== "live" && p.catalogSource === "latest") && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
918
999
|
"\u26A0 ",
|
|
919
1000
|
t("previewStale")
|
|
920
1001
|
] }),
|
|
921
1002
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.modalText, children: sourceLine }),
|
|
922
|
-
|
|
1003
|
+
isStale && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
923
1004
|
"\u26A0 ",
|
|
924
1005
|
t("srcStale")
|
|
925
1006
|
] })
|
|
926
1007
|
] }),
|
|
927
1008
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { flex: 1, overflowY: "auto", minHeight: 0, scrollbarGutter: "stable", padding: "0 20px" }, children: [
|
|
928
|
-
|
|
929
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1009
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", padding: "6px 0" }, children: [
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1011
|
+
"button",
|
|
1012
|
+
{
|
|
1013
|
+
type: "button",
|
|
1014
|
+
style: { ...styles.button, ...styles.secondary, height: 24, fontSize: 12 },
|
|
1015
|
+
onClick: () => emitSel(/* @__PURE__ */ new Set([...addableIds, ...rawAllIds])),
|
|
1016
|
+
children: t("selectAll")
|
|
1017
|
+
}
|
|
1018
|
+
),
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1020
|
+
"button",
|
|
1021
|
+
{
|
|
1022
|
+
type: "button",
|
|
1023
|
+
style: { ...styles.button, ...styles.secondary, height: 24, fontSize: 12 },
|
|
1024
|
+
onClick: () => emitSel(new Set(lockedIds)),
|
|
1025
|
+
children: t("selectNone")
|
|
1026
|
+
}
|
|
1027
|
+
),
|
|
1028
|
+
removalRows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1029
|
+
"button",
|
|
1030
|
+
{
|
|
1031
|
+
type: "button",
|
|
1032
|
+
style: { ...styles.button, ...styles.secondary, height: 24, fontSize: 12, ...locked ? { opacity: 0.5, cursor: "not-allowed" } : null },
|
|
1033
|
+
disabled: locked,
|
|
1034
|
+
title: locked ? t("removalNeedsLive") : void 0,
|
|
1035
|
+
onClick: () => emitSel(/* @__PURE__ */ new Set([...addableIds, ...rows.filter((r) => r.status === "listed").map((r) => r.id)])),
|
|
1036
|
+
children: t("alignAction")
|
|
1037
|
+
}
|
|
1038
|
+
)
|
|
958
1039
|
] }),
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
"\uFF08",
|
|
963
|
-
(diff.removed ?? []).length,
|
|
964
|
-
"\uFF09"
|
|
965
|
-
] }),
|
|
966
|
-
list(diff.removed ?? [], styles.removed, (x) => `${x.id} \u2014 ${t(x.reason === "unresolvable" ? "removedUnresolvable" : "removedAccount")}`),
|
|
967
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.modalText, children: [
|
|
968
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: t("keptModels") }),
|
|
969
|
-
"\uFF08",
|
|
970
|
-
(diff.kept ?? []).length,
|
|
971
|
-
"\uFF09"
|
|
972
|
-
] }),
|
|
973
|
-
list(diff.kept ?? [], styles.muted),
|
|
974
|
-
(diff.warnings ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
975
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.modalText, children: [
|
|
976
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: t("warnings") }),
|
|
1040
|
+
groupDefs.map(({ key, items, retain }) => items.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: 8 }, children: [
|
|
1041
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: { ...styles.modalText, fontWeight: 600, margin: "6px 0 2px" }, title: retain ? t("retain") : void 0, children: [
|
|
1042
|
+
t(key),
|
|
977
1043
|
"\uFF08",
|
|
978
|
-
|
|
1044
|
+
items.length,
|
|
979
1045
|
"\uFF09"
|
|
980
1046
|
] }),
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1047
|
+
items.map((r) => {
|
|
1048
|
+
const forceKept = r.status === "removal-proposal" && locked;
|
|
1049
|
+
const checked = forceKept || selected.has(r.id);
|
|
1050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center", padding: "2px 0" }, children: [
|
|
1051
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked, disabled: forceKept, onChange: () => toggle(r.id) }),
|
|
1052
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.mono, children: r.id }),
|
|
1053
|
+
r.status === "removal-proposal" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { ...styles.removed, fontSize: 12 }, children: t(r.reason === "unresolvable" ? "removedUnresolvable" : "removedAccount") }),
|
|
1054
|
+
r.customized === true && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { ...styles.muted, fontSize: 12 }, children: t("customizedBadge") })
|
|
1055
|
+
] }, r.id);
|
|
1056
|
+
})
|
|
1057
|
+
] }, key)),
|
|
1058
|
+
(p.overridesMeta?.clearable || p.overridesMeta?.inheritedOnly) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { padding: "4px 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "checkbox", checked: coChecked, disabled: !p.overridesMeta?.clearable, onChange: (e) => toggleClearOverrides(e.target.checked) }),
|
|
1060
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: p.overridesMeta?.clearable ? void 0 : { ...styles.muted, fontSize: 13 }, children: t(p.overridesMeta?.clearable ? "clearOverrides" : "inheritedOverrides") })
|
|
1061
|
+
] }) }),
|
|
995
1062
|
(p.skipped ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { style: styles.modalText, children: [
|
|
996
1063
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", { children: [
|
|
997
1064
|
t("skippedModels"),
|
|
@@ -1005,25 +1072,57 @@ function RefreshModal({ t, flow, onSelect, onConfirm, onCancel, onOverlay }) {
|
|
|
1005
1072
|
s.reason
|
|
1006
1073
|
] }, s.id)) })
|
|
1007
1074
|
] }),
|
|
1008
|
-
p.catalogError && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { style: styles.modalText, children: [
|
|
1075
|
+
((p.diff?.warnings ?? []).length > 0 || p.catalogError) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { style: styles.modalText, children: [
|
|
1009
1076
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: t("techDetails") }),
|
|
1010
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
1077
|
+
(p.diff?.warnings ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { style: styles.diffList, children: (p.diff?.warnings ?? []).map((w, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { style: styles.skipped, children: [
|
|
1078
|
+
w.id,
|
|
1079
|
+
" \u2014 ",
|
|
1080
|
+
w.reason
|
|
1081
|
+
] }, w.id ?? i)) }),
|
|
1082
|
+
p.catalogError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { ...styles.mono, fontSize: 12 }, children: p.catalogError })
|
|
1011
1083
|
] })
|
|
1012
1084
|
] }),
|
|
1013
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1085
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { padding: "8px 20px 16px" }, children: [
|
|
1086
|
+
(removedCount > 0 || coChecked || emptyTarget) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: 4 }, children: [
|
|
1087
|
+
removedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.risk, children: [
|
|
1088
|
+
"\u26A0 ",
|
|
1089
|
+
t("removalRisk").replace("{count}", String(removedCount))
|
|
1090
|
+
] }),
|
|
1091
|
+
coChecked && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.risk, children: [
|
|
1092
|
+
"\u26A0 ",
|
|
1093
|
+
t("clearOverrides")
|
|
1094
|
+
] }),
|
|
1095
|
+
emptyTarget && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.risk, children: [
|
|
1096
|
+
"\u26A0 ",
|
|
1097
|
+
t("clearRisk")
|
|
1098
|
+
] })
|
|
1099
|
+
] }),
|
|
1100
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { ...styles.modalText, margin: 0 }, children: total === 0 && removedCount === 0 && (p.catalogNewEntries ?? 0) === 0 ? t("noChanges") : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1101
|
+
t("summaryLine").replace("{total}", String(total)).replace("{kept}", String(keptCount)).replace("{added}", String(addedCount)).replace("{removed}", String(removedCount)),
|
|
1102
|
+
(p.catalogNewEntries ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1103
|
+
" \xB7 ",
|
|
1104
|
+
t("catalogNotice").replace("{count}", String(p.catalogNewEntries))
|
|
1105
|
+
] })
|
|
1106
|
+
] }) }),
|
|
1107
|
+
removedCount > 0 && applyBlocked && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
1108
|
+
"\u26A0 ",
|
|
1109
|
+
t("removalNeedsLive")
|
|
1110
|
+
] }),
|
|
1111
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.modalActions, children: [
|
|
1112
|
+
p.catalogSource === "local" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: { ...styles.button, ...styles.secondary, marginRight: "auto" }, onClick: onOverlay, children: t("overlayBtn") }),
|
|
1113
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { ref: cancelRef, type: "button", style: { ...styles.button, ...styles.secondary }, onClick: onCancel, children: t("cancel") }),
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1115
|
+
"button",
|
|
1116
|
+
{
|
|
1117
|
+
type: "button",
|
|
1118
|
+
style: { ...styles.button, ...styles.primary, ...applyBlocked ? { opacity: 0.5, cursor: "not-allowed" } : null },
|
|
1119
|
+
disabled: applyBlocked,
|
|
1120
|
+
onClick: confirmClick,
|
|
1121
|
+
children: t("applyChanges")
|
|
1122
|
+
}
|
|
1123
|
+
)
|
|
1124
|
+
] })
|
|
1125
|
+
] })
|
|
1027
1126
|
] }) });
|
|
1028
1127
|
}
|
|
1029
1128
|
function RetireDialog({ t, onConfirm, onCancel }) {
|
|
@@ -1090,9 +1189,6 @@ function CopilotSection({ t = (key) => DICTS.en[key] ?? key }) {
|
|
|
1090
1189
|
setCopyFail(false);
|
|
1091
1190
|
void authFlowRef.current?.start();
|
|
1092
1191
|
};
|
|
1093
|
-
const withdraw = () => {
|
|
1094
|
-
void authFlowRef.current?.cancel();
|
|
1095
|
-
};
|
|
1096
1192
|
const checkStatus = () => {
|
|
1097
1193
|
void authFlowRef.current?.refresh();
|
|
1098
1194
|
};
|
|
@@ -1143,15 +1239,13 @@ function CopilotSection({ t = (key) => DICTS.en[key] ?? key }) {
|
|
|
1143
1239
|
] }),
|
|
1144
1240
|
codeNotice.url && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { style: styles.link, href: codeNotice.url, target: "_blank", rel: "noreferrer", children: codeNotice.url }),
|
|
1145
1241
|
copyFail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.error, children: t("copyFailed") })
|
|
1146
|
-
] })
|
|
1147
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: { ...styles.button, ...styles.secondary }, onClick: withdraw, children: t("withdrawAuth") }) })
|
|
1242
|
+
] })
|
|
1148
1243
|
] }),
|
|
1149
1244
|
phase === "risk" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.card, children: [
|
|
1150
1245
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
1151
1246
|
"\u26A0 ",
|
|
1152
1247
|
t("authUnsafe")
|
|
1153
1248
|
] }),
|
|
1154
|
-
auth.riskKind === "withdrawal-pending-unverified" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.modalText, children: auth.withdrawalDelivery === "invoked" ? t("withdrawal") : t("withdrawalUnavailable") }),
|
|
1155
1249
|
auth.riskKind === "timed-out-unverified" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.modalText, children: t("attemptTimeout") }),
|
|
1156
1250
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: { ...styles.button, ...styles.secondary }, onClick: checkStatus, children: t("retryNow") }) })
|
|
1157
1251
|
] }),
|
|
@@ -1159,7 +1253,16 @@ function CopilotSection({ t = (key) => DICTS.en[key] ?? key }) {
|
|
|
1159
1253
|
"\u26A0 ",
|
|
1160
1254
|
t("unavailable")
|
|
1161
1255
|
] }),
|
|
1162
|
-
phase === "failed" && attempt?.error &&
|
|
1256
|
+
phase === "failed" && attempt?.error && (() => {
|
|
1257
|
+
const m = /^fetch failed \(([A-Za-z0-9_]+)\)$/.exec(attempt.error);
|
|
1258
|
+
if (!m) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.error, children: attempt.error });
|
|
1259
|
+
const code = m[1];
|
|
1260
|
+
const human = code === "ENOTFOUND" ? t("netDns") : code.startsWith("CERT") || code.includes("SIGNATURE") ? t("netCert") : t("netConnect");
|
|
1261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1262
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: styles.error, children: human }),
|
|
1263
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: { ...styles.modalText, opacity: 0.6 }, children: attempt.error })
|
|
1264
|
+
] });
|
|
1265
|
+
})(),
|
|
1163
1266
|
phase === "failed" && !attempt?.error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1164
1267
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.banner, children: [
|
|
1165
1268
|
"\u26A0 ",
|
|
@@ -1187,28 +1290,16 @@ function CopilotSection({ t = (key) => DICTS.en[key] ?? key }) {
|
|
|
1187
1290
|
}
|
|
1188
1291
|
);
|
|
1189
1292
|
})(),
|
|
1190
|
-
["previewing", "applying", "checking", "retiring"].includes(flow.name) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: { ...styles.button, ...styles.primary, opacity: 0.5 }, disabled: true, children: flow.name === "applying" ? t("applying") : t("refreshing") }) : /* @__PURE__ */ (0, import_jsx_runtime.
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
),
|
|
1201
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1202
|
-
"button",
|
|
1203
|
-
{
|
|
1204
|
-
type: "button",
|
|
1205
|
-
style: { ...styles.button, ...styles.primary, ...refreshBlocked(flow.flags) ? { opacity: 0.5, cursor: "not-allowed" } : null },
|
|
1206
|
-
disabled: refreshBlocked(flow.flags),
|
|
1207
|
-
onClick: () => drive({ type: "start", operation: "rebuild" }),
|
|
1208
|
-
children: t("rebuild")
|
|
1209
|
-
}
|
|
1210
|
-
)
|
|
1211
|
-
] })
|
|
1293
|
+
["previewing", "applying", "checking", "retiring"].includes(flow.name) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: { ...styles.button, ...styles.primary, opacity: 0.5 }, disabled: true, children: flow.name === "applying" ? t("applying") : t("refreshing") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1294
|
+
"button",
|
|
1295
|
+
{
|
|
1296
|
+
type: "button",
|
|
1297
|
+
style: { ...styles.button, ...styles.primary, ...refreshBlocked(flow.flags) ? { opacity: 0.5, cursor: "not-allowed" } : null },
|
|
1298
|
+
disabled: refreshBlocked(flow.flags),
|
|
1299
|
+
onClick: () => drive({ type: "start", operation: "manage" }),
|
|
1300
|
+
children: t("manageModels")
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1212
1303
|
] }),
|
|
1213
1304
|
auth.logoutError && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { style: styles.error, children: [
|
|
1214
1305
|
"\u26A0 ",
|
|
@@ -1268,7 +1359,7 @@ function CopilotSection({ t = (key) => DICTS.en[key] ?? key }) {
|
|
|
1268
1359
|
{
|
|
1269
1360
|
t,
|
|
1270
1361
|
flow,
|
|
1271
|
-
onSelect: (selectedIds) => drive({ type: "select", selectedIds }),
|
|
1362
|
+
onSelect: ({ selectedIds, clearOverrides, confirmEmpty }) => drive({ type: "select", selectedIds, clearOverrides, confirmEmpty }),
|
|
1272
1363
|
onConfirm: (opts) => drive({ type: "confirm", ...opts }),
|
|
1273
1364
|
onCancel: () => drive({ type: "cancel" }),
|
|
1274
1365
|
onOverlay: () => drive({ type: "start", catalogSource: "overlay" })
|