dsh-crate-web 0.1.1 → 0.1.2-preview.2
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 +11 -290
- package/README.zh-CN.md +2 -303
- package/THIRD-PARTY-LICENSE.txt +21 -0
- package/cordis.patch.yml +1 -6
- package/core/dsh_pack/_version.py +1 -0
- package/core/dsh_pack/bundle.py +74 -0
- package/core/dsh_pack/cli.py +81 -18
- package/core/dsh_pack/desktop_verify.py +304 -0
- package/core/dsh_pack/diagnostics.py +1170 -0
- package/core/dsh_pack/errors.py +16 -1
- package/core/dsh_pack/export.py +86 -103
- package/core/dsh_pack/export_plan.py +96 -0
- package/core/dsh_pack/identity.py +25 -0
- package/core/dsh_pack/importer.py +468 -217
- package/core/dsh_pack/network.py +5 -4
- package/core/dsh_pack/pack.py +14 -2
- package/core/dsh_pack/portability.py +392 -0
- package/core/dsh_pack/preflight.py +63 -16
- package/core/dsh_pack/troubleshooting.py +94 -0
- package/core/dsh_pack/user_cli.py +16 -0
- package/core/dsh_pack/validation.py +64 -4
- package/core/dsh_pack/verify.py +343 -194
- package/core/dsh_pack/windows_verify.py +177 -0
- package/desktop-patch-helper.mjs +140 -0
- package/lib/client.js +292 -102
- package/lib/index.d.ts +7 -1
- package/lib/index.js +1121 -229
- package/package.json +14 -7
- package/skills/dsh-crate-troubleshooting/SKILL.md +172 -0
- package/skills/dsh-crate-troubleshooting/compatibility.json +11 -0
- package/skills/dsh-crate-troubleshooting/reference/diagnostics.generated.md +96 -0
- package/skills/dsh-crate-troubleshooting/reference/repair-boundaries.md +60 -0
- package/skills/dsh-crate-troubleshooting/reference/stages.generated.md +22 -0
- package/verify-desktop.mjs +314 -0
package/lib/client.js
CHANGED
|
@@ -43,17 +43,14 @@ window.__ModuleLoader__.load({
|
|
|
43
43
|
groupToggle: "dsh-crate-group-toggle",
|
|
44
44
|
groupBody: "dsh-crate-group-body",
|
|
45
45
|
badge: "dsh-crate-badge",
|
|
46
|
-
conflict: "dsh-crate-conflict"
|
|
47
|
-
toneOk: "dsh-crate-tone-ok",
|
|
48
|
-
toneBad: "dsh-crate-tone-bad",
|
|
49
|
-
toneNeutral: "dsh-crate-tone-neutral"
|
|
46
|
+
conflict: "dsh-crate-conflict"
|
|
50
47
|
};
|
|
51
48
|
const STYLE = `
|
|
52
49
|
.dsh-crate-section{display:flex;flex-direction:column;gap:12px;max-width:760px;color:var(--dsw-alias-label-primary)}
|
|
53
50
|
.dsh-crate-heading{margin:0;font-size:18px;font-weight:600}.dsh-crate-intro,.dsh-crate-muted{margin:0;font-size:13px;color:var(--dsw-alias-label-tertiary)}
|
|
54
51
|
.dsh-crate-tabs{display:flex;gap:20px;border-bottom:1px solid var(--dsw-alias-border-l2);overflow:auto}.dsh-crate-tab{border:0;padding:7px 1px 9px;background:transparent;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;white-space:nowrap}
|
|
55
52
|
.dsh-crate-tab[data-active=true]{color:var(--dsw-alias-label-primary);border-bottom:2px solid var(--dsw-alias-label-primary)}.dsh-crate-form{display:flex;flex-direction:column;gap:10px}
|
|
56
|
-
.dsh-crate-label{display:flex;flex-direction:column;gap:5px;font-size:13px}.dsh-crate-select,.dsh-crate-file{max-width:100%;padding:7px 8px;border:1px solid var(--dsw-alias-border-l2,#3a3a40);border-radius:6px;background-color:var(--dsw-alias-
|
|
53
|
+
.dsh-crate-label{display:flex;flex-direction:column;gap:5px;font-size:13px}.dsh-crate-select,.dsh-crate-file{max-width:100%;min-width:0;padding:7px 8px;border:1px solid var(--dsw-alias-border-l2,#3a3a40);border-radius:6px;background-color:var(--dsw-alias-bg-layer-1,Canvas);color:var(--dsw-alias-label-primary,CanvasText);color-scheme:inherit}.dsh-crate-select option{background-color:var(--dsw-alias-bg-layer-1,Canvas);color:var(--dsw-alias-label-primary,CanvasText)}.dsh-crate-inventory-item{overflow-wrap:anywhere}.dsh-crate-inventory-item>span{min-width:0}
|
|
57
54
|
.dsh-crate-plugin{display:grid;grid-template-columns:minmax(0,1fr) 150px;gap:8px;align-items:center}.dsh-crate-button{align-self:flex-start;border:0;border-radius:6px;padding:8px 13px;background:var(--dsw-alias-state-business-primary);color:white;cursor:pointer}.dsh-crate-button:disabled{cursor:default;opacity:.5}
|
|
58
55
|
.dsh-crate-report,.dsh-crate-preview,.dsh-crate-diagnostic{display:flex;flex-direction:column;gap:8px;padding:10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;overflow-wrap:anywhere;font-size:12px}.dsh-crate-finding,.dsh-crate-step{padding:7px;border-radius:5px;background:var(--dsw-alias-fill-tertiary)}
|
|
59
56
|
.dsh-crate-preview-row{display:grid;grid-template-columns:170px minmax(0,1fr);gap:8px}.dsh-crate-preview-row pre{margin:0;white-space:pre-wrap}.dsh-crate-diagnostic-grid{display:grid;grid-template-columns:150px minmax(0,1fr);gap:6px}.dsh-crate-diagnostic-grid dt{font-weight:600}.dsh-crate-diagnostic-grid dd{margin:0;white-space:pre-wrap}.dsh-crate-step{display:flex;gap:8px;align-items:flex-start}.dsh-crate-step-status{min-width:80px;font-weight:600}
|
|
@@ -63,36 +60,24 @@ window.__ModuleLoader__.load({
|
|
|
63
60
|
.dsh-crate-group{display:flex;flex-direction:column;gap:6px}.dsh-crate-group-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 0}.dsh-crate-group-toggle{border:0;background:transparent;color:var(--dsw-alias-state-business-primary,#4f8cff);font:inherit;font-size:12px;cursor:pointer;padding:2px 4px}.dsh-crate-group-body{display:flex;flex-direction:column;gap:6px}
|
|
64
61
|
.dsh-crate-badge{margin-left:6px;padding:1px 5px;border-radius:4px;background:var(--dsw-alias-fill-tertiary);color:var(--dsw-alias-label-tertiary);font-size:11px;border:1px solid var(--dsw-alias-border-l2)}.dsh-crate-conflict{color:var(--dsw-alias-label-negative)}
|
|
65
62
|
.dsh-crate-modal-backdrop{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px;background:rgba(0,0,0,.58)}.dsh-crate-modal{display:flex;flex-direction:column;gap:12px;width:min(420px,calc(100vw - 48px));padding:18px;border:1px solid var(--dsw-alias-border-l2,#3a3a40);border-radius:10px;background:var(--dsw-alias-fill-primary,#1d1d20);color:var(--dsw-alias-label-primary,#f9fafb);box-shadow:0 18px 50px rgba(0,0,0,.45)}.dsh-crate-modal h3{margin:0;font-size:16px}.dsh-crate-modal p{margin:0;font-size:13px;color:var(--dsw-alias-label-tertiary,#b6b6bd)}.dsh-crate-modal-actions{display:flex;justify-content:flex-end;gap:8px}.dsh-crate-modal-actions button:last-child{background:var(--dsw-alias-state-business-primary,#4b7bec);color:#fff}
|
|
66
|
-
|
|
63
|
+
@media(max-width:600px){
|
|
64
|
+
[data-dsh-module=settings]:has(.dsh-crate-section){flex-direction:column;width:calc(100vw - 24px);max-width:calc(100vw - 24px)}
|
|
65
|
+
[data-dsh-module=settings]:has(.dsh-crate-section)>nav{width:100%;gap:8px;padding:12px 12px 0}
|
|
66
|
+
[data-dsh-module=settings]:has(.dsh-crate-section)>nav>div:last-child{flex-direction:row;overflow-x:auto}
|
|
67
|
+
[data-dsh-module=settings]:has(.dsh-crate-section)>nav button{flex-shrink:0}
|
|
68
|
+
[data-dsh-module=settings]:has(.dsh-crate-section)>div{min-height:0}
|
|
69
|
+
[data-dsh-module=settings]:has(.dsh-crate-section)>div>div:last-child{padding:0 12px 12px}
|
|
70
|
+
.dsh-crate-section{min-width:0;max-width:100%}
|
|
71
|
+
.dsh-crate-inventory-item{flex-wrap:wrap;justify-content:flex-start}
|
|
72
|
+
.dsh-crate-inventory-item>span:first-of-type{flex:1 1 100%}
|
|
73
|
+
.dsh-crate-preview-row,.dsh-crate-diagnostic-grid{grid-template-columns:minmax(0,1fr)}
|
|
74
|
+
.dsh-crate-section pre{max-width:100%;overflow:auto;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
75
|
+
}
|
|
76
|
+
|
|
67
77
|
`;
|
|
68
78
|
function isObject(value) {
|
|
69
79
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
70
80
|
}
|
|
71
|
-
function formatTime(value) {
|
|
72
|
-
if (typeof value !== "string" || !value) return "";
|
|
73
|
-
const date = new Date(value);
|
|
74
|
-
return Number.isNaN(date.getTime()) ? value : date.toLocaleString();
|
|
75
|
-
}
|
|
76
|
-
function toneOf(status) {
|
|
77
|
-
const text = String(status ?? "").toUpperCase();
|
|
78
|
-
if (text.includes("FAIL") || text.includes("ERROR") || text === "BLOCKER" || text === "UNKNOWN") return css.toneBad;
|
|
79
|
-
if (text.includes("PASS") || text === "READY" || text === "PREPARED" || text === "OK") return css.toneOk;
|
|
80
|
-
return css.toneNeutral;
|
|
81
|
-
}
|
|
82
|
-
const FIELD_LABELS = {
|
|
83
|
-
code: "diagCode",
|
|
84
|
-
stage: "diagStage",
|
|
85
|
-
item: "diagItem",
|
|
86
|
-
expected: "diagExpected",
|
|
87
|
-
observed: "diagObserved",
|
|
88
|
-
evidence: "diagEvidence",
|
|
89
|
-
impact: "diagImpact",
|
|
90
|
-
originalProfileStatus: "diagOriginalProfile",
|
|
91
|
-
failedProfileStatus: "diagFailedProfile",
|
|
92
|
-
temporaryProfileStatus: "diagTemporaryProfile",
|
|
93
|
-
canContinue: "diagCanContinue",
|
|
94
|
-
suggestedNextStep: "diagSuggestedNext"
|
|
95
|
-
};
|
|
96
81
|
function resultOf(value) {
|
|
97
82
|
return isObject(value.result) ? value.result : value;
|
|
98
83
|
}
|
|
@@ -113,7 +98,9 @@ window.__ModuleLoader__.load({
|
|
|
113
98
|
}
|
|
114
99
|
function pluginLabel(plugin) {
|
|
115
100
|
const resolved = isObject(plugin.resolved) ? plugin.resolved : {};
|
|
116
|
-
|
|
101
|
+
const runtime = isObject(plugin.runtime) ? plugin.runtime : {};
|
|
102
|
+
const version = typeof resolved.version === "string" && resolved.version !== "unknown" ? resolved.version : runtime.version;
|
|
103
|
+
return `${String(plugin.name ?? "unknown")}@${String(version ?? "unknown")}`;
|
|
117
104
|
}
|
|
118
105
|
function upsertProfileRow(list, row) {
|
|
119
106
|
const name = typeof row.name === "string" ? row.name : "";
|
|
@@ -250,7 +237,7 @@ window.__ModuleLoader__.load({
|
|
|
250
237
|
"temporaryProfileStatus",
|
|
251
238
|
"canContinue",
|
|
252
239
|
"suggestedNextStep"
|
|
253
|
-
].filter((field) => diagnostic[field] !== void 0).map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children:
|
|
240
|
+
].filter((field) => diagnostic[field] !== void 0).map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: field }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: display(diagnostic[field]) })] }, field))
|
|
254
241
|
}),
|
|
255
242
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
256
243
|
className: css.button,
|
|
@@ -276,10 +263,7 @@ window.__ModuleLoader__.load({
|
|
|
276
263
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
|
|
277
264
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("coreStatus") }),
|
|
278
265
|
" · ",
|
|
279
|
-
|
|
280
|
-
className: toneOf(result.status),
|
|
281
|
-
children: String(result.status ?? "UNKNOWN")
|
|
282
|
-
})
|
|
266
|
+
String(result.status ?? "UNKNOWN")
|
|
283
267
|
] }),
|
|
284
268
|
findings.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("findings") }), findings.map((finding, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
285
269
|
className: css.finding,
|
|
@@ -301,12 +285,14 @@ window.__ModuleLoader__.load({
|
|
|
301
285
|
}
|
|
302
286
|
function ImportPreview({ value, t, targetProfile, overwrite }) {
|
|
303
287
|
const result = resultOf(value);
|
|
288
|
+
if (typeof result.canContinue !== "boolean") return null;
|
|
304
289
|
const pack = isObject(result.pack) ? result.pack : {};
|
|
305
290
|
const profile = isObject(pack.profile) ? pack.profile : {};
|
|
306
291
|
const requiredPlugins = objects(result.requiredPlugins);
|
|
307
292
|
const optionalPlugins = objects(result.optionalPlugins);
|
|
308
293
|
const warningCount = typeof result.warningCount === "number" ? result.warningCount : 0;
|
|
309
294
|
const environment = isObject(result.environment) ? result.environment : {};
|
|
295
|
+
const secrets = isObject(result.secrets) ? result.secrets : {};
|
|
310
296
|
const target = targetProfile?.trim() || String(result.targetProfile ?? profile.name ?? "UNKNOWN");
|
|
311
297
|
const safety = overwrite ? t("overwritePreview") : t("willNotOverwrite");
|
|
312
298
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -338,6 +324,16 @@ window.__ModuleLoader__.load({
|
|
|
338
324
|
"data-field": "environment",
|
|
339
325
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("environment") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: display(environment) })]
|
|
340
326
|
}),
|
|
327
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
328
|
+
className: css.previewRow,
|
|
329
|
+
"data-field": "requiredSecrets",
|
|
330
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("requiredSecrets") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: Array.isArray(secrets.required) ? secrets.required.join(", ") || t("none") : t("none") })]
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
333
|
+
className: css.previewRow,
|
|
334
|
+
"data-field": "missingSecrets",
|
|
335
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("missingSecrets") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: Array.isArray(secrets.missing) ? secrets.missing.join(", ") || t("none") : t("none") })]
|
|
336
|
+
}),
|
|
341
337
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
342
338
|
className: css.previewRow,
|
|
343
339
|
"data-field": "coreDecision",
|
|
@@ -404,14 +400,10 @@ window.__ModuleLoader__.load({
|
|
|
404
400
|
" · ",
|
|
405
401
|
String(result.status ?? "UNKNOWN")
|
|
406
402
|
] }),
|
|
407
|
-
String(result.status ?? "") === "UNTESTED" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
408
|
-
className: css.muted,
|
|
409
|
-
children: t("verifyUntestedNote")
|
|
410
|
-
}) : null,
|
|
411
403
|
steps.map((step, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
412
404
|
className: css.step,
|
|
413
405
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
414
|
-
className:
|
|
406
|
+
className: css.stepStatus,
|
|
415
407
|
children: String(step.status ?? "UNKNOWN")
|
|
416
408
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
417
409
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: String(step.name ?? "unknown") }),
|
|
@@ -434,6 +426,14 @@ window.__ModuleLoader__.load({
|
|
|
434
426
|
const [profiles, setProfiles] = (0, react.useState)([]);
|
|
435
427
|
const [profile, setProfile] = (0, react.useState)("");
|
|
436
428
|
const [modes, setModes] = (0, react.useState)({});
|
|
429
|
+
const [preset, setPreset] = (0, react.useState)("custom");
|
|
430
|
+
const [secretNames, setSecretNames] = (0, react.useState)("");
|
|
431
|
+
const [dataSelection, setDataSelection] = (0, react.useState)([]);
|
|
432
|
+
const [dataOwners, setDataOwners] = (0, react.useState)({});
|
|
433
|
+
const [dataKinds, setDataKinds] = (0, react.useState)({});
|
|
434
|
+
const [exportPlan, setExportPlan] = (0, react.useState)();
|
|
435
|
+
const [reviewedSelection, setReviewedSelection] = (0, react.useState)("");
|
|
436
|
+
const [downloadSelection, setDownloadSelection] = (0, react.useState)("");
|
|
437
437
|
const [file, setFile] = (0, react.useState)();
|
|
438
438
|
const [report, setReport] = (0, react.useState)();
|
|
439
439
|
const [history, setHistory] = (0, react.useState)([]);
|
|
@@ -467,6 +467,41 @@ window.__ModuleLoader__.load({
|
|
|
467
467
|
const exportBundles = installedBundles.filter((bundle) => bundle.active === true);
|
|
468
468
|
const conflictBundles = installedBundles.filter((bundle) => bundle.conflict === true);
|
|
469
469
|
const exportNames = exportBundles.map((bundle) => String(bundle.name ?? "")).filter(Boolean);
|
|
470
|
+
const requiredSecrets = [...new Set(secretNames.split(/[\s,]+/).filter(Boolean))];
|
|
471
|
+
const invalidSecretNames = requiredSecrets.some((name) => !/^[A-Za-z_][A-Za-z0-9_]*$/.test(name));
|
|
472
|
+
const exportBody = {
|
|
473
|
+
profileName: profile,
|
|
474
|
+
includeInstalledBundles: true,
|
|
475
|
+
preset,
|
|
476
|
+
dataSelection,
|
|
477
|
+
requiredSecrets,
|
|
478
|
+
embed: exportNames.filter((name) => (modes[name] ?? "embedded") === "embedded"),
|
|
479
|
+
referenceOnly: exportNames.filter((name) => (modes[name] ?? "embedded") === "reference-only")
|
|
480
|
+
};
|
|
481
|
+
const exportSignature = JSON.stringify(exportBody);
|
|
482
|
+
const previewExport = async () => {
|
|
483
|
+
setBusy(true);
|
|
484
|
+
setError("");
|
|
485
|
+
try {
|
|
486
|
+
const value = await request("export-plan", exportBody);
|
|
487
|
+
if (value.status === "failed") throw new Error(failMessage(value) || t("error"));
|
|
488
|
+
setExportPlan(resultOf(value));
|
|
489
|
+
setReviewedSelection(exportSignature);
|
|
490
|
+
} catch (caught) {
|
|
491
|
+
setError(caught instanceof Error ? caught.message : String(caught));
|
|
492
|
+
setReviewedSelection("");
|
|
493
|
+
} finally {
|
|
494
|
+
setBusy(false);
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
(0, react.useEffect)(() => {
|
|
498
|
+
setDataSelection([]);
|
|
499
|
+
setDataOwners({});
|
|
500
|
+
setDataKinds({});
|
|
501
|
+
setSecretNames("");
|
|
502
|
+
setExportPlan(void 0);
|
|
503
|
+
setReviewedSelection("");
|
|
504
|
+
}, [profile]);
|
|
470
505
|
const canImport = isObject(report?.result) && report.result.canContinue === true;
|
|
471
506
|
const currentRuntimeProfile = typeof runtime?.currentProfile === "string" ? runtime.currentProfile : "";
|
|
472
507
|
const loadProfiles = async () => {
|
|
@@ -524,19 +559,18 @@ window.__ModuleLoader__.load({
|
|
|
524
559
|
const run = async (action, body) => {
|
|
525
560
|
setBusy(true);
|
|
526
561
|
setError("");
|
|
562
|
+
if (action === "export") setDownloadSelection("");
|
|
527
563
|
try {
|
|
528
564
|
const value = await request(action, body);
|
|
529
565
|
setReport(value);
|
|
530
566
|
const result = resultOf(value);
|
|
531
567
|
const profileLabel = String(body.profileName ?? "");
|
|
532
568
|
if (value.status === "failed" || result.status === "failed" || result.status === "FAIL") showToast(`${t("error")}: ${failMessage(value) || t("error")}`);
|
|
533
|
-
else if (action === "export" && typeof value.downloadName === "string")
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
else showToast(`${t("verifyFinished")} ${profileLabel} · ${String(result.status ?? "")}`.trim());
|
|
539
|
-
}
|
|
569
|
+
else if (action === "export" && typeof value.downloadName === "string") {
|
|
570
|
+
setDownloadSelection(JSON.stringify(body));
|
|
571
|
+
showToast(`${t("exportSuccess")} ${profileLabel}`.trim());
|
|
572
|
+
} else if (action === "inspect") showToast(t("inspectSuccess"));
|
|
573
|
+
else if (action === "verify" && value.success !== true) showToast(`${t("verifyFinished")} ${profileLabel} · ${String(result.status ?? "")}`.trim());
|
|
540
574
|
} catch (caught) {
|
|
541
575
|
const message = caught instanceof Error ? caught.message : String(caught);
|
|
542
576
|
setError(message);
|
|
@@ -695,8 +729,7 @@ window.__ModuleLoader__.load({
|
|
|
695
729
|
return;
|
|
696
730
|
}
|
|
697
731
|
if (!window.confirm(`${t("overwriteWarning")}\n\n${target}`)) {
|
|
698
|
-
|
|
699
|
-
setError("");
|
|
732
|
+
setError(t("overwriteCanceled"));
|
|
700
733
|
return;
|
|
701
734
|
}
|
|
702
735
|
setBusy(true);
|
|
@@ -840,10 +873,14 @@ window.__ModuleLoader__.load({
|
|
|
840
873
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
841
874
|
className: css.button,
|
|
842
875
|
type: "button",
|
|
843
|
-
disabled: busy || !switchTarget,
|
|
876
|
+
disabled: busy || !switchTarget || runtime?.restartConfigured !== true,
|
|
844
877
|
onClick: () => void switchSelectedProfile(),
|
|
845
878
|
children: busy ? t("switchPending") : t("switchProfile")
|
|
846
879
|
}),
|
|
880
|
+
runtime?.restartConfigured === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
881
|
+
className: css.muted,
|
|
882
|
+
children: t("switchUnavailable")
|
|
883
|
+
}) : null,
|
|
847
884
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
848
885
|
className: css.label,
|
|
849
886
|
children: [t("deleteProfile"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
@@ -1006,10 +1043,13 @@ window.__ModuleLoader__.load({
|
|
|
1006
1043
|
className: css.select,
|
|
1007
1044
|
disabled: conflict,
|
|
1008
1045
|
value: modes[name] ?? "embedded",
|
|
1009
|
-
onChange: (event) =>
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1046
|
+
onChange: (event) => {
|
|
1047
|
+
setPreset("custom");
|
|
1048
|
+
setModes((current) => ({
|
|
1049
|
+
...current,
|
|
1050
|
+
[name]: event.target.value
|
|
1051
|
+
}));
|
|
1052
|
+
},
|
|
1013
1053
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1014
1054
|
value: "embedded",
|
|
1015
1055
|
children: t("embedded")
|
|
@@ -1047,19 +1087,172 @@ window.__ModuleLoader__.load({
|
|
|
1047
1087
|
})]
|
|
1048
1088
|
}, `conflict-${String(bundle.name)}`))]
|
|
1049
1089
|
}) : null,
|
|
1090
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
|
|
1091
|
+
t("exportPreset"),
|
|
1092
|
+
" ",
|
|
1093
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1094
|
+
className: css.select,
|
|
1095
|
+
value: preset,
|
|
1096
|
+
disabled: busy,
|
|
1097
|
+
onChange: (event) => {
|
|
1098
|
+
const value = event.target.value;
|
|
1099
|
+
setPreset(value);
|
|
1100
|
+
if (value !== "custom") setModes(Object.fromEntries(exportNames.map((name) => [name, value === "freeze" ? "embedded" : "reference-only"])));
|
|
1101
|
+
},
|
|
1102
|
+
children: [
|
|
1103
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1104
|
+
value: "share",
|
|
1105
|
+
children: "Share"
|
|
1106
|
+
}),
|
|
1107
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1108
|
+
value: "freeze",
|
|
1109
|
+
children: "Freeze"
|
|
1110
|
+
}),
|
|
1111
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1112
|
+
value: "custom",
|
|
1113
|
+
children: "Custom"
|
|
1114
|
+
})
|
|
1115
|
+
]
|
|
1116
|
+
})
|
|
1117
|
+
] }),
|
|
1118
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1119
|
+
className: css.label,
|
|
1120
|
+
children: [t("requiredSecrets"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1121
|
+
className: css.file,
|
|
1122
|
+
value: secretNames,
|
|
1123
|
+
disabled: busy,
|
|
1124
|
+
autoComplete: "off",
|
|
1125
|
+
spellCheck: false,
|
|
1126
|
+
"aria-describedby": "crate-secret-hint",
|
|
1127
|
+
"aria-invalid": invalidSecretNames,
|
|
1128
|
+
onChange: (event) => setSecretNames(event.target.value)
|
|
1129
|
+
})]
|
|
1130
|
+
}),
|
|
1131
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1132
|
+
className: css.muted,
|
|
1133
|
+
id: "crate-secret-hint",
|
|
1134
|
+
children: t("secretNamesHint")
|
|
1135
|
+
}),
|
|
1136
|
+
invalidSecretNames ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1137
|
+
className: css.error,
|
|
1138
|
+
role: "alert",
|
|
1139
|
+
children: t("invalidSecretNames")
|
|
1140
|
+
}) : null,
|
|
1050
1141
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1051
1142
|
className: css.button,
|
|
1052
1143
|
type: "button",
|
|
1053
|
-
disabled: busy || !profile,
|
|
1054
|
-
onClick: () => void
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1144
|
+
disabled: busy || !profile || invalidSecretNames,
|
|
1145
|
+
onClick: () => void previewExport(),
|
|
1146
|
+
children: busy ? t("working") : t("previewExport")
|
|
1147
|
+
}),
|
|
1148
|
+
exportPlan ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1149
|
+
className: css.inventory,
|
|
1150
|
+
"data-field": "exportPreview",
|
|
1151
|
+
children: [
|
|
1152
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("requiredSecrets") }),
|
|
1153
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1154
|
+
"data-field": "reviewedSecrets",
|
|
1155
|
+
children: Array.isArray(exportPlan.requiredSecrets) ? exportPlan.requiredSecrets.join(", ") || t("none") : t("none")
|
|
1156
|
+
}),
|
|
1157
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("portableData") }),
|
|
1158
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("privacyReview") }),
|
|
1159
|
+
objects(exportPlan.dataInventory).map((item, index) => {
|
|
1160
|
+
const path = typeof item.path === "string" ? item.path : "";
|
|
1161
|
+
const conversation = item.kind === "conversation";
|
|
1162
|
+
const chosen = dataSelection.some((row) => row.path === path);
|
|
1163
|
+
const owner = conversation ? "@deepseek-ai/dsh-session-persistence-jsonl" : dataOwners[path] || "";
|
|
1164
|
+
const selectable = item.selectable === true || item.classification === "portable";
|
|
1165
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1166
|
+
className: css.inventoryItem,
|
|
1167
|
+
children: [
|
|
1168
|
+
selectable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1169
|
+
type: "checkbox",
|
|
1170
|
+
"aria-label": path,
|
|
1171
|
+
disabled: busy || !owner,
|
|
1172
|
+
checked: chosen,
|
|
1173
|
+
onChange: (event) => {
|
|
1174
|
+
setDataSelection((current) => event.target.checked ? [...current.filter((row) => row.path !== path), {
|
|
1175
|
+
path,
|
|
1176
|
+
owner,
|
|
1177
|
+
kind: conversation ? "conversation" : dataKinds[path] || "plugin-data"
|
|
1178
|
+
}] : current.filter((row) => row.path !== path));
|
|
1179
|
+
}
|
|
1180
|
+
}) : null,
|
|
1181
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
1182
|
+
path || String(item.name ?? ""),
|
|
1183
|
+
" · ",
|
|
1184
|
+
String(item.classification ?? "")
|
|
1185
|
+
] }),
|
|
1186
|
+
selectable && !conversation ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1187
|
+
className: css.select,
|
|
1188
|
+
"aria-label": path + " " + t("dataOwner"),
|
|
1189
|
+
disabled: busy || chosen,
|
|
1190
|
+
value: owner,
|
|
1191
|
+
onChange: (event) => setDataOwners((current) => ({
|
|
1192
|
+
...current,
|
|
1193
|
+
[path]: event.target.value
|
|
1194
|
+
})),
|
|
1195
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1196
|
+
value: "",
|
|
1197
|
+
children: t("chooseOwner")
|
|
1198
|
+
}), objects(exportPlan.plugins).map((plugin) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1199
|
+
value: String(plugin.name),
|
|
1200
|
+
children: String(plugin.name)
|
|
1201
|
+
}, String(plugin.name)))]
|
|
1202
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1203
|
+
className: css.select,
|
|
1204
|
+
"aria-label": path + " " + t("dataKind"),
|
|
1205
|
+
disabled: busy || chosen,
|
|
1206
|
+
value: dataKinds[path] || "plugin-data",
|
|
1207
|
+
onChange: (event) => setDataKinds((current) => ({
|
|
1208
|
+
...current,
|
|
1209
|
+
[path]: event.target.value
|
|
1210
|
+
})),
|
|
1211
|
+
children: [
|
|
1212
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1213
|
+
value: "plugin-data",
|
|
1214
|
+
children: "Plugin data"
|
|
1215
|
+
}),
|
|
1216
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1217
|
+
value: "plugin-config",
|
|
1218
|
+
children: "Plugin config"
|
|
1219
|
+
}),
|
|
1220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1221
|
+
value: "plugin-workflow",
|
|
1222
|
+
children: "Plugin workflow"
|
|
1223
|
+
})
|
|
1224
|
+
]
|
|
1225
|
+
})] }) : null
|
|
1226
|
+
]
|
|
1227
|
+
}, path || index);
|
|
1228
|
+
}),
|
|
1229
|
+
isObject(exportPlan.completeness) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1230
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("completeness") }),
|
|
1231
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", { children: [
|
|
1232
|
+
t("embedded"),
|
|
1233
|
+
": ",
|
|
1234
|
+
Array.isArray(exportPlan.completeness.embedded) ? exportPlan.completeness.embedded.length : 0,
|
|
1235
|
+
" · ",
|
|
1236
|
+
t("referenceOnly"),
|
|
1237
|
+
": ",
|
|
1238
|
+
Array.isArray(exportPlan.completeness.referenceOnly) ? exportPlan.completeness.referenceOnly.length : 0,
|
|
1239
|
+
" · ",
|
|
1240
|
+
t("offlineRestore"),
|
|
1241
|
+
": ",
|
|
1242
|
+
String(exportPlan.completeness.offlineRestorable ?? "UNPROVEN")
|
|
1243
|
+
] }),
|
|
1244
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("rawJson") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", { children: JSON.stringify(exportPlan.completeness, null, 2) })] })
|
|
1245
|
+
] }) : null
|
|
1246
|
+
]
|
|
1247
|
+
}) : null,
|
|
1248
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1249
|
+
className: css.button,
|
|
1250
|
+
type: "button",
|
|
1251
|
+
disabled: busy || !profile || invalidSecretNames || reviewedSelection !== exportSignature,
|
|
1252
|
+
onClick: () => void run("export", exportBody),
|
|
1060
1253
|
children: busy ? t("exporting") : t("exportButton")
|
|
1061
1254
|
}),
|
|
1062
|
-
isObject(report) && typeof report.downloadName === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1255
|
+
!busy && downloadSelection === exportSignature && isObject(report) && typeof report.downloadName === "string" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
1063
1256
|
href: `/dsh-crate/download?name=${encodeURIComponent(report.downloadName)}`,
|
|
1064
1257
|
children: t("download")
|
|
1065
1258
|
}) : null,
|
|
@@ -1188,15 +1381,12 @@ window.__ModuleLoader__.load({
|
|
|
1188
1381
|
}) : history.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1189
1382
|
className: css.historyItem,
|
|
1190
1383
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
1191
|
-
|
|
1384
|
+
item.time,
|
|
1192
1385
|
" · ",
|
|
1193
1386
|
item.action,
|
|
1194
1387
|
" · ",
|
|
1195
1388
|
item.profile ?? item.pack ?? ""
|
|
1196
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
|
|
1197
|
-
className: toneOf(item.status),
|
|
1198
|
-
children: item.status
|
|
1199
|
-
})]
|
|
1389
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: item.status })]
|
|
1200
1390
|
}, `${item.time}-${index}`))
|
|
1201
1391
|
}) : null,
|
|
1202
1392
|
newProfileDialogOpen ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1241,7 +1431,7 @@ window.__ModuleLoader__.load({
|
|
|
1241
1431
|
className: css.button,
|
|
1242
1432
|
type: "button",
|
|
1243
1433
|
onClick: () => void confirmNewProfileImport(),
|
|
1244
|
-
children: t("
|
|
1434
|
+
children: t("importButton")
|
|
1245
1435
|
})]
|
|
1246
1436
|
})
|
|
1247
1437
|
]
|
|
@@ -1366,8 +1556,7 @@ window.__ModuleLoader__.load({
|
|
|
1366
1556
|
choosePack: "Choose a .dshcrate file",
|
|
1367
1557
|
inspectButton: "Run Preflight",
|
|
1368
1558
|
importButton: "Import Crate",
|
|
1369
|
-
|
|
1370
|
-
confirmImport: "Imports as a new Profile after a Preflight check. Continue?",
|
|
1559
|
+
confirmImport: "Preflight passed. Import as a new Profile?",
|
|
1371
1560
|
working: "Working…",
|
|
1372
1561
|
noReport: "No report yet.",
|
|
1373
1562
|
noHistory: "No DSH Crate operations have been recorded.",
|
|
@@ -1418,6 +1607,11 @@ window.__ModuleLoader__.load({
|
|
|
1418
1607
|
profileNameRequired: "Profile name is required.",
|
|
1419
1608
|
profileNameExists: "That Profile name already exists.",
|
|
1420
1609
|
cancel: "Cancel",
|
|
1610
|
+
switchUnavailable: "This desktop environment cannot switch and restart Profiles here. Start the restored environment in a separate DSH Home.",
|
|
1611
|
+
requiredSecrets: "Required Secret names",
|
|
1612
|
+
missingSecrets: "Missing Secret names",
|
|
1613
|
+
secretNamesHint: "Enter environment variable names only, separated by spaces or commas (for example DEEPSEEK_API_KEY). Never enter values. Blank keeps names recorded by a prior import; no credentials are read automatically.",
|
|
1614
|
+
invalidSecretNames: "Use environment variable names containing letters, digits and underscores, starting with a letter or underscore. Do not enter assignments or Secret values.",
|
|
1421
1615
|
createProfile: "New Profile",
|
|
1422
1616
|
createProfilePlaceholder: "new profile name",
|
|
1423
1617
|
createProfileHint: "A new Profile includes the official DSH bundles and the DSH Crate plugin by default.",
|
|
@@ -1448,26 +1642,22 @@ window.__ModuleLoader__.load({
|
|
|
1448
1642
|
conflictBundles: "Conflicted Bundles (not exported)",
|
|
1449
1643
|
collapse: "Collapse",
|
|
1450
1644
|
expand: "Expand",
|
|
1645
|
+
exportPreset: "Export mode",
|
|
1646
|
+
previewExport: "Review export contents",
|
|
1647
|
+
portableData: "Selected conversations and plugin data",
|
|
1648
|
+
dataOwner: "Plugin owner",
|
|
1649
|
+
chooseOwner: "Choose the owner after checking its storage contract",
|
|
1650
|
+
dataKind: "Data type",
|
|
1651
|
+
privacyReview: "Review selected data before sharing. Recognizable credentials are blocked; private text still needs your review.",
|
|
1652
|
+
completeness: "Freeze completeness",
|
|
1653
|
+
offlineRestore: "Offline-restorable",
|
|
1451
1654
|
exportSuccess: "Crate exported successfully.",
|
|
1452
1655
|
inspectSuccess: "Preflight finished.",
|
|
1453
1656
|
verifySuccess: "Verification passed.",
|
|
1454
1657
|
verifyFailed: "Verification failed.",
|
|
1455
1658
|
verifyFinished: "Verification finished.",
|
|
1456
|
-
verifyUntestedNote: "UNTESTED means composition was checked only; runtime, model, session, and plugin behavior were NOT actually verified.",
|
|
1457
1659
|
importOverwritten: "Profile overwritten.",
|
|
1458
|
-
switchPending: "Switching Profile and waiting for DSH ready…"
|
|
1459
|
-
diagCode: "Code",
|
|
1460
|
-
diagStage: "Stage",
|
|
1461
|
-
diagItem: "Item",
|
|
1462
|
-
diagExpected: "Expected",
|
|
1463
|
-
diagObserved: "Observed",
|
|
1464
|
-
diagEvidence: "Evidence",
|
|
1465
|
-
diagImpact: "Impact",
|
|
1466
|
-
diagOriginalProfile: "Original Profile",
|
|
1467
|
-
diagFailedProfile: "Failed Profile",
|
|
1468
|
-
diagTemporaryProfile: "Temporary Profile",
|
|
1469
|
-
diagCanContinue: "Can continue",
|
|
1470
|
-
diagSuggestedNext: "Suggested next step"
|
|
1660
|
+
switchPending: "Switching Profile and waiting for DSH ready…"
|
|
1471
1661
|
};
|
|
1472
1662
|
const zh = {
|
|
1473
1663
|
nav: "DSH Crate",
|
|
@@ -1487,8 +1677,7 @@ window.__ModuleLoader__.load({
|
|
|
1487
1677
|
choosePack: "选择 .dshcrate 文件",
|
|
1488
1678
|
inspectButton: "运行 Preflight",
|
|
1489
1679
|
importButton: "导入 Crate",
|
|
1490
|
-
|
|
1491
|
-
confirmImport: "将作为新 Profile 导入,导入前会先执行 Preflight 检查。是否继续?",
|
|
1680
|
+
confirmImport: "Preflight 已通过。要作为新 Profile 导入吗?",
|
|
1492
1681
|
working: "处理中…",
|
|
1493
1682
|
noReport: "暂无报告。",
|
|
1494
1683
|
noHistory: "还没有 DSH Crate 操作记录。",
|
|
@@ -1539,6 +1728,11 @@ window.__ModuleLoader__.load({
|
|
|
1539
1728
|
profileNameRequired: "必须填写 Profile 名称。",
|
|
1540
1729
|
profileNameExists: "该 Profile 名称已存在。",
|
|
1541
1730
|
cancel: "取消",
|
|
1731
|
+
switchUnavailable: "当前桌面环境不支持在此切换并重启 Profile。请在独立的 DSH Home 中启动恢复后的环境。",
|
|
1732
|
+
requiredSecrets: "所需 Secret 名称",
|
|
1733
|
+
missingSecrets: "缺失的 Secret 名称",
|
|
1734
|
+
secretNamesHint: "只填写环境变量名称,用空格或逗号分隔,例如 DEEPSEEK_API_KEY。不要填写值。留空时沿用此前导入记录的名称;不会自动读取凭据。",
|
|
1735
|
+
invalidSecretNames: "名称只能包含字母、数字和下划线,并以字母或下划线开头。不要填写赋值表达式或 Secret 值。",
|
|
1542
1736
|
createProfile: "新建 Profile",
|
|
1543
1737
|
createProfilePlaceholder: "新 Profile 名称",
|
|
1544
1738
|
createProfileHint: "新 Profile 默认包含官方插件与本插件(DSH Crate)。",
|
|
@@ -1569,26 +1763,22 @@ window.__ModuleLoader__.load({
|
|
|
1569
1763
|
conflictBundles: "冲突 Bundle(未导出)",
|
|
1570
1764
|
collapse: "折叠",
|
|
1571
1765
|
expand: "展开",
|
|
1766
|
+
exportPreset: "导出模式",
|
|
1767
|
+
previewExport: "预览导出内容",
|
|
1768
|
+
portableData: "选择会话与插件数据",
|
|
1769
|
+
dataOwner: "所属插件",
|
|
1770
|
+
chooseOwner: "确认存储归属后选择插件",
|
|
1771
|
+
dataKind: "数据类型",
|
|
1772
|
+
privacyReview: "分享前请检查所选内容。可识别的凭据会被阻止,私人文本仍需自行检查。",
|
|
1773
|
+
completeness: "Freeze 完整度",
|
|
1774
|
+
offlineRestore: "离线可恢复",
|
|
1572
1775
|
exportSuccess: "Crate 导出成功。",
|
|
1573
1776
|
inspectSuccess: "Preflight 检查完成。",
|
|
1574
1777
|
verifySuccess: "验证通过。",
|
|
1575
1778
|
verifyFailed: "验证未通过。",
|
|
1576
1779
|
verifyFinished: "验证完成。",
|
|
1577
|
-
verifyUntestedNote: "UNTESTED 表示仅验证了组合(composition),运行时、模型、会话、插件业务行为均未实际验证。",
|
|
1578
1780
|
importOverwritten: "Profile 已覆盖。",
|
|
1579
|
-
switchPending: "正在切换 Profile,等待 DSH ready…"
|
|
1580
|
-
diagCode: "诊断代码",
|
|
1581
|
-
diagStage: "失败阶段",
|
|
1582
|
-
diagItem: "对象",
|
|
1583
|
-
diagExpected: "预期",
|
|
1584
|
-
diagObserved: "实际",
|
|
1585
|
-
diagEvidence: "证据",
|
|
1586
|
-
diagImpact: "影响",
|
|
1587
|
-
diagOriginalProfile: "原 Profile 状态",
|
|
1588
|
-
diagFailedProfile: "失败 Profile 状态",
|
|
1589
|
-
diagTemporaryProfile: "临时 Profile 状态",
|
|
1590
|
-
diagCanContinue: "是否可继续",
|
|
1591
|
-
diagSuggestedNext: "建议下一步"
|
|
1781
|
+
switchPending: "正在切换 Profile,等待 DSH ready…"
|
|
1592
1782
|
};
|
|
1593
1783
|
//#endregion
|
|
1594
1784
|
//#region src/client/index.tsx
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
|
|
3
|
+
//#region src/windows-terminal.d.ts
|
|
4
|
+
interface WindowsTerminalConfig {
|
|
5
|
+
windowsTerminalCompatibility?: boolean;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
2
8
|
//#region src/index.d.ts
|
|
3
9
|
/** Minimal structural projection of the Cordis Loader entry tree used by DSH. */
|
|
4
10
|
interface LoaderEntryOptions {
|
|
@@ -25,6 +31,6 @@ declare module '@deepseek-ai/cordis' {
|
|
|
25
31
|
}
|
|
26
32
|
/** Register the host bridge. The Core executable is intentionally external. */
|
|
27
33
|
declare const inject: string[];
|
|
28
|
-
declare function apply(ctx: Context): void;
|
|
34
|
+
declare function apply(ctx: Context, config?: WindowsTerminalConfig): void;
|
|
29
35
|
//#endregion
|
|
30
36
|
export { apply, inject };
|